merhaba ustalarım
CCS derleyicisinde TIMER0 ve RB4-7 değişiklik kesmesini kullandım.
TIMER0 da
Alıntı Yapsetup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_bit);
enable_interrupts(INT_TIMER0)
enable_interrupts(INT_RB);
enable_interrupts(GLOBAL);
ayarları ile birlikte 4MHz lik kristal kullandım.Taşma sayısına da 61 dedim
RB4-7 değişiklik kesmesinde ise menü yaptım .
Devreyi çalıştırdığımda TIMER0 belirlediğim sürede işlem yapmadı. TIMER0 'ın 1 saniyesi yaklaşık 4 saniyeye denk geldi.
sebebi ne olabilir.
şimdiden teşekkürler
Rb kesmesi ve timer0 kesmesi aynı zamanda mı çalışıyor?
TMR0 yaklaşık 61ms yede kesmeye girer. tasma sayısına 16 demeniz gerekiyor.
@sadogan biraz açar mısın anlattığını?
61 ms de kesmeye girince ne oluyor?
@sadogan hocam,
TMR0 hesabını ben şu şekilde yapmıştım
Alıntı Yap
Fkomut=(4MHz/4) =1MHz
Kesme Oluşma Süresi= Tkomut * Bölme Oranı *(256-TMR0 'a yazılan deger)
=0,016384 saniye
1 Kesme 0,016384 saniye
? Kesme 1 saniye (doğru orantı)
_____________________________________________________
? Kesme =61,0351 ~ 61 kesme
61 'i bu şekilde belirlemiştim
16 nasıl olacak anlamadım hocam
RB4-7 değişiklik kesmesi aynı anda çalışmıyor
@Teğmen hocam RB4-7 değişiklik kesmesi olduğunda sadece RB7 pini için yazdığım menü işlemleri yapılıyor .Menüden çıktıktan sora TMR0 kaldığı yerden devam ediyor.Bunun için
Alıntı Yap
#priority RB, TIMER0
komutunu kullandım hocam.
Hesap doğru, bende yanlışlık olmuş.
Timer0 rutini paylaşırsan ona bakalım.
Kullandugın mcu nedir ve test ortamın gerçek mcu ilemi yoksa similasyonmu ?
Alıntı Yap
#int_TIMER0
void timer0_kesmesi() {
if(++sayac == 61) // timer0 61 kez taştıysa
{ // 61 x 16.3 ms = 1 sn süre geçmiştir
sayac = 0;
led1--;
saniye =led1 %60;
dakika =led1 /60;
lcd_gotoxy(1,1);
if(x ==1)
printf(lcd_putc," 1.cihaz %02d:%02d ",dakika,saniye);
if(led1==0)
{
led1=0;
output_low(pin_c0);
lcd_gotoxy(1,1);
printf(lcd_putc," ");
delay_ms(10);
z=0,x=0;
}
led2--;
saniye_2 =led2 %60;
dakika_2 =led2 /60;
lcd_gotoxy(2,2);
if (y == 2)
printf(lcd_putc,"2.cihaz %02d:%02d ",dakika_2,saniye_2);
if(led2 == 0) // 60 saniye
{
led2=0;
output_low(pin_c1);
lcd_gotoxy(1,2);
printf(lcd_putc," ");
delay_ms(10);
zz=0, y=0;
}
}
}
16F887 kullanıyorum
@sadogan hocam
Acaba RB4 kesmesindeki menüden kaynaklanıyor olabilir mi TMR0 daki kayma? RB4-7 kesmesinde baya bi delay_ms kullanmıştım.
printf ,lcd_putc gibi fonksiyonları interrupt içinde kulandığınızda derleyici interrupt ları kapatıyor.
interrupt içinde böyle uzun uzun program parçaları kullanmak hele delay_ms gibi fonkiyonlar kulanmak doğru deyil,stack sorunlarına yol açar.
interrupt runtine girdiginizde bir flag setleyip çıkın. Ana programda bu flag'a bakarak işlemlerinizi yapın.
RB4 -7 interrupt rutinde delay_ms printf gibi her yerde kulanılan foksiyonlar varsa, dediğim gibi bu foksiyonlar icra edilirlen ccs interrupt ları kapatıyor.
@sadogan konuyu bende takip ediyprum.Flag set etme olayını anlatır mısın
@sadogan hocam örnek kod verebilir misiniz? Anlayamadım tam demek istediğinizi
RB4-7 de menü yaparken menüye girmek,onaylamak onay yapmak için belirlenen saniye boyunca tuşa basılı olması gerekiyor. bunun için başka nasıl bir yol bulabilirim?
delay_ms kullanmak yerine for döngüsüyle mi saydırmam gerekir acaba ?
int1 HesapYap_LcdYeYaz = 0;
#int_TIMER0
void timer0_kesmesi() {
if(++sayac == 61) // timer0 61 kez taştıysa
{ // 61 x 16.3 ms = 1 sn süre geçmiştir
sayac = 0;
HesapYap_LcdYeYaz = 1;
}
}
void main ()
{
while(true)
{
if(HesapYap_LcdYeYaz)
{
HesapYap_LcdYeYaz = 0;
// Timr0 ın belerledigi süre sonunda yapılacak işler.
}
}
}
Alıntı yapılan: sadogan - 24 Ekim 2017, 14:43:39
int1 HesapYap_LcdYeYaz = 0;
#int_TIMER0
void timer0_kesmesi() {
if(++sayac == 61) // timer0 61 kez taştıysa
{ // 61 x 16.3 ms = 1 sn süre geçmiştir
sayac = 0;
HesapYap_LcdYeYaz = 1;
}
}
void main ()
{
while(true)
{
if(HesapYap_LcdYeYaz)
{
HesapYap_LcdYeYaz = 0;
// Timr0 ın belerledigi süre sonunda yapılacak işler.
}
}
}
if(++sayac == 61) kısmını if(++sayac >=61) olarak yapmak daha iyi olmaz mı hocam?
Alıntı yapılan: volkanunal - 24 Ekim 2017, 15:37:07
if(++sayac == 61) kısmını if(++sayac >=61) olarak yapmak daha iyi olmaz mı hocam?
Evet,tedbirli olmak iyi dir.
Ama ben if(++sayac >60) genellikle böyle kulanıyorum.
@volkanunal ,
@sadogan Çok teşekkür ederim anladım hocam. delay_ms için nasıl bir yol izlemek gerekir?
Programlarda genel olarak delay_ms kullanmak yerine saydırma işlemi yaparak (basic de dec ,inc gibi işlemlerle )kullanın diyorlar.Onu nasıl yaparız hem norma main içinde hem de interrupt da
Örnek kod verebilir misiniz?
Timer içinde belirli değişkenleri
set edin. Ana döngüde bu değişkenleri
kontrol edin. Hangisi hangi iş için ise
onu kullanıp resetleyin.
Yada bir sayaç olsun timer içinde.
Bu sayacın belli değerlerinde belli
işler yapılsın. Sayacın resetlenmesi de
ya interrupt içinde ya da uygun başka
bir yerde yapılır.