74HC595 ile yapılan PWM frekansı nasıl sabitlenir?

Başlatan silver_wolf, 28 Nisan 2022, 13:01:29

silver_wolf

Selam Arkadaşlar;
PIC12F675 ile sürülen 74HC595'teki bütün portlardan 10Hz sabit frekans almak istiyorum.

şeması ve çalışma şekli
#include <12F675.h>
#use delay(internal=4000000)
#fuses INTRC_IO, NOMCLR, NOBROWNOUT, NOPROTECT, NOCPD, NOPUT, NOWDT
unsigned int8 i=0, in_byte=255, out_byte=0, dutyQ0=50, dutyQ1=50, dutyQ2=50, dutyQ3=50, dutyQ4=50, dutyQ5=50, dutyQ6=50, dutyQ7=50;
const  unsigned int8 t0_byte=195;
/*************** Timer0 Kesmesi****************/
#int_timer0
void timer0_kesme(){
   unsigned int8 j=8;
   
   set_timer0(t0_byte);
   // Buton okuyan ve çıkış gönderen kısım
   output_low(PIN_A4);
   #asm
   nop
   #endasm
   output_high(PIN_A4);
   do{
      j--;
      /// 74165 SO'dan data oku ///////////////////////////////
      if(input(PIN_A5)){
    bit_set(in_byte,j);
      }else{
    bit_clear(in_byte,j);
      }
      ////////////////////////////////////////////////
      // 74595 DS'ye data yaz
      output_bit(PIN_A1,bit_test(out_byte,j));
      
      output_high(PIN_A0);
      #asm
      nop
      #endasm
      output_low(PIN_A0);
   }while(j>0);
   output_high(PIN_A2);
   #asm
   nop
   #endasm
   output_low(PIN_A2);
   ///////////////////////////////////////////////////
   
   if(i<=dutyQ0 && dutyQ0!=0 || dutyQ0==100){
      bit_set(out_byte,0);
   }else if(i>dutyQ0 && dutyQ0!=100 || dutyQ0==0 ){
      bit_clear(out_byte,0);
   }

   if(i<=dutyQ1 && dutyQ1!=0 || dutyQ1==100){
      bit_set(out_byte,1);
   }else if(i>dutyQ1 && dutyQ1!=100 || dutyQ1==0 ){
      bit_clear(out_byte,1);
   }
   
   if(i<=dutyQ2 && dutyQ2!=0 || dutyQ2==100){
      bit_set(out_byte,2);
   }else if(i>dutyQ2 && dutyQ2!=100 || dutyQ2==0 ){
      bit_clear(out_byte,2);
   }
   
   if(i<=dutyQ3 && dutyQ3!=0 || dutyQ3==100){
      bit_set(out_byte,3);
   }else if(i>dutyQ3 && dutyQ3!=100 || dutyQ3==0 ){
      bit_clear(out_byte,3);
   }
   
   if(i<=dutyQ4 && dutyQ4!=0 || dutyQ4==100){
      bit_set(out_byte,4);
   }else if(i>dutyQ4 && dutyQ4!=100 || dutyQ4==0 ){
      bit_clear(out_byte,4);
   }
   
   if(i<=dutyQ5 && dutyQ5!=0 || dutyQ5==100){
      bit_set(out_byte,5);
   }else if(i>dutyQ5 && dutyQ5!=100 || dutyQ5==0 ){
      bit_clear(out_byte,5);
   }
   
   if(i<=dutyQ6 && dutyQ6!=0 || dutyQ6==100){
      bit_set(out_byte,6);
   }else if(i>dutyQ6 && dutyQ6!=100 || dutyQ6==0 ){
      bit_clear(out_byte,6);
   }
   
   if(i<=dutyQ7 && dutyQ7!=0 || dutyQ7==100){
      bit_set(out_byte,7);
   }else if(i>dutyQ7 && dutyQ7!=100 || dutyQ0==7 ){
      bit_clear(out_byte,7);
   }
   
   i++;
   if(i==101) i=0;
}
void main(void)
 { 
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_16); // Timer0 ayarları yapılıyor
   set_timer0(t0_byte);   // TMR0 değeri belirleniyor


   enable_interrupts(INT_timer0); // int_timer0 kesmesini aktif yapar
   enable_interrupts(GLOBAL);     // Aktif edilen kesmelere izin ver
   while(TRUE){
      if(in_byte==0b11111110){
         dutyQ0=100;
      }
      if(in_byte==0b11111101){
         dutyQ0=75;
      }
      if(in_byte==0b11111011){
         dutyQ0=50;
      }
      if(in_byte==0b11110111){
         dutyQ0=25;
      }
      if(in_byte==0b11101111){
         dutyQ0=0;
      }
   }
 }  

mehmet

#1
100mS 50mS aralıkla çıkışları
1/0 yapsanız olmuyor mu?



:02000000FD2BD6
:10071E008312A30085102308A323831285140800D7
:10072E0007308312990083169F0183128501831669
:10073E0005110510851008008312A1000830A000D5
:10074E002008A20022080319080005100511A11B9C
:10075E0005150310A10D05140130A202A92BC830F6
:10076E008312A4002408A7009723831227080319D5
:10077E00DC2BFF308F2341308312A500EE30A40016
:10078E00A40BC72BA50BC72B000000308F234130C5
:10079E008312A500EE30A400A40BD32BA50BD32BF4
:1007AE00000001308312A702BC2BFF308F230330D1
:1007BE008312A6008A30A5005530A400A40BE52BA9
:1007CE00A50BE52BA60BE52BEC2B00308F2303306E
:1007DE008312A6008A30A5005530A400A40BF52B79
:1007EE00A50BF52BA60BF52BFC2BDC2B8301B62BC7
:08400000FF3FFF3FFF3FFF3FC0
:02400E0044303C
:00000001FF
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
http://www.mehmetbilgi.net.tr

silver_wolf

Selam @mehmet hocam;
 Aynı programlama dilini kullanıyorsak da neresini modifiye etmem gerekli? Timer0'ı nasıl kalibre etmem lazım? Ya da eğer mümkünse incelemem için kaynak kodunu da paylaşabilir misin? 

Alıntı yapılan: mehmet - 28 Nisan 2022, 18:10:14100mS 50mS aralıkla çıkışları
1/0 yapsanız olmuyor mu?



:02000000FD2BD6
:10071E008312A30085102308A323831285140800D7
:10072E0007308312990083169F0183128501831669
:10073E0005110510851008008312A1000830A000D5
:10074E002008A20022080319080005100511A11B9C
:10075E0005150310A10D05140130A202A92BC830F6
:10076E008312A4002408A7009723831227080319D5
:10077E00DC2BFF308F2341308312A500EE30A40016
:10078E00A40BC72BA50BC72B000000308F234130C5
:10079E008312A500EE30A400A40BD32BA50BD32BF4
:1007AE00000001308312A702BC2BFF308F230330D1
:1007BE008312A6008A30A5005530A400A40BE52BA9
:1007CE00A50BE52BA60BE52BEC2B00308F2303306E
:1007DE008312A6008A30A5005530A400A40BF52B79
:1007EE00A50BF52BA60BF52BFC2BDC2B8301B62BC7
:08400000FF3FFF3FFF3FFF3FC0
:02400E0044303C
:00000001FF

mehmet

Timer kesmesi kullanmadım. Sadece
HC595 'e 0xFF ve 0x00 değerlerini
50ms aralıkla yolladım.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
http://www.mehmetbilgi.net.tr

silver_wolf

#4
@mehmet; hocam sanırım derdimi eksik anlatıyorum. Benim yüklediğim gif'te 8 tane PWM çıkışı var. 74165'deki butonlara göre HC595' Q0 çıkışı değişiyor ve %100, %75, %50, %25 ve %0 oluyor. Fakat ISIS'te PWM sinyalinin frekansını sabit 10Hz alamadım.

Benim amacım sabit frekanslı pwm üretmek ve bununla da led, servo falan sürmek.

mehmet

#5
Tarama hızını hesaplayalım. Sonra
bu işi F675 yapar mı bakalım.
Buton okuma olmasın.
Her bir kanal 8bit, 8 kanal ve
10Hz. Ayrıca her kanalın zamanının
dolup dolmadığını anlayabilmek için
şart döngüleri ve HC595 sürme kodları
gecikmesi...

4MHz / 4 = 1MHz saat döngüsü yeter mi
sizce?

Ek:
Alttaki linkde Arduino ile yapmaya çalışmışlar.
Uzun zaman önce deneme yapmıştım.
Bulmaya çalışırım.
https://forum.arduino.cc/t/arduino-74hc595-and-pwm-how/44120/15
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
http://www.mehmetbilgi.net.tr

mehmet

#6
F675, RC osilatör 20MHZ iken;
Timer1, 4KHz. ayarlanır ve bu
zamanlayıcıya bağlı kesme oluşturulursa:

HC595 'in 8 çıkışından 8Hz-12Hz
arası (oynak) PWM alınabiliyor.

Sümülaysyonda denedim. Bir kaç
gün içinde HC595 kartı yapıp, gerçek
devrede deneyeceğim.

Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
http://www.mehmetbilgi.net.tr

ete

PWM den bahsedince Duty değerinden de bahsetmek gerekir. %50 duty değerine sahip 10 Hz lik bir sinyalin peryodu 1000/10=100 ms olur. Bunun %50 si HIGH ve kalanıda LOW olacak ise, 595 pinlerinden 50 ms süre ile HIGH ve 50 ms süre ile LOW çıkartarak istenilen sonuç alınabilir.

Komut gecikmelerinide hesaba katmak gerekebilir.

Ete

ete

Basit bir program yazdım ve sonuç düşündüğüm gibi.
Dosyalar ilişiktedir. Deneyebilirsiniz.
her 50 ms de bir kesme yaratmak için TMR0 sayacına 60 önyükleme değeri vermek gerekiyor.
Bu değerle 50,5 ms de bir kesme oluştu. 60 değerini 61 yapınca net 50 ms ye düştü düzgün gözüküyor.

Ete

mehmet

#9
HC595 'in her kanalına ayrı ayrı veya
değişken duty değeri verirsek?
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
http://www.mehmetbilgi.net.tr

ete

İşte onu 12F675 ile yapacak olana gerçek usta derim.
Ete


alisumer

#11
Alıntı yapılan: silver_wolf - 28 Nisan 2022, 13:01:29IC12F675 ile sürülen 74HC595'teki bütün portlardan 10Hz sabit frekans almak istiyorum.
başka yöntemler de vardır ama ilk aklıma gelen 2 tanesi birincisi 0x55 sayısını clk bacaklarını sıra ile tetikleyerek (billmiyorum yonga içi gecikmesi ne kadardır belki aynı anda tetikleme ile de çalışabilir simulasyonda oluyor) sürekli göndermek faz kaymalı olarak bütün bacaklarda aynı frekansta ve aynı iş oranında (iş oranını vereceğiniz değer belirler belli çözünürlülükte ayarlanabilir örneğin sadece 1 vererek sürerseniz iş oranı 1/8 olur 55 verirseniz 1/1 olur gibi çıkış alırsınız.ikincisi ise faz kaydırmadan flipflop gibi davranan(şekil olsun diye) 8 bit 0x55 i sadece shcp bacağı tetiklenip tüm bitlerin bitiminde stcp bacağı ile çıkışa verip uygun bir bekleme sonrasında (üreteceğin frekans ve iş süresini senin hesaplaman gerekecek)ardından bu sefer 0xAA verisini aynı yöntemle gönderip en sonunda stcp ile çıkışa vermek frekans düşük olduğundan baş edilebilir iki yöntem.   yada ff ve 00 da gönderebilirsin aynı yöntemle  bu sefer bütün bacaklardan aynı anda 1 yada aynı anda 0 alırsın tam senkron çalışırar
Hep meraktan

alisumer

birde şöyle seçeneklerin var reelde nasıl tepki verir bilemem :)

Hep meraktan

mehmet

#13
Biraz abartmışım galiba... 8)


20MHz lik kristal osilatör ile F675 'i çalıştırdım.
TMR1 ile 10KHz lik kesme oluşturdum.
Bu kesme içerisinde; genelde tanımlanmış
16 adetlik 8-bit dizi içerisindeki değerleri
soft-pwm işlemi yapıp iki adet HC595 üzerine
yolladım. PWM 6-bit olarak ayarlandı.
Kanal başına 45-55Hz aralığında değişken
frekans oluşturuldu. Duty değeri ile her bir
lede ayrı ayrı seviye verildi.
Frekans sabit değil. Dolayısıyla pro işlerde
kullanmak uygun olmayabilir. Ayrıca, boşta
sadece MCLR pini kaldı.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
http://www.mehmetbilgi.net.tr

ete

Algoritma (akıl) olarak fikir fena değil. Ama her şey alt limitlerde çalışıyor. Yinede bir şeyler olmuş gibi gözüküyor. Tebrik ederim. Ustasın.

Ete

Powered by EzPortal