Arkadaşlar merhaba
16F877 ile mikroC de pwm frekansını buton ile artırıp azaltmak istiyorum.
Fakat PWM1_Init(frekans) frekans değeri değişken verilmiyormuş.
Nasıl bir kod yazmalıyım. Mantığı anlatabilir misiniz?
100Hz'e inebilmek için 877 1MHz gibi düşük frekansta çalışmalı
Başka dilde veya hex olarak yardımcı olabilirim.
ayrıca 16F877 çok kötü seçim.
Belki ayarlanması gereken pwm frekansı değildir. Emin misiniz?
dil değişebiliyorsan ASM yada basic yardımım olur istersen o.5 hz 1000hz arası da yaparsın üst sınırda kısıtlama var da altta nerde ise yok gibi
Alıntı yapılan: Kılıç - 02 Mayıs 2021, 17:53:29Belki ayarlanması gereken pwm frekansı değildir. Emin misiniz?
Dutyde frekansda ayarlanacak hocam. Eminim.
Alıntı yapılan: OG - 02 Mayıs 2021, 17:47:58100Hz'e inebilmek için 877 1MHz gibi düşük frekansta çalışmalı
Başka dilde veya hex olarak yardımcı olabilirim.
ayrıca 16F877 çok kötü seçim.
MikroC olması gerekiyor hocam
Alıntı yapılan: alikeskinkilic - 02 Mayıs 2021, 18:19:37dil değişebiliyorsan ASM yada basic yardımım olur istersen o.5 hz 1000hz arası da yaparsın üst sınırda kısıtlama var da altta nerde ise yok gibi
MikroC neden izin vermiyor frekans değişimine anlamış değilim.
Soft pwm işinizi görebilir mi?
Açık kodlu fonksiyonlar vardır.
Alıntı yapılan: Kılıç - 02 Mayıs 2021, 19:04:38Soft pwm işinizi görebilir mi?
Açık kodlu fonksiyonlar vardır.
Örnek var mı hocam bakabilir miyim?
https://libstock.mikroe.com/projects/view/1042/software-pwm
Yazılımsal nasıl olacak
hadi 100Hz veya 500Hz veya 1000Hz kolay ama
123Hz 982Hz üretmek istedik ne yapacağız?
Gerçek bir iş için lazımsa Si5332
(tam model hatırlayamadım şimdi)
gibi entegreler var.
982Hz 1/982 duty olarak üretmek için
Çıkışı On yapıyoruz.
0.00102sn bekliyoruz
Sonra off yapıyoruz
0.00102sn x 982 kadar bekliyoruz.
Bu işlemi döngü içinde yaparak süreklilik sağlanıyor.
Bir işe yaramaz niye öyle bir şey üretelim.
En azından 8 bit çözünürlüklü duty olmalı.
Yani 100Hz ~ 1000Hz arası frekansta
Hadi 8 bitte olmasın
%0 ~ %100 duty oranı %1 adımlarla ayarlanabilir,
pwm frekansı üretilecek olsun.
Bahsedildiği gibi 16F877 kullanılsın.
İşlemci yükü ne olacak,
üretilen pwm in frekans ve duty hatası ne kadar olacak?
Alıntı yapılan: RaMu - 02 Mayıs 2021, 20:03:00Yazılımsal nasıl olacak
hadi 100Hz veya 500Hz veya 1000Hz kolay ama
123Hz 982Hz üretmek istedik ne yapacağız?
Gerçek bir iş için lazımsa Si5332
(tam model hatırlayamadım şimdi)
gibi entegreler var.
100-1000 Hz arası artırıp azaltsam yeterli benim için.
Alıntı yapılan: RaMu - 02 Mayıs 2021, 20:43:55Bir işe yaramaz niye öyle bir şey üretelim.
En azından 8 bit çözünürlüklü duty olmalı.
Yani 100Hz ~ 1000Hz arası frekansta
Hadi 8 bitte olmasın
%0 ~ %100 duty oranı %1 adımlarla ayarlanabilir,
pwm frekansı üretilecek olsun.
Bahsedildiği gibi 16F877 kullanılsın.
İşlemci yükü ne olacak,
üretilen pwm in frekans ve duty hatası ne kadar olacak?
Hocam Timer kesme kullanarak frekans ayarı yapılabilir mi?
Alıntı yapılan: PICaso - 02 Mayıs 2021, 18:41:04Dutyde frekansda ayarlanacak hocam. Eminim.
Demiştin.
Alıntı yapılan: PICaso - 02 Mayıs 2021, 20:48:52100-1000 Hz arası artırıp azaltsam yeterli benim için.
dedin.
Duty ayarlanabilecek mi?
Ayarlanmalıysa en az ne çözünürlükte olmalı
yani %10 20 30 .. 90 100 yeterli mi gibi?
Alıntı yapılan: RaMu - 02 Mayıs 2021, 21:00:43Demiştin.
dedin.
Duty ayarlanabilecek mi?
Ayarlanmalıysa en az ne çözünürlükte olmalı
yani %10 20 30 .. 90 100 yeterli mi gibi?
yeterli hocam.
switch(sayac) {
case 1:
PWM1_Init(1000);
break;
case 2:
PWM1_Init(200);
break;
case 3:
PWM1_Init(300);
break;
case 4:
PWM1_Init(400);
break;
case 5:
PWM1_Init(500);
break;
case 6:
PWM1_Init(600);
break;
case 7:
PWM1_Init(700);
break;
case 8:
PWM1_Init(800);
break;
case 9:
PWM1_Init(900);
break;
default:
PWM1_Init(1000);
Şöyle bişey düşündüm çalışır mı sizce?
https://download.mikroe.com/documents/compilers/mikroc/pic/help/pwm_library.htm
note
kısmına bakarsan çalışmaz.
Alıntı YapCalculation of the PWM frequency value is carried out by the compiler, as it would produce a relatively large code if performed on the library level.
Therefore, compiler needs to know the value of the parameter in the compile time. That is why this parameter needs to be a constant, and not a variable.
derleyici init fonksiyonuna yazdığın değeri derleme esnasında kullanıp
gerekli register ayarlamalarını yapıyor.
Yani hex oluştuktan sonra init fonlsiyonunda bir değişiklin yapılamıyor.
Nasıl yapılabilir hocam?
"Pic Pwm frekans hesabı"
konularına biraz bakın anlaşılmayan yer olursa yardımcı olmaya çalışırım.
Yazılımsal pwm içinde halen sınırları net bir şekilde belirtmedin
ama
bahsettiklerimizi baz alarak
şu frekansı şu duty ile üretmek için
ne zamanda bir bir timer kesmesine girsem
pini on sonra off yapsam
...
bunu kağıt kalem ile birkaç frekans için hesapla oluyor mu.
Örnek olması açısından
pic pwm frekansı elle şu registetlara değer girerekte yapılabilir:
(mikroc de bunu elle yaparsan duty ayarı içinde uygun değeri hesaplayıp kendin girmen gerekir,
mikroc duty fonksiyonu doğru çalışmaz.)
PWM Period = [(PR2) + 1] • 4 • TOSC • (TMR2 Prescale Value)
https://www.picproje.org/index.php/topic,30295.0.html
https://etepic.com/index.php?topic=3359.0
Alıntı yapılan: RaMu - 02 Mayıs 2021, 21:51:14"Pic Pwm frekans hesabı"
konularına biraz bakın anlaşılmayan yer olursa yardımcı olmaya çalışırım.
Yazılımsal pwm içinde halen sınırları net bir şekilde belirtmedin
ama
bahsettiklerimizi baz alarak
şu frekansı şu duty ile üretmek için
ne zamanda bir bir timer kesmesine girsem
pini on sonra off yapsam
...
bunu kağıt kalem ile birkaç frekans için hesapla oluyor mu.
Örnek olması açısından
pic pwm frekansı elle şu registetlara değer girerekte yapılabilir:
(mikroc de bunu elle yaparsan duty ayarı içinde uygun değeri hesaplayıp kendin girmen gerekir,
mikroc duty fonksiyonu doğru çalışmaz.)
PWM Period = [(PR2) + 1] • 4 • TOSC • (TMR2 Prescale Value)
https://www.picproje.org/index.php/topic,30295.0.html
https://etepic.com/index.php?topic=3359.0
(https://i.ibb.co/RgwzSSx/Ekran-Al-nt-s.png) (https://ibb.co/RgwzSSx)
fotoğraf upload (https://tr.imgbb.com/)
Fosc =200kHz seçtim ve TMR2 Prescale Value=16 için formülü uyguladığımda
PR2=2 değerinde pwm frekansı 1041,6 Hz,
PR2=30 değerinde pwm frekansı 100,8 Hz, olarak hesapladım.
Doğru yoldamıyım hocam?
PWM Period = [(PR2) + 1] • 4 • TOSC • (TMR2 Prescale Value)
Tp = (2+1)*4 * (1/200kHz) * 16
Tp = 0.00096 saniye
fp = 1/Tp
fp = 1041.67 Hz
Evet hesap doğru ama
Tosc işlemci çalışma frekansı
yani 200kHz de çalışan bir mcu ne kadar işe yarar?
Mcu nun yapacağı başka işler varsa muhtemelen bir işe yaramaz.
Tamam olur desek ben şu ana kadar 200kHz osilatörü ne mcu da kullandım nede gördüm,
var mı şehir efsanesi mi onu bile merak etmedim hiç :)
Mcu 4MHz kristal ile çalışırken oluyor mu dene bir değerleri,
hiç olmadı en kötü mcu 1MHz kristal ile çalışsın.
Ek:
Daha duty oranını ayarlama var
oda PR2 değerine bağlı
CCPxx registerlarıyla ayrlanıyor.
kısaca PR2 değeri kaç ise o kadar bölebilirsin duty oranını.
Mesela PR2 100 ise
0,1,2...100 CCPx değerleriyle duty i 100 adım ile ayarlayabilirsin,
CCPx 50 değeri %50 duty olur.
Mesela PR2 2 ise
0,1,2CCPx değerleriyle duty i 2 adım ile ayarlayabilirsin,
CCPX 0 0 duty
CCPX 1 %50 duty
CCPX 2 % 100 duty olur.
Ayrıca böyle olacağını
@OG söylemişti.
Onun bildiği bu işe uygun mcular var :)
Alıntı yapılan: OG - 02 Mayıs 2021, 17:47:58100Hz'e inebilmek için 877 1MHz gibi düşük frekansta çalışmalı
Başka dilde veya hex olarak yardımcı olabilirim.
ayrıca 16F877 çok kötü seçim.
Alın o zaman değişik bir fikirde ben yumurtlayayım. PWM için kullanılacak timer ın clock kaynağı harici seçilip (TXCKI ima ediyorum) buradan 200KHz lik sinyal verilebilir. Yapılacak işin detayını tam bilmiyorum. Eğer boşta kalan pwm kaynağı varsa burası 200KHz lik sabit üreteç olarak kullanılabilir. Böylece harici elemanlarla osilatör kurmaya gerek olmadan iki pinin pcb de birleştirilmesi yeterli olur.
@yas duty ayarı içinde birşey uydurabilirsen olur.
Zaten 16f877 uygun değil dememiz ondan
pwm clock için harici bir şey seçilemiyor.
Süt oğlan misali 16f877 yi oldum olası sevmedim zaten, babasını da sevmezdim. Yanlış hatırlamıyorsam 16f877 pwm için sadece timer2 kullanılıyordu ve timer2 nin harici clock girişi yoktu. Evet 16f877 görevini tamamlamış gibi. Yeni hiçbir işte kullanılmaması gerekli.
duty olayı çok zor olmamalı aslında. 10 bitlik çözünürlükte duty değeri 0-1023 (biz ona 0-1000 diyelim) olabileceğinden %0-100 arası değiştirilmek istenildiğine göre iki değişken kullanılmalı birisi 0-100 arası skalanın girildiği değişken diğeri bu değerin 10 ile çarpıldığı duty olacak olan word boyutundaki değişken. Eğer skalanın 0-1000 olmasında bir mahsur yoksa tek word değişkende olabilir.
I = 50 '%50
DUTY = I * 10
CCP1CON.4 = DUTY.0
CCP1CON.5 = DUTY.1
CCPR1L = DUTY >> 2
Yada
DUTY = 500 '~%50
CCP1CON.4 = DUTY.0
CCP1CON.5 = DUTY.1
CCPR1L = DUTY >> 2
@yas yazdıklarından şair burada ne demek istemiş anlayamadım.
16F877 nin donanımsal Pwm de neler yapabileceğinin nasıl anlaşılacağını yukarıdaki mesajlarda anlattım.
Yazılımsal yaparım diyen babayiğitlerede
100Hz 1000Hz Pwm i 1Hz çözünürlükle
0 %100 duty yi %1 adımlarla
ayarlayabileceğimiz kodu yazmak öyle kolay iş değil dedim.
Alıntı yapılan: RaMu - 02 Mayıs 2021, 21:51:14"Pic Pwm frekans hesabı"
konularına biraz bakın anlaşılmayan yer olursa yardımcı olmaya çalışırım.
Yazılımsal pwm içinde halen sınırları net bir şekilde belirtmedin
ama
bahsettiklerimizi baz alarak
şu frekansı şu duty ile üretmek için
ne zamanda bir bir timer kesmesine girsem
pini on sonra off yapsam
...
Hocam Pwm değilde timer ile bir pini ON-OFF yapmak daha mantıklı ve kolay gibi duruyor.
Timer kesmesi oluştuğunda bir sayac artsın. Sayac 100 olduğunda asıl pwm periyodu tamamlanmış olur. Her kesmede çıkışın on veya off yapılacağına karar verilebilir.
Örneğin sayac 0 iken on oldu
Sayac 10 ilen off yapalım
Sayac 100 olana kadar hep off kalsın
Bu durumda %10 duty değeri elde ettik demektir.
Timer periyodu ile pwm frekans ı ayarlamak mümkün.
Timer 100 katı pwm periyodu olur.
Çözünürlük az gelmişse 100 değil 1000 olarak hesap yapılabilir. Binde 1 hassasiyet olur
Alıntı yapılan: Kılıç - 04 Mayıs 2021, 09:13:15Timer kesmesi oluştuğunda bir sayac artsın. Sayac 100 olduğunda asıl pwm periyodu tamamlanmış olur. Her kesmede çıkışın on veya off yapılacağına karar verilebilir.
Örneğin sayac 0 iken on oldu
Sayac 10 ilen off yapalım
Sayac 100 olana kadar hep off kalsın
Bu durumda %10 duty değeri elde ettik demektir.
Timer periyodu ile pwm frekans ı ayarlamak mümkün.
Timer 100 katı pwm periyodu olur.
Çözünürlük az gelmişse 100 değil 1000 olarak hesap yapılabilir. Binde 1 hassasiyet olur
Evet böyle daha kolay gibi.
sanki Atmel bu konuda daha becerikli...
http://www.zl2pd.com/pwmgen.html
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?
İ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?
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;
}
}
(https://i.ibb.co/V0yJG5c/Ekran-Al-nt-s.png) (https://ibb.co/V0yJG5c)
take picture online hd (https://tr.imgbb.com/)
Hocam proteusta da pici 8MHz seçtim. osiloskop çıktısı neden böyle çıktı anlamış değilim.
İ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
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
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?
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;