PIC16F628A kullanılarak 5 farklı frekansta, Duty Cycle oranları ayarlanılabilen PWM oluşturmak istiyorum. Mümkün müdür?
Sistem ilk açıldığında 100Hz, 1. butona tıkladığımda 150 Hz, tekrar tıkladığımda 200 Hz...250 Hz...300 Hz ve en son tekrar tıkladığımda 100 Hz olacak.
2. butona tıkladığımda Duty (+)
3. butona tıkladığımda Duty (-) ayarlanabilmeli...
Bu durum 16F628A için donanımsal ya da yazılımsal olarak mümkün müdür?
evet mumkun arkadasim
setup_timer_2(T2_DIV_BY_16,250,1); bu kod pwmin frekansini ayarlamaya yariyor...
ayarlar ayni kalsin degistirmeniz gereken sadece 250 yazan yer burasi.asagidaki formuldende bu degeri belirleyebilirsiniz...
PWM period = [(PR2) + 1] ⋅ 4 ⋅ Tosc ⋅ TMR2 prescale value
-PWM period =1/ PWM frequency
-TOSC =1 / FOSC
Donanımsal PWM ile 4MHz koştursan 145Hz e iner, frekansı daha düşürmen gerekir.
Xtal frequency Lowest useable Pwm frequency
4MHz 145Hz
8MHz 489Hz
10MHz 611Hz
12MHz 733Hz
16MHz 977Hz
20MHz 1221Hz
24MHz 1465Hz
33MHz 2015Hz
40MHz 2442Hz
Yazılımsal olarak mümkündür.
Butona her basışta frekansın değişmesi için "if" komutunu mu kullanmalıyım peki? Sonuçta sistem ilk açıldığında 100 Hz ile çalışacak, butona her bastığımda 50'şer Hz artacak ve en sonunda 300 Hz'den sonra 100 Hz'e geri dönecek.
pic baska islem yapacakmi peki yoksa sadece duty ve frekans ayarlama icin mi kullanilacak??
Alıntı yapılan: justice_for_all - 20 Kasım 2010, 22:33:06
pic baska islem yapacakmi peki yoksa sadece duty ve frekans ayarlama icin mi kullanilacak??
Yalnız ve yalnız 5 değişik frekans üretip bunların duty oranlarını ayarlayacak o kadar...
100-150-200-250 ve 300 Hz...
o zaman if le yapmanizda bi sakinca yok arkadasim...
algoritma ise soyle olabilir die dusunuyorum..
while(true)
{
if(frekans_butonu_basildiysa)
{
if(i==0)
setup_timer_2(T2_DIV_BY_16,250,1); ///burayi istediginiz frekans degerlerine gore duzenleyiniz.....(100 Hz)
else if(i==1)
setup_timer_2(T2_DIV_BY_16,250,1); ///burayi istediginiz frekans degerlerine gore duzenleyiniz.....(150 Hz)
else if(i==2)
setup_timer_2(T2_DIV_BY_16,250,1);///burayi istediginiz frekans degerlerine gore duzenleyiniz.....(200 Hz)
else if(i==3)
setup_timer_2(T2_DIV_BY_16,250,1);///burayi istediginiz frekans degerlerine gore duzenleyiniz.....(300 Hz)
else if(i==4)
setup_timer_2(T2_DIV_BY_16,250,1);///burayi istediginiz frekans degerlerine gore duzenleyiniz.....(400 Hz)
if(++i==5)
i=0;
}
}
frekans ayarlama islemi bu sekilde olur...
Not: Ama ilk once yukarida OG hocamin dedigini dikkate alman gerekli...
4MHz kristal kullandığımızda bunu donanımsal olarak yapamıyoruz ama...
Yazılımsal olarak nasıl yapacağız? Bildiğim kadarıyla 16F628'in dahili RC osilatörü olması lâzım. Bunu nasıl dikkate almalıyız?
peki ilk frekansin 100 hz yerine 150 hz olsa olmazmi??
Neden olmasın?
yani bazi uygulamalar icin hassas frekanslar gerekli ama senin uygulamanda okadar onemli degilse kristalin degeri icin kullanabilecegin minimum pwm frekansinda basla bence...
Kolay gelsin...
Gerçekten önemli ne yazık ki... Şimdiye kadar yaptığım araştırmalar; düşük frekansların yapmak istediğim iş için çok daha etkili olduğunu, yüksek frekansların ise yapmak istediğim işte tepki süresinin çok daha iyi olduğunu gösteriyor. İşin garip tarafı, şu an için; düşük frekanslar benim işimi çok daha iyi görüyor... Etki tepkiden daha önemli yani ???
Aklıma şöyle bir şey geldi:
Min. PWM frekansı kullanılan kristalin frekansına bağlı ve bu en düşük kristal frekansı 4Mhz olarak gösterilir... 1MHz'lik ya da ne bileyim 32.768kHz'lik kristal bağlanamıyor mu bu MCU'lara?
baglanir tabiki 1 Mhzlik alabilirsin arkadasim...
O zaman yazdığım frekansları alabilirim sanırım değil mi? ;D
evet minimum yaklasik 62 Hz e kadar pwm alabilirsiniz...
Alıntı yapılan: justice_for_all - 20 Kasım 2010, 23:42:58
evet minimum yaklasik 62 Hz e kadar pwm alabilirsiniz...
Harika...
Program 4MHz e göre yazılır, frekanslar da 4 katı yazılır, ancak pic 1MHz de koşturulur. Yani 1MHz lik kristal takılır. Simule ederken de PIC 1MHz e ayarlanır.
http://hotfile.com/dl/83894731/06287fa/dusuk_frekans_pwm.rar.html
[IMG]http://img641.imageshack.us/img641/6839/simc.png[/img] (http://img641.imageshack.us/i/simc.png/)
[IMG]http://img194.imageshack.us/img194/649/47581271.jpg[/img] (http://img194.imageshack.us/i/47581271.jpg/)
Device = 16F628A
Config BOREN_ON, CP_ON, DATA_CP_OFF, PWRTE_OFF, WDT_ON, LVP_OFF, MCLRE_OFF, INTRC_OSC_NOCLKOUT
Declare Xtal 4
All_Digital = TRUE
TRISA =%11111111
TRISB =%11110111
OPTION_REG=%00001111
Dim frekans As Word
Dim x As Byte
Dim deger As Byte
Dim hiz As 15
Dim f_degis As PORTB.0
Dim arttir As PORTB.6
Dim azalt As PORTB.7
PORTB = 0
DelayMS 100
clrwdt
EData 400,127
Basla:
frekans = ERead 0
deger = ERead 2
Goto cikisver2
bekle:
clrwdt
If arttir = 0 Then artiyor
If azalt = 0 Then azaliyor
If f_degis = 1 Then bekle
cikisver:
frekans = frekans + 200
If frekans > 1200 Then frekans = 400
cikisver1:
EWrite 0 , [frekans]
cikisver2:
HPWM 1,deger,frekans
cikisver3:
For x = 1 To 50
DelayMS 1
clrwdt
If f_degis = 0 Then cikisver3
Next
GoTo bekle
'''''''''''''''''''''''''''
artiyor:
If deger < 255 Then
deger = deger + 1
HPWM 1,deger,frekans
EndIf
DelayMS hiz
clrwdt
If arttir = 0 Then artiyor
For x = 1 To 50
DelayMS 1
clrwdt
If arttir = 0 Then artiyor
Next
EWrite 2 , [deger]
GoTo bekle
'''''''''''''''''''''''''''''''''''
azaliyor:
If deger > 0 Then
deger = deger - 1
HPWM 1,deger,frekans
EndIf
DelayMS hiz
clrwdt
If azalt = 0 Then azaliyor
For x = 1 To 50
DelayMS 1
clrwdt
If azalt = 0 Then azaliyor
Next
EWrite 2 , [deger]
GoTo bekle
Öncelikle çok teşekkür ederim... Bu yöntem cidden işe yarar mı?
Bir de; C'nin daha profesyonel olduğu ve hex'e çok daha az kayıpla çevrildiği için MCS öğrenmekten vazgeçip, C öğrenmeye çalışıyorum. Verdiğiniz Basic kodu için de ayrıca teşekkür ederim. Ama dediğiniz yöntemi C'de denemeye çalışacağım...
Eğer direkt olarak 1 MHz kristal takarak istediğim frekanslardaki PWM'leri alabiliyorsam, bu daha çok işime gelir... Umarım yanlış anlaşılmamışımdır...
Saygılarımla...
http://www.4shared.com/file/uZfA3yQh/16f628a_ccs.html
buyur arkadasim bi bak bakalim programa istedigin gibi olmusumu?
Derlemede hata verdi...
İlk satırı #include <16f628a.h> olarak değiştirdim derledi... Ancak ISIS'te çalışmadı bu sefer... ???
derlemene gerek yoktu hex kodu icinde vardi zaten..
isis versiyonun ne acaba??
ilk satira asagidaki kodu eklermisin??
#include <16F628A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES MCLR //Master Clear pin enabled
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES RESERVED //Used to set the reserved FUSE bits
#use delay(clock=1000000)
Proteus 7.4 SP3 Portable
bide yukarda mesajda yazdigim kodu ekleyip derlermisiniz...
#fuses RESERVED satırı hata veriyor... O satırı çıkardım derledi ancak program çalışmıyor...
benim gonderdigim dosyadaki hexi yuklermisin icine degistirilmemis olsun ama....
Gönderdiğiniz dosyadaki değiştirilmemiş olan hex'i yükledim, çalışmadı...
NOT: Devreyi aynen yukarıdaki şemada olduğu gibi çizdim... Tek fark kristali de ekledim ve 22pF kondansatörleri de çizdim... Özelliklerden hem PIC'in hem de kristalin frekansını 1MHz olarak ayarladım...
benim gonderdigim dosyadaki isis dosyasini acmadimi peki...
hic pwm uretmiyomu yoksa butonlarmi calismiyo??
Alıntı yapılan: justice_for_all - 22 Kasım 2010, 00:45:01
benim gonderdigim dosyadaki isis dosyasini acmadimi peki...
hic pwm uretmiyomu yoksa butonlarmi calismiyo??
Hayır açmadı... Hiç PWM üretmiyor...
http://www.4shared.com/file/T9xWE_FX/16f628a_ccs_2.html
yenisini yukledim bunuda denermisin arkadasim...
Alıntı yapılan: justice_for_all - 22 Kasım 2010, 00:53:52
http://www.4shared.com/file/T9xWE_FX/16f628a_ccs_2.html
yenisini yukledim bunuda denermisin arkadasim...
Ben denedim, çalışıyor...
Alıntı yapılan: RcALTIN - 22 Kasım 2010, 08:13:09
Ben denedim, çalışıyor...
siz hangi versiyonunu kullaniyosunuz proteus un??
Kusuruma bakmayın, biraz geç yanıtlamak zorunda kaldım...
Üstadım ellerinize, aklınıza sağlık... Gerçekten ama gerçekten çok teşekkür ediyorum... Şimdi bu devre şemasına harici olarak 1 MHz kristal bağlayacak mıyım yoksa Internal OSC falan mı devrede?
kristal ve kondansatorleri baglamalisin regulator devresi yapcaksin arkadasim ben onlar olmadan calistigi icin yapmadim ama devreyi yapcaksan baglamalisin...(kristal 1MHz olmali ve ona gore kapasitorler...)
Kolay Gelsin...
Besleme devresi, PCB vs. basit işler benim için, sorun değil... Peki 1 MHz.'lik kristalin osilasyon yapabilmesi için gerekli olan kondansatör değeri ne olmalıdır?
4 MHz için 22 pF uygun; peki 1 MHz için kaç pF?
Buldum... ;D
15 pF...
o zaman vakit kaybetmeden cizmeye baslayin devrenizi...
Iyi Calismalar...
Sonsuz teşekkürler...
33pf~47pf
http://www.nazimyildiz06.tr.gg/PIC-Giri%26%23351%3B_2.htm
Tabii ki en doğrusu üreticinin datasheet deki tavsiyesi. Titreşmez ise verdiğim değere doğru çıkabilirsiniz.
(http://img217.imageshack.us/img217/9162/capw.jpg)
16F628A'nın datasheet'indeki tabloda 1 MHz için değer belirtilmemişti... Sanırım farketmez...
2 MHz ve 4 MHz icin 15-33 pf arasi verilmis 1 Mhz icinde odegerler arasinda kullansan olur die dusunuyorum...
Hani bana en son gönderdiğin C dosyası var ya... İşte o programdaki kodların, benim anlayacağım dille ne işe yaradığını da yazabilir misin yanlarına...
Örneğin;
#int_EXT
void EXT_isr(void)
{
if(++i==6)
i=1;
if(i==1)
setup_timer_2(T2_DIV_BY_16,155,1); //100 Hz
Mesela burada
#int_EXT ya da void EXT_isr(void) ne demektir,
if(++i==6)
i=1; ne demektir vs. gibi...
Yani yazdığın o kodların yanlarına da açıklamalarını kısaca yazabilir misin? Senin için yorucu olmayacaksa yani... Çünkü bu dili öğrenmeyi çok istiyorum...
http://www.4shared.com/file/I_9PQODe/16f628a_ccs.html
buyur arkadasim bi bak bakalim...
Bu devre simülasyonda sapıtmaya başladı... Frekansı her zaman değiştirmiyor, frekans değiştirme butonu her zaman iş yapmıyor, Duty Arttır butonu frekansı değiştiriyor vs... Acaba atladığımız bir şey falan olmuş olabilir mi? İstediğim gibi sadece 1 kez çalıştı, ondan sonra tamamen saçmalamaya başladı :-\
ne Tur hata var bende iyi calisiyor...
bitek su var bendede bazi frekanslarda duty farklilasiyor sizdede oylemi...
Mesela;
PWM 100 Hz ile sorunsuz olarak başlıyor... Frekans değiştirme butonuna ilk tıkladığımda frekansın değişmesi gerekirken değiştirmiyor.
2. kez tıkladığımda frekansı bir üst frekansa ayarlıyor. 3. basışımda pulse tamamen gidiyor...
Devreyi yeniden başlatıyorum. Yine aynı olaylar devam ediyor... Bir de frekans değiştirme butonu Duty Arttır işlevini, Duty Arttır butonu da frekans değiştirme işlevini gerçekleştiriyor... Ondan sonra yine sapıtıyor...
Valla işin içinden nasıl çıkacağımı şaşırdım açıkçası :(
Bir de mesela Duty %50 ile başlamış olsa bile Duty Azalt dediğim zaman Duty oranı direkt olarak %10 gibi bir orana iniyor ve ordan devam ediyor...
Alıntı yapılan: oongit - 25 Kasım 2010, 00:02:41
Mesela;
PWM 100 Hz ile sorunsuz olarak başlıyor... Frekans değiştirme butonuna ilk tıkladığımda frekansın değişmesi gerekirken değiştirmiyor.
2. kez tıkladığımda frekansı bir üst frekansa ayarlıyor.
nedeni devre ilk basladiginda 100 hz basliyor ve butona basinca ilk istedigin frekans 100 hz oldugu icin ilk basicta bi degisiklik olmuyor...
Alıntı yapılan: oongit - 25 Kasım 2010, 00:02:41
Devreyi yeniden başlatıyorum. Yine aynı olaylar devam ediyor... Bir de frekans değiştirme butonu Duty Arttır işlevini, Duty Arttır butonu da frekans değiştirme işlevini gerçekleştiriyor... Ondan sonra yine sapıtıyor...
bende o hatalar meydana gelmiyor...cok iyi frekansi ve dutysini degistiriyor..Proteus versiyonun kac?
Alıntı yapılan: oongit - 25 Kasım 2010, 00:02:41
Bir de mesela Duty %50 ile başlamış olsa bile Duty Azalt dediğim zaman Duty oranı direkt olarak %10 gibi bir orana iniyor ve ordan devam ediyor...
o zaman programi soyle degistirin...
degisken tanimlamasini bu sekilde yapin...
int8 i=0,sayac=70;
7.4 SP3 Portable...
Bu sefer de 300 Hz.den 400 Hz.e geçerken sapıtıyor... 200 Hz deyken, duty değeri %100'ü aşınca frekans 100 hz.e iniyor.
simdi arkadasim her frekansin kendine ayri max dutysi var ok 100 hzin max dutysi 200 hze uymuyor o yuzden frekans degisiyomus gibi geliyo...
o max degerleri belirleyip ona gore kod yazmalisin sen degerleri belirle yeter kodlari ben yazarim ok ...
Tamam... Uğraşacağım... Bakalım altından kalkabilecek miyim? Şimdi uyku zamanı ;D
Devre şemasını aşağıdaki gibi değiştirdim...
http://img713.imageshack.us/img713/5525/adszkxv.jpg
Başlangıç prosedürleri;
if (input(pin_a0))
setup_timer_2(t2_div_by_16,155,1);
set_pwm1_duty(62);
setup_ccp1(ccp_pwm);
if (input(pin_a1))
setup_timer_2(t2_div_by_16,103,1);
set_pwm1_duty(41);
setup_ccp1(ccp_pwm);
if (input(pin_a2))
setup_timer_2(t2_div_by_16,77,1);
set_pwm1_duty(31);
setup_ccp1(ccp_pwm);
if (input(pin_a3))
setup_timer_2(t2_div_by_16,61,1);
set_pwm1_duty(25);
setup_ccp1(ccp_pwm);
if (input(pin_a4))
setup_timer_2(t2_div_by_16,51,1);
set_pwm1_duty(20);
setup_ccp1(ccp_pwm);
(Buraya kadar sırasıyla 100-150-200-250 ve 300 Hz (%10 Duty) üretecek)
Buradan itibaren de; Duty ayarlama prosedürleri olacak;
void (main)
ana prosedürler...
Arkadaşım, yazım dili önemli değilse verdiğimi kullanabilirsiniz. Çalışıyor.
Aslına bakarsanız; alıp kullanacağım için çok da önemli sayılmaz... Ancak; balık verilmesindense, balık tutmanın öğretilmesinden yanayım... Bilmem anlatabildim mi?
Madem ki bu işe gönül verdim... O halde bu işi düşe kalka öğrenmeliyim... Etim sizin, kemiğim babamın yani ;D
Alıntı yapılan: oongit - 26 Kasım 2010, 00:30:03
Devre şemasını aşağıdaki gibi değiştirdim...
http://img713.imageshack.us/img713/5525/adszkxv.jpg
Başlangıç prosedürleri;
if (input(pin_a0))
setup_timer_2(t2_div_by_16,155,1);
set_pwm1_duty(62);
setup_ccp1(ccp_pwm);
if (input(pin_a1))
setup_timer_2(t2_div_by_16,103,1);
set_pwm1_duty(41);
setup_ccp1(ccp_pwm);
if (input(pin_a2))
setup_timer_2(t2_div_by_16,77,1);
set_pwm1_duty(31);
setup_ccp1(ccp_pwm);
if (input(pin_a3))
setup_timer_2(t2_div_by_16,61,1);
set_pwm1_duty(25);
setup_ccp1(ccp_pwm);
if (input(pin_a4))
setup_timer_2(t2_div_by_16,51,1);
set_pwm1_duty(20);
setup_ccp1(ccp_pwm);
(Buraya kadar sırasıyla 100-150-200-250 ve 300 Hz (%10 Duty) üretecek)
Buradan itibaren de; Duty ayarlama prosedürleri olacak;
void (main)
ana prosedürler...
Buradaki gibi bir yol izlemek mantıklı mıdır?
arkadasım kesme ile yapacaksn a portunu kullanamazsın ama kesme kullanmadan yapcaksan olabilir ama if leri while dogusunun içine yazmalısın ayrıca iflere parantez koylmalısın if(sart) kume parantezi içinde komutlar gibi...ayrıca o butonlar frekans ayarlamak için mi...
Alıntı yapılan: oongit - 26 Kasım 2010, 00:30:03
Devre şemasını aşağıdaki gibi değiştirdim...
http://img713.imageshack.us/img713/5525/adszkxv.jpg
Yukarıdaki şemada olduğu gibi olabilir diye o şekilde düşündüm... PWM değiştirmek için A portunu, Duty oranını değiştirmek için de B6 ve B7 pinini kullanmayı düşünüyorum... Bu şekilde istediğim gibi çalışmaz mı yoksa?
yazılımında bikac hata var donanımına gore if(!input(pin)) gibi kullanman gerek...her ifde setup_ccp demen gerek yok main fonksionunda bikez demen yeterli ayrıca frekanslanların max dutysini bul demiştim bulabildinmi...
Alıntı yapılan: justice_for_all - 26 Kasım 2010, 20:34:17
ayrıca frekanslanların max dutysini bul demiştim bulabildinmi...
Aklımdan çıkmış, üzgünüm... Şöyle olacak:
Hangi frekans seçilirse seçilsin, Duty değeri %10 ile başlayıp, %90'da son bulacak... Yani; ne %10'un altına inecek, ne de %90'ın üzerine çıkacak... Sanırım bu iş için de, her frekans için ayrı ayrı Duty değiştirme programı yazmak zorunda kalabilirim belki... Tabii başka mantıklı bir yolu yoksa...
mantıklı bir yolu var senden istediğim tek sey frekansların %90 nında duty degeri kac olması gerek...
100 Hz PWM ve %90 Duty için:
setup_timer_2(T2_DIV_BY_16, 155, 1);
set_pwm1_duty(562);
150 Hz PWM ve %90 Duty için:
setup_timer_2(T2_DIV_BY_16, 103, 1);
set_pwm1_duty(375);
200 Hz PWM ve %90 Duty için:
setup_timer_2(T2_DIV_BY_16, 77, 1);
set_pwm1_duty(281);
250 Hz PWM ve %90 Duty için:
setup_timer_2(T2_DIV_BY_16, 61, 1);
set_pwm1_duty(225);
300 Hz PWM ve %90 Duty için:
setup_timer_2(T2_DIV_BY_16, 51, 1);
set_pwm1_duty(187);
ok ben yapar linkini gonderirim simdi cıkmam gerek...
Teşekkürler...
int8 i=0,sayac=0;
#int_rb //PORTB'de B4-B7 pinlerinde oluşan kesme vektörü
void rb_isr(void) //Kesme fonksiyonu
{
if(!input(pin_b6)) //B6 pinindeki butona basıldı mı?
{
if(sayac==150) //Sayaç değerini sınırlamak için
sayac=140;
sayac+=10;
Buradaki int8 i=0,sayac=0 bloğu ve
if(sayac==150) //Sayaç değerini sınırlamak için
sayac=140;
sayac+=10; bloğundaki "i" ve "sayac" ifadelerinin ne anlama geldiğini ve ne amaçla kullanıldığını bir türlü anlayamıyorum... Bunları benim anlayabileceğim bir şekilde yazabilir misiniz rica etsem :(
Alıntı yapılan: oongit - 26 Kasım 2010, 23:20:12
Buradaki int8 i=0,sayac=0 bloğu
yukarda sadece degisken tanimlamisim ve ilk deger atamasi yapmisim..
i degiskeni butona kackez basildigi degerini tutuyo...
sayac degiskeni ise duty nin max degerini asmasini engelliyo...
yeni programini yaptim birazdan kodu buraya yazcam burdan kopyalarsin ama maz duty degerleri yalnis max degeri asiyo...
Alıntı yapılan: oongit - 26 Kasım 2010, 23:20:12
if(sayac==150) //Sayaç değerini sınırlamak için
sayac=140;
sayac+=10;
yukaridaki kod ise duty degerini max 150 degerinde tutmak icin yapilmistir yani duty degeri 150 de iken arttirma butonuna basildi ise degeri yukselmesin 150de sabit kalsin die...
Sanırım biraz daha iyi anladım. Ama halâ tam olarak çözebilmiş değilim. O kodları kendim hesaplamadım. PWM Calculator diye bir program var ya ona hesaplattırdım... :(
#include <16F628A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES MCLR //Master Clear pin enabled
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES RESERVED //Used to set the reserved FUSE bits
#use delay(clock=1000000)
int16 i=0,sayac=70,maxduty;
#int_RB /////PORTB de b4-b7 pinlerinde olusan kesme vektoru
void RB_isr(void) //kesme fonksiyonu
{
if(!input(pin_b6)) ///b6 pinindeki butona basildi mi?
{
while(!input(pin_b6))
{
delay_ms(100);
if(sayac==maxduty) //sayac degerinin sinirlamak icin
sayac=maxduty-5;
sayac+=5; //duty degerini arttirmak icin...
set_pwm1_duty(sayac); //hesaplanan sayac degerini duty'e yansit..
}
}
if(!input(pin_b7)) ///b7 pinindeki butona basildi mi?
{
while(!input(pin_b7))
{
delay_ms(100);
if(sayac==5) //yine buda sayac degerini sinirlama
sayac=10;
sayac-=5; //duty degerini azalt
set_pwm1_duty(sayac); //hesaplanan sayac degerini duty'e yansit..
}
}
}
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); //bu satir timer0 icin kullanmadigin icin seni ilgilendirmiyo...
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); //bu satirda timer1 icin buda ilgilendirmiyo..
setup_timer_2(T2_DIV_BY_16,155,1); //bu satir pwmin frekansini ayarlamak icin pwm periyodu=(PR2(bu satirda degeri 155)+1)*4*TOSC*timer bolucu orani(bu satirda degeri 16)
//TOSC=1/FOSC (FOSC=1000000)
setup_ccp1(CCP_PWM); //CCP modulu PWM olarak kullaniliyo demek.
set_pwm1_duty(sayac); //baslangicta pwm duty si %50 dir demek..bunu sen istedigin miktarda yapabilirsin...
setup_comparator(NC_NC_NC_NC); //Analog karsilastirici yok
setup_vref(FALSE);
enable_interrupts(INT_RB); //b4-b7 pinlerindeki kesme aktif
enable_interrupts(INT_EXT); //b0 pinindeki kesme aktif
enable_interrupts(GLOBAL); //aktif olan butun kesmelere izin ver..
set_tris_b(0xF7); //11110111 pin_b3 cikis diger pinler giris olarak ayarlandi..
set_tris_a(0xFF);
while(1)
{
if(!input(pin_a0)) ///a0 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,155,1); //100 Hz butona bikez basilinca bu if e girer
maxduty=560;
set_pwm1_duty(62);
}
else if(!input(pin_a1)) ///a1 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,103,1); //150 Hz ikinci kez basilinca
maxduty=375;
set_pwm1_duty(41);
}
else if(!input(pin_a2)) ///a2 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,103,1); //150 Hz ikinci kez basilinca
maxduty=280;
set_pwm1_duty(31);
}
else if(!input(pin_a3)) ///a3 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,103,1); //150 Hz ikinci kez basilinca
maxduty=225;
set_pwm1_duty(25);
}
else if(!input(pin_a4)) ///a4 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,103,1); //150 Hz ikinci kez basilinca
maxduty=185;
set_pwm1_duty(20);
}
}
}
max degerleri 5in katlari seklinde yazinca duzeldi arkadasim simdi bu programi derleyip denermisin...
Hemen deniyorum... Allah razı olsun, emeğinize sağlık...
Programı kontrol ettim... 100 ve 150 Hz.'den sonra 200-250-300 diye devam etmesi gerekirken, 100-150-150-150-150 diye devam ediyordu. Sanırım küçük bir yanlışlık olmuş.
O kodların 100-150-200-250 ve 300 olacak şekilde değişmesi için o kodları düzelttim. Şu an 5 frekansı da sorunsuz olarak değiştirebiliyorum. Ancak Duty Arttır ve Duty Azalt butonları çalışmıyor...
Bir de her frekansın %10 Duty ile başlaması gerekiyordu ya... İşte o sadece simülasyon ilk başladığında 100 hz ve %10 olarak başlıyor...
http://img249.imageshack.us/i/65723804.jpg/
100 hz butonuna tıkladığımda duty yaklaşık 40 lara çıkıyor.
http://img337.imageshack.us/i/100hztkla.jpg/
150 de yaklaşık %40 civarlarında
http://img34.imageshack.us/i/150hztkla.jpg/
200 de yaklaşık %40 civarlarında
http://img189.imageshack.us/i/200hztkla.jpg/
250 de yaklaşık %40 civarlarında
http://img10.imageshack.us/i/250hztkla.jpg/
300 de yaklaşık %40 civarlarında
http://img517.imageshack.us/i/300hztkla.jpg/
Hiçbiri şu an için %10 olarak başlamıyor...
Bir de;
int16 i=0,sayac=70,maxduty;
burada i=0 için değişken atamışız ama i değişkenini hiç bir yerde kullanmamışız. Acaba bu satırla alakalı bir sorun olabilir mi?
Bir de şu anki güncel kod şu şekilde:
#include <16f628a.h>
#fuses xt,nowdt,noput,noprotect,nobrownout,mclr,nolvp,nocpd
#use delay(clock=1000000)
#define pwm100 pin_a0
#define pwm150 pin_a1
#define pwm200 pin_a2
#define pwm250 pin_a3
#define pwm300 pin_a4
#define duty_arttir pin_b6
#define duty_azalt pin_b7
int16 i=0,sayac=70,maxduty;
#int_RB //PORTB'de B4..B7 pinlerinde oluşan kesme
void RB_isr(void) //Kesme fonksiyonu
{
if(!input(duty_arttir)) //Duty Arttır butonuna basıldı mı?
{
while(!input(duty_arttir))
{
delay_ms(100);
if(sayac==maxduty) //Sayac değerini sınırlamak için
sayac=maxduty-5;
sayac+=5; //Duty değerini arttırmak için
set_pwm1_duty(sayac); //Hesaplanan sayaç değerini Duty'e yansıt
}
}
if(!input(duty_azalt)) //Duty Azalt butonuna basıldı mı?
{
while(!input(duty_azalt))
{
delay_ms(100);
if(sayac==5) //Yine bu da sayac değerini sınırlama
sayac=10;
sayac-=5; //Duty değerini azalt
set_pwm1_duty(sayac); //Hesaplanan sayaç değerini Duty'e yansıt
}
}
}
void main()
{
setup_timer_0(rtcc_internal|rtcc_div_1);
setup_timer_1(t1_internal|t1_div_by_1);
setup_timer_2(t2_div_by_16,155,1);
setup_ccp1(CCP_PWM);
set_pwm1_duty(sayac); //Başlangıçta Duty %50'dir demek
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RB);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
set_tris_b(0xF7);
set_tris_a(0xFF);
while(1)
{
if(!input(pwm100)) //A0 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,155,1); //100 Hz butona bikez basilinca bu if e girer
maxduty=560;
set_pwm1_duty(62);
}
else if(!input(pwm150)) //A1 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,103,1); //150 Hz ikinci kez basilinca
maxduty=375;
set_pwm1_duty(41);
}
else if(!input(pwm200)) ///a2 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,77,1); //200 Hz ikinci kez basilinca
maxduty=280;
set_pwm1_duty(31);
}
else if(!input(pwm250)) ///a3 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,61,1); //150 Hz ikinci kez basilinca
maxduty=225;
set_pwm1_duty(25);
}
else if(!input(pwm300)) ///a4 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,51,1); //300 Hz ikinci kez basilinca
maxduty=185;
set_pwm1_duty(20);
}
}
}
sayac=deger
set_pwm1_duty(sayac)
While dongusu içindeki if lerin içine yazın deger yerine baslangıc duty degerlerini yazın...
Alıntı yapılan: justice_for_all - 28 Kasım 2010, 13:43:00
sayac=deger
set_pwm1_duty(sayac)
While dongusu içindeki if lerin içine yazın deger yerine baslangıc duty degerlerini yazın...
Özür dilerim ama anlayamadım...
programınızda while(1) donguu içindeki iflerin parantez içlerini yazdığım kodu yazım...
Yine anlayamadım sanırım... Bu satırı çözemedim...
int16 i=0,sayac=70,maxduty;
Sanırım olay burada karışıyor ???
Alıntı yapılan: oongit - 26 Kasım 2010, 00:36:52
Aslına bakarsanız; alıp kullanacağım için çok da önemli sayılmaz... Ancak; balık verilmesindense, balık tutmanın öğretilmesinden yanayım..
Ortak amaç o zaten. Siz çok butonlu istiyorsunuz, al kullan demekle program üzerinde çalışarak, değişiklik yaparak, bir yandan öğrenerek demek istedim.
Alıntı yapılan: OG - 28 Kasım 2010, 15:28:11
Alıntı yapılan: oongit - 26 Kasım 2010, 00:36:52
Aslına bakarsanız; alıp kullanacağım için çok da önemli sayılmaz... Ancak; balık verilmesindense, balık tutmanın öğretilmesinden yanayım..
Ortak amaç o zaten. Siz çok butonlu istiyorsunuz, al kullan demekle program üzerinde çalışarak, değişiklik yaparak, bir yandan öğrenerek demek istedim.
Vakit ayırmış olmanız bile yeter... Hepinizin amacının, öğrenmek isteyen acemi birine bir şekilde bu işi öğretmeye çalışmak zaten... Hepinize teker teker teşekkür ediyorum tekrar...
Alıntı yapılan: oongit link=topic=30515.msg212428#msg212428
code]int16 i=0,sayac=70,maxduty;[/code]
while(1)
{
else if(!input(pwm150)) //A1 pinindeki butona basildi mi?
{
setup_timer_2(T2s_DIV_BY_16,103,1); //150 Hz ikinci kez basilinca
maxduty=375;
sayac=41;
set_pwm1_duty(sayac);
}
}
}[/code]
Yukarda yaptığımı butun iflere koy...
Derlemede hata veriyor...
Özür dilerim, benim hatammış... Şimdi derledi. Şu an %10'lar seviyesinde başlıyor her biri. Ancak Duty Arttır ve Duty Azalt tuşları ile işlem yapamıyorum.
Edit kullanınız (OG)
Tekrar özür dilerim, bu da benim hatammış. Başından beri Duty butonlarını 10k'lar ile yükseğe çekmemişim... Şu an harika çalışıyor.
Ancak Duty oranının minimum %10'da,
Maksimum Duty oranının ise %75'de kalabilmesi gerekiyor. Program şu anki haliyle bunu sağlayamıyor. %0'ın altına indiğinde ve %100'ün üstüne çıktığında frekansı da bozuyor...
Şimdi;
Seçilen her frekans min. %10 Duty oranı ile başlamalı ve max. %75 Duty oranı ile sınırlı kalabilmeli,
Ve Duty butonlarına her tıkladığımda, %5'er %5'er artırılıp, azaltılabilmeli...
Bunu sağlayabilmek için yapmamız gereken değişiklik nasıl olmalıdır? Her frekans için ayrı bir değişken falan mı tanımlamalıyız?
Örneğin; 100 Hz için "i" değişkeni, 150 Hz için "j" değişkeni, 200 Hz için "k" değişkeni vs. gibi...
Edit kullanınız (OG):
Özür dilerim haklısınız...
sorun ne anlamadim bende max degerini asmiyor...siz ilk basta %90 diyodunuz bende ona gore yaptin degerleride siz buldunuz hatta..
sizde neden max degeri astigini anladim...
mesela birinci if dongusunde sizin normal degeriniz 61 ben bunu 5'in katiyla degistirdim asagidaki gibi sizde o degerleri duzeltirsen sorun kalmicaktir..
arkadasim...
sayac=60;
set_pwm1_duty(sayac);
Sorun sizde değil, kesinlikle yanlış anlamayın beni... Sorun bende... Yaptığım araştırmayı, yazdıkalrıma aktarmayı unutmuşum sadece, kafam biraz karışık şu günlerde. %75'i aşmaya başladığım zaman, süreceğim Mosfeti yakma ihtimalim kuvvetleniyormuş. Bu yüzden 75'in aşılmaması daha mantıklı oluyormuş, unuttuğum için kusuruma bakmayın...
Bunu engelleyebilmek adına; her frekans değeri için min. ve max. duty oranlarını hesaplamaya çalışıyorum. Örneğin; 100 Hz. PWM, %10 başlangıç,%5 arttırma ve %5 azaltma için kodları aşağıdaki gibi değiştirmem gerekir mi yoksa saçmalamış mıyım?
//100 Hz PWM, %50 Duty başlangıcı için
int i=62 //%50 Duty
//%5 arttırmak için, Frekans*5/100=i yerine yazılacak değer
if(!input(duty_arttir))
{
delay_ms(5);
i+=5;
if(i>=75)
i=75;
}
//%5 azaltmak için, Frekans*5/100=i yerine yazılacak değer
if(!input(duty_azalt))
{
delay_ms(5);
i-=5;
if(i<=5)
i=5;
Tekrar özür dilerim...
simdi 75 demissiniz ama dutynin %75i 75 sayisina esit degil...yani o kisim hatali arkadasim...
dutynin yuzdesi pwm cozunurlugu ile alakali sizin frekansiniza gore cozunurlugunuz degisir 8bit 9bit 10bit gibi iste bu cozunurlugu hesaplamalisiniz..
mesela 10 bit cikti diyelim hesaplamasi soyle
duty degerinin %75i=1024*75/100 ordaki 1024 cozunurluk 10 bit oldugu icin kullanilmistir senin cozunurlugun kac bitse ona gore orasi degisecektir...
Peki çözünürlüğümün kaç bit olması gerektiğini nasıl bileceğim?
resolution = log(FOSC/FPWM) / log(2) bits hesaplamasi boyle arkadasim...
Eyvah! "log" sanırım logaritma olmalı... Şimdi Google'a bir bakayım, nasıl hesaplanıyormuş. Teşekkür ederim.
arkadasim bilgisayarin heap makinasinda hesaplaniyo logaritma...
Çok teşekkür ederim, bunu da sizden öğrenmiş oldum.
buldugunuz degerleri ise yazilimdaki dutymax degiskenine ayri ayri yazarsaniz istediginizi elde etmis olursunuz...
Iyi Calismalar...
Eğer yanlış hesaplamadıysam;
çözünürlük= [log(1000000/100)]/log(2)
=log(10000)/log(2)
=4/0,301
=13,29 çıkıyor...
Ama en fazla 10 bit çözünürlük alabiliyoruz sanırım... 13 bit 10 bitten büyük olduğu için, 10 bit olarak mı kabul edeceğiz çözünürlüğü?
aynen oyle :)arkadasim...
O halde;
Çözünürlük = log(Fosc/Fpwm) / log(2) formülünden yola çıkarak;
Fosc= Osilatör frekansımız (yani 1.000.000 Hz),
Fpwm=İstediğimiz pwm çıkış frekansımız, (yani 100 hz), olacak... Tamam bu kısmı çok iyi anladım...
Peki;
PWM period = [(PR2) + 1] x 4 x Tosc x TMR2 Prescaler Değeri formülünde ise;
PR2 ve TMR2 Prescaler Değeri nasıl ve neye göre hesaplanıyor?
zaten prescale degerleri belli (1,4,16) bu ilk once prescaler degeri 1 verilerek baslanir eger PR2 degeri 255 ten kucuk bi degerse bunu kullanabilirsin ama degilse o zaman prescaler degerine 4 verirsin yine hesaplayip yukaridaki sarta bakarsin oda olmadi bu kez prescaler degerine 16 verirsin bu sekilde hesaplanir arkadasim...
Sayenizde benim için oldukça değerli bilgiler edindim, sonsuz kere sonsuz teşekkürler ;D
Öğrenmenin yaşı yokmuş gerçekten de... Bu yaşta kafa basmaz dedim ama anlamaya başladım yavaş yavaş... Ama öğrenmek istediklerim henüz bitmedi :)
Biz bu satırda ne demek istedik?
int16 i=0,sayac=70,maxduty;
Burada "i" neden "0",
"sayac" neden 70,
maxduty, bizim istediğimiz max. duty anlamına mı geliyor?
sayac=70 de yoksa min. duty anlamına mı geliyor?
simdi hocam i degiskeni artik isimize yaramiyor o ilk programdaydi i=0 denilmesinin sebebi ilk deger atamasi eger biz o degeri vermezsek program random bi deger atar buda bizim isimize gelmez...
sayac degiskeni dutynin degerini tutuyo aslinda butonlarla sayac degiskenini azaltip cogaltiyoruz bu degiskenide dutyde gosteriyoruz..
max dutyde dediginiz gibi frekansin maz duty degeri programda gorduyseniz her frekansin icinde ayri max duty degeri yazdik sizin istediginiz gibi..
yasiniz kacti acaba??
Alıntı yapılan: justice_for_all - 29 Kasım 2010, 00:29:01
simdi hocam i degiskeni artik isimize yaramiyor o ilk programdaydi
Yani onu programımızdan çıkaracak mıyız artık?
Alıntı yapılan: justice_for_all - 29 Kasım 2010, 00:29:01
yasiniz kacti acaba??
4 ay sonra 33...
evet cikarabilirsiniz hocam..
benden buyukmussunuz abi demem gerekir..ne isle mesguldunuz abi..
Estağfurullah... Hitap şeklinizden rahatsızlık duymadım... Bursa'da Gazcılar'da Gündüz Elektronikte çalışıyorum. Elektrik, elektronik malzeme, komponent vs. satışı, ayrıca trafo sarımı falan da yapıyoruz... Normalde mobilya mezunuyum ve otomotivciyimdir, ama elektroniğe karşı yıllardır bir sempatim ve merağım var. Bugüne kadar tüm öğrendiklerimi araştıra araştıra, sora sora öğrenmiştim. Bugünden sonra da yine araştırmaya ve bunaltana kadar sormaya devam edeceğim. Çünkü elektroniği çok seviyorum...
PIC'lere de en başta MCS ve PBP ikilisiyle başlamıştım. Ama C dilinin çok daha az kayıpla hex'e dönüştürülebildiğini ve daha profesyonel bir dil olduğunu öğrendiğim andan itibaren, C dilini öğrenmeye çalışıyorum ben de...
Bu arada sizin yaşınız kaçtı?
Alıntı Yapbunaltana kadar sormaya devam edeceğim.
Bu güzel. Ancak, Hızlı gitmek istiyorsan bir kitap, bir kurs vs gerekir. Parça parça gitmek zordur.
Yarın sabah Altaş Yayıncılığın çıkardığı, Serdar ÇİÇEK imzalı CCS C ile PIC Programlama kitabını satın alacağım inşaallah...
C dili en kolay ogrenebilen ve yapi bakimindan saglam bir dildir (tabi buna C++ ve C# i dahil etmiyorum onlar daha profesyonel cunku) ben asm filan ogrenmeden direct olarak C ile basladim cokda memnunum..
basic filan bilmem oyuzden asm yide biraz bilirim onuda universiteden ders olarak gosteriliyodu ordan ogrendim ama kodlari anlarim..
C iyi bir dildir memnun kalacaksiniz yani:)
kitap alacaksaniz serdar cicek CCS C kitabi var gercekten cok guzel anlatmis tavsiye ederim cunku ben C dilini o kitaptan ogrendim...
Sanırım biraz fazla yoruldum bugün... Kafam iyice karıştı... Bazı şeyleri kavrayamaz hale geldim... Şu programa beraberce bir el atsak nasıl olur? Uykum da geldi, sabah erkenden işe gideceğim...
Benim tam olarak istediğim şey şu:
1- Program ilk başladığında 100 Hz PWM, %10 Duty ile başlayacak...
2- Frekans 100-150-200-250-300 Hz. butonlarından hangisine basarsam basayım %10 Duty ile başlayacak...
3- Duty kesinlikle %10 seviyesinin altına düşmeyecek...
4- Duty kesinlikle %75 seviyesinin üzerine çıkmayacak...
5- Duty değeri azalırken ve artarken daima %5 artıp azalacak...
Kafam çok karıştı, üzgünüm...
Kodun son hali böyle:
#include <16f628a.h>
#fuses xt,nowdt,noput,noprotect,nobrownout,mclr,nolvp,nocpd
#use delay(clock=1000000)
#use fast_io(a)
#use fast_io(b)
#define pwm100 pin_a0
#define pwm150 pin_a1
#define pwm200 pin_a2
#define pwm250 pin_a3
#define pwm300 pin_a4
#define duty_arttir pin_b6
#define duty_azalt pin_b7
int16 sayac=60,maxduty;
#int_RB //PORTB'de B4..B7 pinlerinde oluşan kesme
void RB_isr(void) //Kesme fonksiyonu
{
if(!input(duty_arttir)) //Duty Arttır butonuna basıldı mı?
{
while(!input(duty_arttir))
{
delay_ms(20);
if(sayac==maxduty) //Sayac değerini sınırlamak için
sayac=maxduty-5;
sayac+=5; //Duty değerini arttırmak için
set_pwm1_duty(sayac); //Hesaplanan sayaç değerini Duty'e yansıt
}
}
if(!input(duty_azalt)) //Duty Azalt butonuna basıldı mı?
{
while(!input(duty_azalt))
{
delay_ms(20);
if(sayac==5) //Yine bu da sayac değerini sınırlama
sayac=10;
sayac-=5; //Duty değerini azalt
set_pwm1_duty(sayac); //Hesaplanan sayaç değerini Duty'e yansıt
}
}
}
void main()
{
setup_timer_0(rtcc_internal|rtcc_div_1);
setup_timer_1(t1_internal|t1_div_by_1);
setup_timer_2(t2_div_by_16,155,1);
setup_ccp1(CCP_PWM);
set_pwm1_duty(sayac); //Başlangıçta Duty %50'dir demek
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RB);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
set_tris_b(0xF7);
set_tris_a(0xFF);
while(1)
{
if(!input(pwm100)) //A0 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,155,1); //100 Hz butona bikez basilinca bu if e girer
maxduty=300;
sayac=62;
set_pwm1_duty(sayac);
}
else if(!input(pwm150)) //A1 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,103,1); //150 Hz ikinci kez basilinca
maxduty=375;
sayac=41;
set_pwm1_duty(sayac);
}
else if(!input(pwm200)) ///a2 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,77,1); //200 Hz ikinci kez basilinca
maxduty=375;
sayac=31;
set_pwm1_duty(sayac);
}
else if(!input(pwm250)) ///a3 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,61,1); //150 Hz ikinci kez basilinca
maxduty=375;
sayac=25;
set_pwm1_duty(sayac);
}
else if(!input(pwm300)) ///a4 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,51,1); //300 Hz ikinci kez basilinca
maxduty=375;
sayac=20;
set_pwm1_duty(sayac);
}
}
}
size verdigim formulden dutylerin %10 ve %75 hangi desimal degerlere esit oldugunu bulmanizi istemistim buldunuzmu?
100 Hz:
setup_timer_2(T2_DIV_BY_16, 155, 1);
set_pwm1_duty(62); //%10
set_pwm1_duty(468); //%75
150 Hz:
setup_timer_2(T2_DIV_BY_16, 103, 1);
set_pwm1_duty(41); //%10
set_pwm1_duty(312); //%75
200 Hz:
setup_timer_2(T2_DIV_BY_16, 77, 1);
set_pwm1_duty(31); //%10
set_pwm1_duty(234); //%75
250 Hz:
setup_timer_2(T2_DIV_BY_16, 61, 1);
set_pwm1_duty(25); //%10
set_pwm1_duty(187); //%75
300 Hz:
setup_timer_2(T2_DIV_BY_16, 51, 1);
set_pwm1_duty(20); //%10
set_pwm1_duty(156); //%75
#include <16F628A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES MCLR //Master Clear pin enabled
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES RESERVED //Used to set the reserved FUSE bits
#use delay(clock=1000000)
int16 i=0,sayac=600,maxduty,minduty;
#int_RB /////PORTB de b4-b7 pinlerinde olusan kesme vektoru
void RB_isr(void) //kesme fonksiyonu
{
if(!input(pin_b6)) ///b6 pinindeki butona basildi mi?
{
while(!input(pin_b6))
{
delay_ms(50);
if(sayac==maxduty) //sayac degerinin sinirlamak icin
sayac=maxduty-5;
sayac+=5; //duty degerini arttirmak icin...
set_pwm1_duty(sayac); //hesaplanan sayac degerini duty'e yansit..
}
}
if(!input(pin_b7)) ///b7 pinindeki butona basildi mi?
{
while(!input(pin_b7))
{
delay_ms(50);
if(sayac==minduty) //yine buda sayac degerini sinirlama
sayac=minduty+5;
sayac-=5; //duty degerini azalt
set_pwm1_duty(sayac); //hesaplanan sayac degerini duty'e yansit..
}
}
}
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); //bu satir timer0 icin kullanmadigin icin seni ilgilendirmiyo...
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); //bu satirda timer1 icin buda ilgilendirmiyo..
setup_timer_2(T2_DIV_BY_16,155,1); //bu satir pwmin frekansini ayarlamak icin pwm periyodu=(PR2(bu satirda degeri 155)+1)*4*TOSC*timer bolucu orani(bu satirda degeri 16)
//TOSC=1/FOSC (FOSC=1000000)
setup_ccp1(CCP_PWM); //CCP modulu PWM olarak kullaniliyo demek.
set_pwm1_duty(0); //baslangicta pwm duty si %50 dir demek..bunu sen istedigin miktarda yapabilirsin...
setup_comparator(NC_NC_NC_NC); //Analog karsilastirici yok
setup_vref(FALSE);
enable_interrupts(INT_RB); //b4-b7 pinlerindeki kesme aktif
enable_interrupts(GLOBAL); //aktif olan butun kesmelere izin ver..
set_tris_b(0xF7); //11110111 pin_b3 cikis diger pinler giris olarak ayarlandi..
set_tris_a(0xFF);
while(1)
{
if(!input(pin_a0)) ///a0 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,155,1); //100 Hz butona bikez basilinca bu if e girer
maxduty=470;
minduty=60;
sayac=60;
set_pwm1_duty(sayac);
}
else if(!input(pin_a1)) ///a1 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,103,1); //150 Hz ikinci kez basilinca
maxduty=290;
sayac=40;
minduty=40;
set_pwm1_duty(sayac);
}
else if(!input(pin_a2)) ///a2 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,77,1); //200 Hz ikinci kez basilinca
maxduty=235;
sayac=30;
set_pwm1_duty(sayac);
}
else if(!input(pin_a3)) ///a3 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,61,1);//250 Hz ikinci kez basilinca
maxduty=190;
minduty=25;
sayac=25;
set_pwm1_duty(sayac);
}
else if(!input(pin_a4)) ///a4 pinindeki butona basildi mi?
{
setup_timer_2(T2_DIV_BY_16,51,1); //300 Hz ikinci kez basilinca
maxduty=145;
minduty=20;
sayac=20;
set_pwm1_duty(sayac);
}
}
}
soyle bir denermisiniz hocam...
Mükemmel olmuş, elinize sağlık, çok teşekkür ederim... Peki bu butonlar için buton gecikmesi de ekleyebilir miyiz? Yani duty butonlarına basılı tuttuğumda kendi kendine ilerlemesin... Bir de kontak sıçraması denilen olayı engellemek için çok küçük bir gecikme koyabilir miyiz?
o zaman programi soyle degistirmeniz gerekiyor...
#include <16F628A.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES MCLR //Master Clear pin enabled
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES RESERVED //Used to set the reserved FUSE bits
#use delay(clock=1000000)
int16 i=0,sayac=600,maxduty,minduty;
#int_RB /////PORTB de b4-b7 pinlerinde olusan kesme vektoru
void RB_isr(void) //kesme fonksiyonu
{
if(!input(pin_b6)) ///b6 pinindeki butona basildi mi?
{
while(!input(pin_b6))
delay_ms(50);
if(sayac==maxduty) //sayac degerinin sinirlamak icin
sayac=maxduty-5;
sayac+=5; //duty degerini arttirmak icin...
set_pwm1_duty(sayac); //hesaplanan sayac degerini duty'e yansit..
}
if(!input(pin_b7)) ///b7 pinindeki butona basildi mi?
{
while(!input(pin_b7))
delay_ms(50);
if(sayac==minduty) //yine buda sayac degerini sinirlama
sayac=minduty+5;
sayac-=5; //duty degerini azalt
set_pwm1_duty(sayac); //hesaplanan sayac degerini duty'e yansit..
}
}
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1); //bu satir timer0 icin kullanmadigin icin seni ilgilendirmiyo...
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); //bu satirda timer1 icin buda ilgilendirmiyo..
setup_timer_2(T2_DIV_BY_16,155,1); //bu satir pwmin frekansini ayarlamak icin pwm periyodu=(PR2(bu satirda degeri 155)+1)*4*TOSC*timer bolucu orani(bu satirda degeri 16)
//TOSC=1/FOSC (FOSC=1000000)
setup_ccp1(CCP_PWM); //CCP modulu PWM olarak kullaniliyo demek.
set_pwm1_duty(0); //baslangicta pwm duty si %50 dir demek..bunu sen istedigin miktarda yapabilirsin...
setup_comparator(NC_NC_NC_NC); //Analog karsilastirici yok
setup_vref(FALSE);
enable_interrupts(INT_RB); //b4-b7 pinlerindeki kesme aktif
enable_interrupts(GLOBAL); //aktif olan butun kesmelere izin ver..
set_tris_b(0xF7); //11110111 pin_b3 cikis diger pinler giris olarak ayarlandi..
set_tris_a(0xFF);
while(1)
{
if(!input(pin_a0)) ///a0 pinindeki butona basildi mi?
{
while(!input(pin_a0))
delay_ms(50);
setup_timer_2(T2_DIV_BY_16,155,1); //100 Hz butona bikez basilinca bu if e girer
maxduty=470;
minduty=60;
sayac=60;
set_pwm1_duty(sayac);
}
else if(!input(pin_a1)) ///a1 pinindeki butona basildi mi?
{
while(!input(pin_a1))
delay_ms(50);
setup_timer_2(T2_DIV_BY_16,103,1); //150 Hz ikinci kez basilinca
maxduty=290;
sayac=40;
minduty=40;
set_pwm1_duty(sayac);
}
else if(!input(pin_a2)) ///a2 pinindeki butona basildi mi?
{
while(!input(pin_a2))
delay_ms(50);
setup_timer_2(T2_DIV_BY_16,77,1); //200 Hz ikinci kez basilinca
maxduty=235;
sayac=30;
set_pwm1_duty(sayac);
}
else if(!input(pin_a3)) ///a3 pinindeki butona basildi mi?
{
while(!input(pin_a3))
delay_ms(50);
setup_timer_2(T2_DIV_BY_16,61,1);//250 Hz ikinci kez basilinca
maxduty=190;
minduty=25;
sayac=25;
set_pwm1_duty(sayac);
}
else if(!input(pin_a4)) ///a4 pinindeki butona basildi mi?
{
while(!input(pin_a4))
delay_ms(50);
setup_timer_2(T2_DIV_BY_16,51,1); //300 Hz ikinci kez basilinca
maxduty=145;
minduty=20;
sayac=20;
set_pwm1_duty(sayac);
}
}
}
Çok teşekkür ederim, ellerinize sağlık... Yarın akşam görüşmek üzere, hoşçakalın...
Kusuruma bakma... Bir kaç gündür olduka yoğundum. O yüzden nete pek girebilme fırsatım olmadı. Son yaptığımız revizyonu derledim ve PIC'e yükledim. Buton gecikmeleri çalışıyor, ancak %5'lik arttırma ve azaltma yapamıyorum. Çok daha düşük seviyelerde arttırma ve azaltma yapıyor. Belki %1'ler seviyesinde. Bunu nasıl düzeltebilirim? Bir de program ilk çalışmaya başladığında %10 ile başlaması gerekirken %0 ile başlıyor. Acaba şu en alttaki satırdan kaynaklanıyor olabilir mi?
void main()
{
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
setup_timer_2(T2_DIV_BY_16,155,1);
setup_ccp1(CCP_PWM);
set_pwm1_duty(0);
Bir de şu ilk satırdaki "INTERNAL ile T1" arasında kalan düz çizgi karakterini nasıl yazıyoruz. Klavyedeki tuş kombinasyonu nedir?
(T1_INTERNAL|T1_DIV_BY_1)
Alıntı yapılan: oongit - 02 Aralık 2010, 00:27:09
Bir de şu ilk satırdaki "INTERNAL ile T1" arasında kalan düz çizgi karakterini nasıl yazıyoruz. Klavyedeki tuş kombinasyonu nedir?
(T1_INTERNAL|T1_DIV_BY_1)
Alt Gr+ (sol taraftaki shift tuşunun yanındaki tuş :) )
>
< |
gibi.
klavyenize gore degisir egerki ingilizce klavye kullaniyosaniz shift+ soru isareti olan(sifirin hemen sag tarafindaki tus)..
eger turkce klavye kullanıyosanız shift + backspace tusunun sol tarafındakı tus...
Alıntı yapılan: oongit - 02 Aralık 2010, 00:27:09
Bir de program ilk çalışmaya başladığında %10 ile başlaması gerekirken %0 ile başlıyor. Acaba şu en alttaki satırdan kaynaklanıyor olabilir mi?
set_pwm1_duty(0);
[/code]
evet bu satir yuzunden ben ilk basladiginda bi hata olmasin die sifirdan baslatmak istedim ama siz 0 yerine istediginiz sayiyi yazabilirsiniz..
Alıntı yapılan: JKramer - 02 Aralık 2010, 10:37:00
Alıntı yapılan: oongit - 02 Aralık 2010, 00:27:09
Bir de şu ilk satırdaki "INTERNAL ile T1" arasında kalan düz çizgi karakterini nasıl yazıyoruz. Klavyedeki tuş kombinasyonu nedir?
(T1_INTERNAL|T1_DIV_BY_1)
Alt Gr+ (sol taraftaki shift tuşunun yanındaki tuş :) )
>
< |
gibi.
Teşekkür ederim, öğrendiğim iyi oldu :)
Peki %5'lik değişimler için nasıl bir değişiklik yapmalıyım? Program şu anki haliyle %1'ler mertebesinde değiştiriyor Duty seviyesini...
http://www.4shared.com/file/8Rcx-Vp5/16f628a_ccs.html
programi biraz daha degistirdim bi bakarmisin...
Programa eklediğin artış değişkeni satırlarında yazan değerleri değiştirdiğim zaman sanırım istediğim gibi olacak. Çünkü 100 Hz'lik frekansa baktığımda, değişimlerin yaklaşık %2.8'er gibi oranlarla değiştiğini görüyorum.
Bir de şu;
#fuses reserved
satırı olduğu zaman kesinlikle derlemiyor. Ancak o satırı sildiğimde derleyebiliyorum. Bu satır ne demek istiyor?
iste odegerleri hesaplayip artis degiskenine atamalisiniz baska hic bi islem yapmaniza gerek kalmiyor...
o kodun ne oldugunu bilmiyorum bende hiz bi hata vermiyor...
ama sunu soyleyim ben degerleri dogru hesaplamistim calismasi gerek cunku proteusda deniyorum 20 kez arttirma butonuna basinca max degere,20 kex azaltma butonuna basinca min degere ulasiyorum...
yani %5lik artis * 20 =% 100 yapar...
Alıntı yapılan: justice_for_all - 02 Aralık 2010, 22:09:57
ama sunu soyleyim ben degerleri dogru hesaplamistim calismasi gerek cunku proteusda deniyorum 20 kez arttirma butonuna basinca max degere,20 kex azaltma butonuna basinca min degere ulasiyorum...
yani %5lik artis * 20 =% 100 yapar...
Ama maxduty değişkeni ile %75 ile sınırlamıştık...
%100 dedigim orda hasapladigin max deger varya ondan bahsediyorum yani %100 olan aslinda senin asil pwm frekansinin %75 i oluyor...
simdi nasil calisiyomu devre..
hesabida soyle (maxduty-minduty)* 5 / 100
Haklısın yaa... Bak ben işin orasını hiç düşünmemiştim... Söylediğinde haklısın. Evet çalışıyor. Sayende...
Teşekkürler...
Aynı devre şemasına 1 adet 16F628 daha eklemek istiyorum. Ekleyeceğim 16F628'in görevi de, mevcut PIC'in CCP1 pininden çıkan frekansı ve o anki Duty oranını hesaplayamak...
Bunun için ekleyeceğim 16F628'in A0....A3 pinlerinden birini mi, yoksa CCP1 pinini (Capture ya da Compare) mi kullanmalıyım?
CCP1 den capture modunu kullanmalisin...
ornegin her yukselen kenardan onu takip eden dier yukselen kenara kadar olan sure senin periyodun,
heryukselen kenardan,takip eden dusen kenara kadar gecen sure ise senin duty olacak..
Anladım... Peki bu hesaplama işlemi sonucunda, hesaplanan frekansı ve Duty oranını, herhangi bir pinden 8 ya da 10 bit çözünürlükte çıkış olarak alabilir miyim?
Mesela;
Çıkış 100 Hz ve Duty %10 ise 10101001,
Çıkış 250 Hz ve duty %65 ise 00110110 vs. gibi... Anlatabildim mi?
ne yapmak istediginizi anlatirsaniz daha fazla yardimci olabilirim...
Şimdi verici devremizi tamamladık biliyorsunuz... İstediğimiz frekansta ve istediğimiz Duty oranında çıkış alabiliyoruz... Bu programla işimiz bitti.
Şimdi aynı devreye 1 adet daha 16F628 ekleyeceğim. Ekleyeceğimiz bu PIC, ilk programımızdaki PIC'in çıkışındaki frekansı ve Duty oranını hesaplayıp, herhangi bir pin üzerinden 8 ya da 10 bit olarak çıkış verecek...
Mesela;
Çıkış 100 Hz ve Duty %10 ise 10101001,
Çıkış 250 Hz ve duty %65 ise 00110110 vs. gibi...
peki o dijital cikisi ne yapmayi dusunuyosunuz...
Ana işlemcim vasıtası ile GLCD ekranında hem frekansı hem de Duty oranını görebilmek için... Yani;
İlk 16F628 kare dalgayı üretiyor,
İkinci 16F628 bu kare dalganın frekansını ve Duty oranını ölçüp, ana işlemci olan 16F877'ye 8 bit ya da 10 bit olarak göndermek.
16F877 ise bundan gelen dijital bilgiye göre GLCD üzerinde o anki frekansı ve Duty oranını gösterecek...
Biraz dolaylı oldu ama; ana işlemcim olan 16F877 bu işlerle uğraşıp zaman kaybetsin istemiyorum. Çünkü; onun yapacağı iş çok önemli olacak...
o zaman usart modulunden gonderebilirsiniz...
ana islemcinizin tx ve rx pinlerine baglanti yapin seri portla gonderin ...
Kitaptan şu Usart modülünü bir araştırayım bakalım, neler çıkacak?
merak etmeyin usart moduluyle kolayca gonderirsiniz ama 8 bit seklinde gonderebilirsiniz...