PWM Frekans 100Hz-1000Hz Ayarı

Başlatan PICaso, 02 Mayıs 2021, 16:23:33

ipek


PICaso

4 adet buton olan sistemde  100 Hz - 1 KHz ve %10 - %100 duty elde edeceğim bir kare dalga sinyali üretmem gerekiyor.

Pic16f877 ve MikroC zorunlu olarak kullanmam gerekiyor.

void main()
{    OPTION_REG=0x06;         // 0b00000110
// dahili osc.; PSA=0,PS2:1,PS1=1,PS0=0,  (1/64)
     INTCON.GIE  = 1;        // Tüm kesmelere izin
     INTCON.T0IE = 1;       // Timer kesmesi izin
     TRISC=0;
     PORTC =0;
     TMR0   = 225;

Fosc = 8MHz seçtim. Bu kod ile 1ms timer kurduğumu düşünüyorum. 100Hz-1000Hz arası 10 farklı frekans değeri benim için yeterli.

Bu noktaya kadar herhangi bir hatam var mıdır değerli hocalarım?

power20

#32
İnterrupt fonksiyonu görünmüyor. Kodu biz mi deneyelim? Proteus  yok mu? İnterrupt çalışıyor mu ? LED yanıp sönüyor mu? Frekans istediğiniz gibi mi?

PICaso

Alıntı yapılan: Kılıç - 05 Mayıs 2021, 02:56:48İnterrupt fonksiyonu görünmüyor. Kodu biz mi deneyelim? Proteus  yok mu? İnterrupt çalışıyor mu ? LED yanıp sönüyor mu? Frekans istediğiniz gibi mi?
void interrupt()            // Kesme alt programı
{    INTCON.TMR0IF=0;  //Kesme bayrağı reset
    TMR0  = 225;
 }
void main()
{    OPTION_REG=0x06;        // 0b00000110
// dahili osc.; PSA=0,PS2:1,PS1=1,PS0=0,  (1/64)
    INTCON.GIE  = 1;        // Tüm kesmelere izin
    INTCON.T0IE = 1;      // Timer kesmesi izin
    TRISC=0;
    PORTC =0;
    TMR0  = 225;

while(1){
      PORTC.B1 = 0;
      interrupt;
      PORTC.B1 = 1;
      interrupt;
}
}


take picture online hd

Hocam proteusta da pici 8MHz seçtim. osiloskop çıktısı neden böyle çıktı anlamış değilim.

power20

#34
İnterrupt main içine adını yazarak çağırılmaz. 
Süre aşımında kendisi çalışır.

 Hazır Timer interrupt örneklerinden yola çıkınız.

https://forum.mikroe.com/viewtopic.php?t=63432

alikeskinkilic

Alıntı yapılan: PICaso - 02 Mayıs 2021, 18:43:09MikroC neden izin vermiyor frekans değişimine anlamış değilim.
izin vermiyo demedimki ben anlamıyorum C den :)
ayrıca bütün diller asm ye derlenip öyle yazılır çipe ASM de yazılımsal olsun donanımsal olsun bütün pwm ler timer kullanır
aslında birkaç yolu var ana programda pot ile ayarını değiştirebileceğiniz bir word değişkeni atar  kesme kısmında ise (pic Basic için)
portb.1=1 -
pause x+değişken
portb.1 =0
pause x- değişken
yada  PULSOUT  PORTA.0 ,değişken +200

 
demen yeterli pot ile yaptığın değişim duty  değerini değiştirir kesme için de timer değerini aynı şekilde başka bir pot ile ayarlayıp frekansı ayrıca değiştirirsin
Hep meraktan

PICaso

unsigned int sayi;
unsigned int sayi1;
unsigned int topsayi;

void interrupt()            // Kesme alt programı
{    if(INTCON.TMR0IF){
       sayi++;
       TMR0 = 56;
       if(sayi<sayi1){PORTC.B1 = 1;}
       if(sayi>sayi1){PORTC.B1 = 0;}
       if(sayi==topsayi){sayi=0;}
       INTCON.TMR0IF=0;
}
 }


void main()
{
     OPTION_REG=0x00;         // 0b00000000 // dahili osc.; PSA=0,PS2:1,PS1=1,PS0=0,  (1/1)
     INTCON.GIE  = 1;        // Tüm kesmelere izin
     INTCON.T0IE = 1;       // Timer kesmesi izin
      INTCON.TMR0IF=0;
     TRISC=0;
     PORTC =0;
     TRISD = 0xFF; //buton bağlantıları
     sayi=0;
     sayi1=50;
     topsayi=sayi1*2;
do{
    if(tus1 == 0)      //FREKANS ARTAR
       {

        while(tus1==0);       // tus bırakmayı bekle
        }
    if(tus2 == 0)      //FREKANS AZALIR
        {

         while(tus2==0); // tus bırakmayı bekle
         }
     if(tus3 == 0)       //DUTY ARTAR
        {
         sayi1=sayi1++;
         while(tus3==0); // tus bırakmayı bekle
         }
     if(tus4 == 0)        //DUTY AZALIR
        {
         sayi1=sayi1--;
         while(tus4==0); // tus bırakmayı bekle
         }

}
while(1);
}

Değerli hocalarım yukarıda paylaştığım kod ile frekans sabit olup tus3 ve tus4 ile duty kontrol edebiliyorum.

Frekans kontrolünü bir türlü beceremedim. Kodda ne gibi değişiklik yapmalıyım?

power20

#37
TMR0 = 56;

Kısmı değişirse frekans değişir

if(tus == 0)      //FREKANS ... Ayar
        {

       Periyot++;

         while(tus==0); // tus bırakmayı bekle
         }


....

interrupt içinde
TMR0 = Periyot;