CCS C / 16f877A / RS232 kesmesi sürekli açık kalıyor / takılıyor

Başlatan halnpx, 17 Mayıs 2019, 01:31:39

halnpx

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;

}

Tagli

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.
Gökçe Tağlıoğlu

RaMu

#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.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

fide

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.
Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com

halnpx

pull-up ve kodda tavsiyeleriniz üzerine yaptığım değişikliklerden sonra sorun düzeldi.
 ::ok

Teşekkürler,