Haberler:

Foruma Resim Yükleme ve Boyut Sınırlaması ( ! )  https://bit.ly/2GMFb8H

Ana Menü

Timer0 ile süre oluşturmak

Başlatan kostebek, 04 Mart 2008, 22:42:01

kostebek

Merhaba arkadaşlar. Assebly ile çok rahat Pıc programlayabiliyorum artık. :)

Yavaştan C öğrenmeye başladım bende. Biraz önce IDE sini de indirdim. Aslında böyle de gayet hızlı program geliştirilebiliyor.

Şimdi sormak istediğim şu; Derste bir program yazdık. Dalga paketleri yöntemi ile AC kıyıcı yapıyoruz. Programın kodları da aşağıdaki gibi.
Şimdi sormak istediğim buradaki Delay() ile oluşturduğumuz beklemeyi Timer0 ile nasıl oluşturabiliriz.

Yardımlarınız için teşekkürler :)

//////////////////////////////////////////////////////////////////////////////////////
////                  DALGA PAKETLERİ                                               // 
////  Bu devrede T1 ve T2 süreleri potansiyometre ile AN1, AN2 kanallarından        //
///   okunuyor. Triyak sıfır gerilim şalteri gibi ON-OFF kontrol ile çalıştırılıyor //
//////////////////////////////////////////////////////////////////////////////////////

#include <16F877.H>
#device *=16
#DEVICE ADC=10
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)

#include <lcd.c>


#define Triyak       PIN_D0   // Triyak tetiklemek için kullanılıyor.


int16 T1,T2;

void main()
   {

   set_tris_c(0x80);
   set_tris_d(0);

   setup_port_a( ALL_ANALOG );
   setup_adc( ADC_CLOCK_DIV_32 );  //   setup_adc( ADC_CLOCK_INTERNAL );

   lcd_init();

   while(1)
   { 
   
   set_adc_channel(1);
   T1 = read_adc();
     
   set_adc_channel(2);
   T2 = read_adc();

   printf(lcd_putc,"\f T1=%Lu T2=%Lu", T1, T2);
   
  
   output_high(Triyak);
   delay_ms(T1);   //işte bu süreler
   
   output_low(Triyak);
   delay_ms(T2);   //bir de bu süre :)
   }
 



}

remzi

Timer0 ı bekliyceğin süreye göre set etmen gerekiyor.

Mesela şöyle

Bekle=255-t1;

set_timer0(bekle);


Kesme geldiğindede tristörü tetiklersin olur biter...

Eğer 8 bit yetmezse 16 bitlik timer1 i kullanabilirsin.

kostebek

Ama işte bu kesme alt programı felan ne şekjilde işliyor bir türlü anlayamadım.

Şöyle birşey düşündüm de çalışmadı

//////////////////////////////////////////////////////////////////////////////////////
////                  DALGA PAKETLERİ                                               // 
////  Bu devrede T1 ve T2 süreleri potansiyometre ile AN1, AN2 kanallarından        //
///   okunuyor. Triyak sıfır gerilim şalteri gibi ON-OFF kontrol ile çalıştırılıyor //
//////////////////////////////////////////////////////////////////////////////////////

#include <16F877.H>
#device *=16
#DEVICE ADC=10
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)

#include <lcd.c>


#define Triyak       PIN_D0   // Triyak tetiklemek için kullanılıyor.


int16 T1,T2;
int i=0; // sayi hengi tristörü tetikleyeceğimizi seçmek için

//****************** Timer0 Kesmesi *****************************

#int_timer1  // Timer1 kesmesi
void  timer1_kesme ()   // Kesme fonksiyonu ismi
{
   //set_timer1(63036); // TMR1 değeri belirleniyor

   i++; // i değeri 1 arttırılıyor

   if (i==50){
     output_high(Triyak);
   }
   if (i==100)
   {
      output_low(Triyak);
   }
   if(i==150){
   i=0;
   }
}

//********************Ana Program**********************************

void main()
   {

   set_tris_c(0x80);
   set_tris_d(0);

   setup_port_a( ALL_ANALOG );
   setup_adc( ADC_CLOCK_DIV_32 );            //   setup_adc( ADC_CLOCK_INTERNAL );
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); // Timer1 ayarları yapılıyor
   set_timer1(63036);                        // TMR1 değeri belirleniyor
   enable_interrupts(INT_timer1);            // int_timer1 kesmesini aktif yapar
   enable_interrupts(GLOBAL);                // Aktif edilen kesmelere izin ver

   lcd_init();

   while(1)
   { 
   
   set_adc_channel(1);
   T1 = read_adc();
     
   set_adc_channel(2);
   T2 = read_adc();

   //printf(lcd_putc,"\f i=%Lu i=%Lu", i, i);
   
  
   //output_high(Triyak);
   //delay_ms(T1);
   //output_low(Triyak);
   //delay_ms(T2);   
   
    while(1);   // Sonsuz döngü
    
   }
 



}

kostebek

Arkadaşlar yaptım sonunda.

Buyurun

Potansiyometreden okunan değerler doğrultusunda high low süreleri değiştiriliyor




//////////////////////////////////////////////////////////////////////////////////////
////                  DALGA PAKETLERİ                                               // 
////  Bu devrede T1 ve T2 süreleri potansiyometre ile AN1, AN2 kanallarından        //
///   okunuyor. Triyak sıfır gerilim şalteri gibi ON-OFF kontrol ile çalıştırılıyor //
//////////////////////////////////////////////////////////////////////////////////////
#include <16F877.H>
#device *=16
#DEVICE ADC=10
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#include <lcd.c>
#define Triyak       PIN_D0   // Triyak tetiklemek için kullanılıyor.
int16 T1,T2,A,B;
int i=0; // sayi hengi tristörü tetikleyeceğimizi seçmek için
//Triyak ON Fonksiyonu
void tetik()
{
   output_high(Triyak);

}
//Triyak OFF Fonksiyonu
void sustur()
{
    output_low(Triyak);
    //i=0;
}
//****************** Timer0 Kesmesi *****************************
#int_timer1  // Timer1 kesmesi
void  timer1_kesme ()   // Kesme fonksiyonu ismi
{
   
   i++; // i değeri 1 arttırılıyor
   A=(T1/60);  //T1den alınan sayıyı orantılı olarak küçültelim
   B=(T2/60);
      printf(lcd_putc,"\f HIGH=%Lu  \n LOW=%Lu", A, B);
   if(i==1)
   {
   tetik();        
   }  
   //i sayısı A oluncaya kadar tetikle
    if(i==A) 
    { 
      sustur();        
    }   
   //i sayısı B oluncaya kadar sustur
     if(i==B)
     {
      i=0;
     }
   //i'yi sıfırlayıp  tekrar tetiklemeye git
}



//********************Ana Program**********************************

void main()
   {

   set_tris_c(0x80);
   set_tris_d(0);

   setup_port_a( ALL_ANALOG );
   setup_adc( ADC_CLOCK_DIV_32 );            //   setup_adc( ADC_CLOCK_INTERNAL );
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); // Timer1 ayarları yapılıyor
   set_timer1(65536);                        // TMR1 değeri belirleniyor
   enable_interrupts(INT_timer1);            // int_timer1 kesmesini aktif yapar
   enable_interrupts(GLOBAL);                // Aktif edilen kesmelere izin ver

   lcd_init();

   while(1)
   { 
   set_adc_channel(1);
   T1 = read_adc();
     
   set_adc_channel(2);
   T2 = read_adc();
   
    while(1);   // Sonsuz döngü
   }
 



}

picusta

Kardes, istersen lcd'ye yazdirma isini interruptta değilde Ana döngünün içinde yap (su an ana döngü bos), ayrica periyodik olarak ADC'den okuma yapsan ona göre PWM'i dinamik olarak ayarlasan daha da hos olacak.

kostebek

Alıntı yapılan: "picusta"Kardes, istersen lcd'ye yazdirma isini interruptta değilde Ana döngünün içinde yap (su an ana döngü bos), ayrica periyodik olarak ADC'den okuma yapsan ona göre PWM'i dinamik olarak ayarlasan daha da hos olacak.

Evet aslında gayet mantıklı. Hem lcd ye yazmak için gereken süreyi de her interrupt da geçirmemiş olurum

Teşekkürler  :)