Herkese selamlar,
CCS C ile 16f877a denetleyicisine bluetooth üzerinden sinyal gönderip işleyen bir devrem vardı. Bir ara verdikten sonra tekrar denediğimde önceden sorunsuz çalışan devrede enteresan bir durumla karşılaştım ve artık içinden çıkamıyorum.
Özetle sorunum şu; pic sürekli olarak RX bacağından sinyal geliyormuş gibi davranıyor. normalde pic'in RX bacağına dışardan bir sinyal geldiğinde işleyip bir motoru döndüren bir programdı. programı iyice basitleştirdim artık rx bacağına sinyal gelince sadece led yakıp söndürmesini bekliyorum ama olmuyor. Daha devreye gücü verir vermez led hemen yanıp sönmeye başlıyor, hatta RX ucuna kablo bile bağlı değilken. RX ucundaki (26.pin) kabloyu sökmeme rağmen sanki kesme sinyali geliyormuşçasına davranıyor.
Besleme voltajını kontrol ettim, 7805 ile besleme yapıyorum bütün giriş voltajları 4.5V iken durum aynı, led rx kesme sinyali olmadan yanıp sönüyor. 7805 kullanmasam besleme 5.5V gibi sonuç yine aynı.
pic'te 1.pine 10K direnç ile giriş voltajı uyguladım, sonuç değişmedi
RX ucunda (26.pin) kablo yokken voltaj ölçüyorum, 0V değer görüyorum. (bazen 0.1V oluyor)
breadboardda kısa devre mi var dedim, farklı boardda denedim durum aynı
pic'te sorun vardır diye düşündüm, onu da değiştirdim, hiç kullanılmamış pic'le denedim sonuç yine aynı
programın konfigürasyonlarında bazı değişiklikler yaptım sonuç yine değişmedi.
aynı bread board, aynı işlemci farklı devrede çalışıyor. RS232 kesmesine gelince sürekli kesme geliyormuş gibi davranıyor ve led'i yakıp söndürüyor. koddaki "RS232" satırını commentleyince, RS232 dinlemeye geçmiyor, dolayısıyla o kısım (normal olarak) hiç çalışmıyor.
kbhit() veya rda kesmesi fark etmiyor aynı davranışı sergiliyor. hatta artık denemelerimde RX ucuna kablo bağlamıyorum bile, fakat sonuç aynı, sinyal geliyormuş gibi davranıyor.
Birçok denemeden sonra artık işin içinden çıkamıyorum.
artık rx kesmesinden gelen sinyalin içeriğinden işlenmesinden vazgeçtim, sadece sinyal geldiğinde kesmeye tepki versin, diğer zamanlarda ilgili kısma girmesin istiyorum.
kodda hem kbhit() hem de #int_rda ile çalışan satırlar var, commentleyerek sadece birisini kullanıyorum, aynı anda her ikisi de açık olmuyor.
devrede 11, 32 ve 1. pinlere (+); 12 ve 31. pinlere (-), 2 ve 3. pinlere de 0.5K direnç ile led bağlı.
pic'in bacaklarındaki gerilim değerleri besleme ile aynı.
kodu aşağıda paylaşıyorum, burada neyi yanlış yapıyor olabilirim?
#include <16F877A.h>
#device adc=8
#fuses XT, NOWDT, NOPROTECT, NOBROWNOUT, NOLVP, NOPUT, NOWRT, NODEBUG, NOCPD
#include <math.h>
#include <stdlib.h>
#include <string.h>
#use delay (clock=4000000)
#use rs232 (baud=9600, xmit=pin_C6, rcv=pin_C7, parity=N, bits=8, stop=1, stream=signal)
char rs_blg[40];
/*
#int_rda
void serial_read ()
{
disable_interrupts(int_rda);
output_high(PIN_A1);
delay_ms(3000);
output_low(PIN_A1);
delay_ms(1000);
return;
}
*/
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
// Program kodları başlıyor
set_tris_a(0x00); // A portu çıkış yapılıyor
set_tris_b(0x00); // B portu çıkış yapılıyor
set_tris_c(0xFF); // C portu giriş yapılıyor
output_a(0x00); // A portunun çıkışları sıfırlanıyor
output_b(0x00); // B portunun çıkışları sıfırlanıyor
output_high(PIN_A0); // Cihazın çalıştığını gösteren led yakılıyor
basla:
//clear_interrupt(INT_RDA);
//enable_interrupts(INT_RDA);
//enable_interrupts(GLOBAL);
if (kbhit(signal))
{
//gets(rs_blg); // rs232 verisi okunuyor
output_high(PIN_A1);
delay_ms(3000);
output_low(PIN_A1);
delay_ms(1000);
}
goto basla;
}
RX bacağının normalde logic 1 seviyesinde olması gerekir. Orada 0 görülmesi start bit olarak algılanıp kesmeye sebep olabilir. RX bacağına 10k ile pullup yapmakta fayda var.
Bazı durumlarda, bir bacağa gelen sinyal, açıkta bırakılmış komşu bacağı da etkiliyebiliyor. Geçmişte bunu bir kez yaşamıştım. Yukarıdaki pullup çözümü bu sorunu da engeller.
#int_rda yazan yerde
(uart kesmesi geldiğinde mcu buraya dallanır)
getc(); ile 1 byte okuma yapılması gerekiyor ve
return olmaması daha iyi olur hatta olmaması lazım.
Programın main kısmındada uarttan alma işlemi yapılmayacak,
yani getc(); gets(); gibi şeyler kullanılmayacak.
yani şöyle bir yapı olacak
#INT_RDA
void RDA_isr(void)
{
received_data = getc();
receive_state = 1;
}//void rdaisr son
Ayrıca basla:
...
goto basla yapısını ortadan kaldırın,
birdahada C yazarken hiç kullanmayın.
Program içinde veri alınan bir komut yok.
@RaMu'nun da belirttiği gibi int rda içinde byte byte okuma yapmalısın.
Ayrıyeten hem program içinde hem de kesme rutini içinde bekleme yapmak çok doğru değil. Özellikle kesme içinde kesinlikle bekleme yapmamak gerekir.
Şu şekilde main içinde tanım yapabilirsin.
Unsigned int16 sayac;
sayac++;
if (sayac%3000==1)
{output-high(pin_a0);}
İf ( sayac%4000==1)
{output-low(pin_a0);}
Delay_ms(1);
Bu şekilde hem seri porta daha kolay erişir hem de gereksiz beklemez.
pull-up ve kodda tavsiyeleriniz üzerine yaptığım değişikliklerden sonra sorun düzeldi.
::ok
Teşekkürler,