//#include <16F877A.h>
#include <18F4520.h>
#device ADC=10
#FUSES HS
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP
#use delay(crystal=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,errors)
char komut[80];
int role0on[]={"led0on"};
int role0off[]={"led0off"};
int k=1;
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#INT_RDA
void RDA_isr(void)
{
disable_interrupts(int_rda);
gets(komut);
k=1;
k=strcmp(komut,role0on);
if(k==0)
{
printf("\n\r Led aktif \n\r ");
}
k=strcmp(komut,role0off);
if(k==0)
{
printf("\n\r Led pasif \n\r ");
}
printf("\n\r kesme \n\r ");
}
void main()
{
/*setup_psp(PSP_DISABLED); // PSP birimi devre dışı
setup_timer_1(T1_DISABLED); // T1 zamanlayıcısı devre dışı
setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
setup_adc_ports(NO_ANALOGS); // ANALOG giriş yok
setup_adc(ADC_OFF); // ADC birimi devre dışı
setup_CCP1(CCP_OFF); // CCP1 birimi devre dışı
setup_CCP2(CCP_OFF); // CCP2 birimi devre dışı
*/
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(TRUE)
{
enable_interrupts(INT_RDA);
}
}
Arkadaşlar bir konuda yardıma ihtiyacım var. 877A sorunsuz çalışıyor fakat aynı kodlar 4520'de kesmeye giriyor fakat strcmp çalışmıyor. Nerede hata yapıyorum, neden çalışmıyor anlayamadım.
strcmp()'un calismadigini neye dayanarak soyluyorsun?
Kesme icinde iki yerde de strcmp()'u cagirmadan bir satir once printf ya da breakpoint koyarak "komut", "role0on" ve "role0off" degiskenlerinin degerlerini soyler misin?
Dedigim gibi ayni kod 877A 'da calisip 4520 de calismiyor.
Bu strcmp()'un calismadigi anlamina gelmez. strcmp()'un bekledigin gibi bir deger dondurmedigi anlamina gelebilir. O yuzden debug yapip bakmak lazim.
Dedigim degiskenlerin strcmp()'dan onceki, "k"nin de strcmp()'dan sonraki degerine debug yaparak bakip soyler misin?
Ayrica 877A icin yaptigin donanim ayarlarinin aynisi ile 4520'yi sorunsuz calistirabileceginden emin misin?
Alıntı yapılan: vitruvius - 27 Ekim 2017, 22:11:39
Bu strcmp()'un calismadigi anlamina gelmez. strcmp()'un bekledigin gibi bir deger dondurmedigi anlamina gelebilir. O yuzden debug yapip bakmak lazim.
Dedigim degiskenlerin strcmp()'dan onceki, "k"nin de strcmp()'dan sonraki degerine debug yaparak bakip soyler misin?
Doğrudur. k değişkeni sıfır değeri almıyor. Sürekli 1.
"komut"un degeri ne?
Alıntı yapılan: vitruvius - 27 Ekim 2017, 23:26:53
"komut"un degeri ne?
komut değişkeninin içeriğini geri çağırdığımda benim gönderdiğim değer ile birebir aynı. Ama şunu farkettim, gönderdiğim komuta göre k değeri +1 ve -1 değeri alıyor. Ama hiç sıfır değeri almıyor. (k değişkenini unsigned olarak değiştirdim)
k'yi unsigned olarak tanimlamamalisin. strcmp() (http://www.cplusplus.com/reference/cstring/strcmp/)'in tanimlamasini okudun mu? int deger dondurur. Ayrica arguman olarak da char array alir.
Farkli "komut" degerleri icin verdigin "komut" degerini ve "k"nin aldigi degeri yazar misin? (k hangi "komut" degerlerinde negatif ve pozitif bir deger aliyor onlari yazsan yeterli)
Strcmp fonk. Geri donus degerleri string.h icerisinde belirtilmis.
Burada benim icin asil sorun 877 de calisan kod neden 4520 de calismiyor. 4520 de demekki birseyler farkli, demekki biryerlerde eksik/ yanlis birsey var. Su an strcmp fonk +1 ve -1 degerleri uretiyor ve sifir degeri uretmiyor. Daha baska ne yapilabilir.?
!strcmp(a,b) seklinde deneyin
Merhaba.
Öncelikle şu gözüme çarptı.Role0on ve role0off değişkenlerini ibt tanımlayıp string atama yapmışsın.
Ve strcmp ile string ve int karşılaştırmadı yapıyorsun.
Seriporttan gelen veri içinde /r /n olabilir. Seriporttan ne geldiğinin önemi büyük. -1 alman karşılaştırılanlardan birinin daha kısa olduğu anlamına gelir. 1 ise eşit olmadığı.
Diğer bir konu efektif kod yazmak istiyorsan interrupt rutinini gets komutunda bitir. Burada 1 bitlik bir drğişkeni set et. Main içinde de bu değişkenin 1 olup olmadığını test et. Eğer 1 ise katşolaştırmaları yap, sey ettiğin değişkeni sıfırla. Strcmp, strcpy gibi string işlemleri yavaş yapılır ve beklemeye sebep olur. İnterrupt içinde beklemeye sebep olacak işlem yapılmaz.
Tahminin senin kodun 16f877de de çalışmıyor. 4520de çalışmamadı süpriz olmaz.
877 de calisan bir uygulamaydi. Farkli uzunlukta komutlar var ve bunlar 877 de sorunsuz calisiyor. Ayni string ve int karsilastirmayi orada da yapiyorum.
Simdi, 877 de calismasi mi imkansiz ? , 4520 de çalişmamasi mi. ?
Merhaba.
Sadece kendimi mikroişlemci yerine koyup düşünmeye çalışıyorum. İnt tanımlama ve string atama var. Bu hataya sebep olur gibi geldi. Seri portla ve gelen verileri işlemekle yoğun şekilde uğraştım. Belirli ve belirsiz uzunluktaki stringlerin okunması işlenmesi ile yüzlerce satır kod yazdım. Benim düşüncem stabil çalışmayacağı yönünde.
if(k==0)
{ printf("\n\r Led aktif \n\r "); }
k=strcmp(komut,role0off);
if(k==0)
{ printf("\n\r Led pasif \n\r ");
}
interrupta her girince kesme yazar çıkar.
Led aktif pasif yazmaz diyorum.
Kesme icinde cok zaman harcariz, kesme icinde harici is yapariz, kod mantigina uygun degil vs. Bunlarda haklisiniz. Benim icin suan bunlar teferruat. Ben daha cok sizden sunu bekliyorum.
4520 nin farki ne ki, 877 de calisan kod 4520 ye gelince tökezliyor. 4520 su yönden 877 den farkli o sebeple calismiyor vs?
while(TRUE) {
enable_interrupts(INT_RDA);
delay_ms(100);
}
Şeklinde dener misin.
16F877A ile 18F4520 arasında dağlar kadar fark var.
Birde CcsCde Project Wizard kısmından
sıfırdan 18F4520 için gerekli niteliklerde bir proje oluşturup
bu şekilde ilerlesen daha sağlıklı olur.
877'de yazdığın her kod 4520 de çalışır. Proteusta denerken 8mhz ayarla.
+led0on-
+led0off-
virtual terminale böyle yazacaksın.
#include <18F4520.h>
#device ADC=10
#use delay(internal=32MHz)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,stream=PORT1,errors)
#include "string.h"
#define bufferRead 0x0fae
char role0on[]={"led0on"};
char role0off[]={"led0off"};
char relay[100]={};
int1 bilgiKontrol=0;
int i=0;
#INT_RDA
void RDA_isr(void)
{
relay[i]=*(bufferRead);
if(bilgiKontrol)
{
if((relay[i]=='-')|| (i>7))
{
bilgiKontrol=0;
i=0;
}
}
if( relay[(i)] =='+')
{
bilgiKontrol=1;
i=255;
}
i++;
}
void main()
{
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while(TRUE)
{
if(!strncmp (role0on, relay,6 )) printf("relayON\r");
if(!strncmp (role0off, relay,7 )) printf("relayOFF\r");
delay_ms(1000);
}
}
kodlarına tekrar bakınca bulabildiğim 16 ve 18 serisi ailelerde Global interrupt kullanım farkı. 18 serilerinde globali aktif etmeden prg çalışır. 16 serisinde çalışmıyor. Belki global olarak tüm interruptları tek tek test edecek başka bir int rutini aktif oluyor, int rda aktif olmuyor.
Koddaki
[/size]int role0on[]={"led0on"};[/size]int role0off[]={"led0off"};
[/size]satırlarını string olarak tanımlayıp strcpy ile bu değerleri içine at. sonra enable interrupts(global) satırını kaldır ve tekrar dene.
[/size]