MikroC kullanarak gecikme açısı verme

Başlatan ferdi carrefour, 22 Mart 2016, 18:53:23

ferdi carrefour

Merhaba arkadaşlar

Ben zerocross devresinden aldığım sinyalin, pic16f877a ya yazdığım kod ile sıfır geçişlerini bulup sonra da ADC yaparak Potansiyometre yardımı ile gecikme vermek istiyorum ve böylece 2 scr 3 diyot modülü (vhf36-16ı05) tetikleyerek DC motorun hızını kontrol etmek istiyorum. Projemi proteus ta sounsuz bir şekilde çalıştırıyorum. yani şöyle açıklayayım, Zero cross dan aldığım sinyali pic16f877a ya okutup pot yardımı ile gecikme verebiliyorum, ayrı bir devrede de BT151 tetikliyorum. 2scr 2 diyot kurduğum devreyi de tetikliyorum.
Fakat bu devrelerden mikroişlemci kullanıp gecikme verdiğim devreyi breadrboarda kurduğumda osiloskopta hiçbir sinyal göremiyorum, aynı zamanda bt151 tetiklediğim devrede de SCR belli bir süre iletimde gözüküp yarım dalga doğrulturken belli bir süre sonra da sinyal gözükmüyor yani bir süre sonra kendi kendine kesime gidiyormuş gibi oluyor. Bunun nedenini kullandığımız yük olarak düşünüyoruz. Bu devrede yük beyaz led ve 1k direnç kullanmıştık bu sonucu elde etmiştik. Aynı devreyi akkor lamba kullanarak tekrar deneyip sağlıklı sonuç alacağımızı umuyoruz fakat yazılım kısmında, yani pic16f877a da ki sorunumuzun neden kaynaklandığını anlayamadık.
Bu konu hakkında tavsiye verip yardımcı olabilecek birileri var mı acaba ? Yazılımda mı devrede mi ? nerde sıkıntımız var yardımcı olabilir misiniz ? Teşekkürler

Yazdığımız kod
long int veri=0;
float voltaj=0,gerilim=0;
unsigned char FlagReg;
sbit ZC at FlagReg.B0;

void interrupt(){
if (INTCON.INTF){ //kesme oluşması için INTCON.INTF bayrağı kaldırdı
ZC = 1;
INTCON.INTF = 0;

  if (ZC){ //zero crossing oluştu
 Vdelay_ms(gerilim); // gerilim değerine göre gecikme zamanı

PORTD.f0 = 1;
delay_us(100); //100us pulse göndersin POZİTİF ALTERNANSDAKİ SCR Yİ TETİKLEMEK İÇİN
PORTD.f0 = 0;
delay_us(9000); //iki scrnin tetiklenme sürelerinin farkı
PORTD.f1 = 1;
delay_us(100); //100us pulse göndersin NEGATİF ALTERNANSDAKİ SCR Yİ TETİKLEMEK İÇİN
PORTD.f1 = 0;
ZC = 0;
}
}
}

void main() {
TRISA= 0b00000100;   // potansiyometre girişi
TRISD = 0b11111100; // RD0 ve RD1 is output
TRISB = 0x01; //RB0 giriş yapıldı
OPTION_REG.INTEDG = 1; //yükselen  kenarda tetikleme
INTCON.INTF = 0; // INT bayrağını sil
INTCON.INTE = 1; //Rb0 KESMESİNE MÜSADE ET
INTCON.GIE = 1; //BÜTÜN KESMELERE MÜSADE ET
   adcon0=0b10010000;  // kanal2(AN2)seçildi.
   adcon1=0b10000010; // 5 analog,3 dijital uç olacak şekilde ayarlandı

 do
{
        veri=ADC_Read(2); //Kanal 2 seçildiğinde ADC_Read(2) olur.
        voltaj=(0.004887586*veri);
        gerilim=11*voltaj; // Gerilim bölücüyle 11 kat gerilimi küçültük.Yazılımla 11 kat büyütüyoruz.


  }
while(1);
}


Çalışmalarımız

https://www.dropbox.com/sh/iuh6xm7afg6x2xw/AADAUlCPbDqratMXl1N8yUfVa?dl=0

35Murat35

Merhaba
Koda biraz baktım negatif ve pozitif alternans için işlemler yapmışsın ama o anki alternansın pozitif yada negatif olduğunu nasıl anlıyosun.
50hz şehir şebekesinde 1000ms / 50 = 20ms yani tek alternans 10ms. Bunu zaten hesaplamış ve kodun içine yazmışsın sanırım. 10ms yani 10.000uS içinde palsin genişliğiyle oynayıp parlaklık/hız neyse onu kontrol edeceksin.
ADC'den max 1023 gelicek. Sana 0-10000 arası değer lazım. Bu durumda çarpanın 9,77517 gibi bi sayı oluyo. ADC'den okuduğun değeri 9,77517 ile çarpıp gecikme değişkenine atman gerekiyor. Hesapladığın sayıyı lojik bir süresinceki gecikmeye uygulayıp sonra lojik 0'a çek. Ondan sonra gecikme vermene gerek yok zaten bir sonraki alternans gelecek kesmeyle.
Tabi bu hesapları kabaca yaptım. Derleyicinin ürettiği asm kodlarından satırları sayarak extra gecikmeleri düşebilirsin veya kesmenin içini direk asm yazabilirsin.