Picproje Elektronik Sitesi

DERLEYİCİLER => CCS C => Konuyu başlatan: hemso - 11 Şubat 2011, 00:12:34

Başlık: RS232 ile veri alımı
Gönderen: hemso - 11 Şubat 2011, 00:12:34
Merhaba arkadaşlar,

Yaklaşık 6 7 ay önce RS232 ile seri port haberleşmeli bir hesap makinesi yapmıştım. O projede bilgisayardan hyperterminal ile bir değer girip ascii kodlarını da kullanarak gercekleyebilmiştim. Ancak şu an önümde cok cabuk halledilmesi gereken başka bir RS232 projesi var. Projeyi 2 kanattan yürütüyoruz. Diğer arkadaş RFiD etiketli kartı kapıda okutuyor. Eğer kart daha önce oluşturulan vertabanında ise bilgisayara eşleşmenin başarıyla gerçekleştiğine dair 5 ya da 6 bytelık bir bilgi geliyor. Buraya kadar olan kısmı arkadaşım CSHARP programlama dili ile gerçekleştirdi. Buradan sonra benim bu bilgiyi RS232 ile bilgisayardan pic'e gönderip eğer gelen bilgi benim istediğim 5 Byte'lık bilgi ise pic'in daha önceden belirlediğim bir cıkıs portuna lojik 1 vermem gerekiyor. Yani kısacası aldığım veri onay ise pic ledi yakacak gibi düşünebilirsiniz. Şimdi benim burdaki sorunum şu: Hesap makinesi yaptığım zaman bilgisayara girilen bir karakter vardı ve getch() komutu ile bu karakteri alabiliyorduk. Ama burda basılan bir tuş olmadığı için getch fonksiyonunu kullanmam mantıksız olur sanırsam. Veriyi direk nasıl alabilirim ve kontrol olabilirim sizce. 

NOT: Gelen veri 8 er bitlik 5 paket şeklinde sırayla gelecek yanılmıyorsam. Yani mesela 0xFF, 0x01, 0x01,0x11,0x00 olsun.
Başlık: Ynt: RS232 ile veri alımı
Gönderen: hemso - 11 Şubat 2011, 01:53:12
Arkadaşlar projeyi böyle yapmak yerine şu duruma indirgedik. Eğer bilgisayardan 00d11 gelirse onay;00y11 gelirse ret cevabı olacak. Onay cevabı: ledin yanması,ret cevabı: ledin yanmaması olarak düşünebilirsiniz. Yazdığım kodda önce char klavye[80] diye bir şey tanımladım daha sonra gets(klavye) dedim.(bunların hepsini rs232 interruptının içinde yapıyorum.) daha sonrada işte if(klavye=="00d11") vs. diyerek programı tamamladım. Ancak program if'li olan satırda hata verdi. Sebebini anlayamadım bir türlü. Sizce hata nerede olabilir? Kod burda:

#include "C:\Documents and Settings\hemso\Desktop\CCS\abc.h"

char klavye[80];
int i;

#int_rda
void serihaberlesme_kesmesi ()
{
   disable_interrupts(int_rda);
   gets(klavye);
   
   if(klavye=="00d11")
   {
     output_high(pin_a2);
     output_high(pin_a4);
     output_high(pin_a3);
     delay_ms(1000);
     output_a(0x00);
     break;
   }
   if(klavye=="00y11")
   {
     output_high(pin_a5);
     for(i=0;i<3;i++)
     {
        output_high(pin_a3);
        delay_ms(500);
        output_low(pin_a3);
        delay_ms(200);
     }
     
     output_a(0x00);
     break;
   }
}

void main()
{
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   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);
//Setup_Oscillator parameter not selected from Intr Oscillator Config tab

   set_tris_a(0x00);
   output_a(0x00);
   
   while(1)
   {
      enable_interrupts(int_rda);
   }

}
Başlık: Ynt: RS232 ile veri alımı
Gönderen: eseneren - 11 Şubat 2011, 08:58:41
CCS bilmiyorum ama  if(klavye=="00d11") tırnaklar olacak mı?
Fırat Deveci hitech (soft) kitabında SPI kutuphane hazırlamıs guzel ornegı de var 15 dakıka harcanarak etkın olarak kullanılır dıye dusunuyorum.
Başlık: Ynt: RS232 ile veri alımı
Gönderen: hemso - 11 Şubat 2011, 16:45:34
Klavye string olacağı için burda bir sorun olmaz diye düşünmüştüm. Hatayı aldıktan sonra değiştireyim diye düşündüm ancak onun alt satırlarında klavye=="00y11" diye bir if li ifade var gene ama orada bir hata görünmüyor. hatta altta çıkan hatayı da yazayım. 1 warning bir de error görünüyor. Hata şöyle:

Warning 203 "rfid.c" line 54(1,1): Condition always true.
Error 44 "rfid.c" Line 12(1,1): Internal Error- Contact CCS LABEL SCR=332
1 Errors, 1 Warnings.
Başlık: Ynt: RS232 ile veri alımı
Gönderen: JKramer - 11 Şubat 2011, 17:47:40
Warning çok önemli değil, muhtemelen while(TRUE) şeklinde bir satır için vermiştir.

Hata içinse; derleyici sürümünü yazmamışsınız ama eski bir sürümse güncelleme yapmanız durumunda sorununuz belki çözülebilir. (rfid.c'de ilgili satır nedir, bilmiyoruz.)
Başlık: Ynt: RS232 ile veri alımı
Gönderen: mufitsozen - 11 Şubat 2011, 18:11:05
Alıntı yapılan: hemso - 11 Şubat 2011, 01:53:12
Arkadaşlar projeyi böyle yapmak yerine şu duruma indirgedik. Eğer bilgisayardan 00d11 gelirse onay;00y11 gelirse ret cevabı olacak. Onay cevabı: ledin yanması,ret cevabı: ledin yanmaması olarak düşünebilirsiniz. Yazdığım kodda önce char klavye[80] diye bir şey tanımladım daha sonra gets(klavye) dedim.(bunların hepsini rs232 interruptının içinde yapıyorum.) daha sonrada işte if(klavye=="00d11") vs. diyerek programı tamamladım. Ancak program if'li olan satırda hata verdi. Sebebini anlayamadım bir türlü. Sizce hata nerede olabilir? Kod burda:

#include "C:\Documents and Settings\hemso\Desktop\CCS\abc.h"

char klavye[80];
int i;

#int_rda
void serihaberlesme_kesmesi ()
{
   disable_interrupts(int_rda);
   gets(klavye);
   
   if(klavye=="00d11")
   {
     output_high(pin_a2);
     output_high(pin_a4);
     output_high(pin_a3);
     delay_ms(1000);
     output_a(0x00);
     break;
   }
   if(klavye=="00y11")
   {
     output_high(pin_a5);
     for(i=0;i<3;i++)
     {
        output_high(pin_a3);
        delay_ms(500);
        output_low(pin_a3);
        delay_ms(200);
     }
     
     output_a(0x00);
     break;
   }
}

void main()
{
   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   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);
//Setup_Oscillator parameter not selected from Intr Oscillator Config tab

   set_tris_a(0x00);
   output_a(0x00);
   
   while(1)
   {
      enable_interrupts(int_rda);
   }

}

Program dili olarak C dilini kullaniyorsunuz değil mi?

O takdirde su iki if dusundugunuz seyi yapmiyor


C dilinde arrayler (karakter dizinleride dahil olmak uzere) aslinda pointer'dir. Bu yuzden siz klavye string'inin saklandigin yerin pointer'ini  (adresini) "00d11" yada "00y11" stringinin saklandigi yerin adresi ile karsilastiriyorsunuz. Buda herzaman "false" olur. (cunku literal stringler ROMda yada diger degiskenlerden ayri bir segmentda tutulurlar.

iki karakter stringini karsilastirmak icin run-time libraryden strcmp fonksiyonunu kullanmaniz gerekir.

if(1 == strcmp(klavye,"00d11") [veya daha cesursaniz if(strcmp(klavye, "00d11")    :)
  yada
if(1 == strcmp(klavye,"00y11") [veya if(strcmp(klavye,"00y11")]

seklinde.


Başlık: Ynt: RS232 ile veri alımı
Gönderen: hemso - 12 Şubat 2011, 03:36:23
Verdiğiniz bilgiler için çok teşekkür ederim. Bu bilgiler ışığında #include string.h kütüphanesini ekleyerek strcmp fonksiyonuyla dediğiniz işlemi yaptım. Bunun üzerine attempt to create..... tarzında bir hata verdi. Bende bunun üzerine strcmp(klavye,"00d11") yapmadım. 2 adet daha string tanımlayıp bu değerleri stringin içine attım(mesela onay[10]="00d11") ve if(strcmp(klavye,onay)) şeklinde iki diziyi karşılaştırdım ve sonuç olarak hiç hata vermedi. Şimdi kod işlevini yerine getiriyormu diye proteusta deneyeceğim. Umarım beklediğim gibi olur. Tüm yardımlarınız için tekrar teşekkürler. Bu siteyi seviyorum:D
Başlık: Ynt: RS232 ile veri alımı
Gönderen: hemso - 12 Şubat 2011, 11:17:50
Maalesef kod şu an işlevini yerine getiremiyor.gets(klavye) dedikten hemen sonra puts(klavye) dedim rs232 calısıyomu diye kontrol edebilmek için ancak herhangi bir şey cıkmadı ekranda...
Başlık: Ynt: RS232 ile veri alımı
Gönderen: drmp - 12 Şubat 2011, 12:35:10
if ile yaptığın karşılaştırmayı  bytelara böl ayrı ayrı if içinde sınaya bilirsin ben olsaydım bu şekilde yapardım
Başlık: Ynt: RS232 ile veri alımı
Gönderen: hemso - 12 Şubat 2011, 13:05:18
programda mainin içine acaba rs232 calısıyormu diye deneme amaclı olarak printf("quaresma") yazdım ancak virtual terminal ekranında sacma sapan 3 tane harf cıktı. Önce bu sorunu halletmem gerekiyor sanırsam. Kodumun basında yazan ayarlamaları yaptıgım kütüphaneyi yazmamısım onu da belirteyim belki orada düzeltilmesi gereken bir şey vardır:

#include <16F88.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES EC_IO                    //External clock
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPROTECT                //Code not protected from reading
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES IESO                     //Internal External Switch Over mode enabled

#use delay(clock=20000000)
#use rs232(baud=19200,parity=N,xmit=PIN_B5,rcv=PIN_B2,bits=8)
Başlık: Ynt: RS232 ile veri alımı
Gönderen: hemso - 12 Şubat 2011, 13:08:19
Bu arada yukarıdaki xmit ve rcv pinleri yani RS232 aktarımının yapıldığı pinler project wizard dan ayar yaptığımda otomatik olarak a2 ve a3 görünüyordu. Ancak picteki donanımsal olarak görünen usart pinleri(TX ve RX) B5 ve B2 göründüğü için bunları B5 ve B2 pini haline getirdim. Bundan solayı oluşmuş bir sorun da deildir heralde.
Başlık: Ynt: RS232 ile veri alımı
Gönderen: hemso - 12 Şubat 2011, 13:57:05
Arkadaşlar beklenti cok düştüğünden ve projenin acelesi olduğunda projenin son hali şu. Bilgisayardan d harfi gelirse ledi yakacak, l harfi gelirse yakmayacak diye düşünün. Harflerin yanlış cıkma olayını da çözdüm bu arada. Bir terslik olmasın diye de int_rda kesmesini de kaldırdım. Pic başka birşey için kullanılmayacak çünkü zaten.Kod şöyle:

#include "D:\rflab\rfid_kapi\deneme1\deneme.h"
#include "string.h"


char klavye[10];
int i;

void main()
{

   setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   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);
//Setup_Oscillator parameter not selected from Intr Oscillator Config tab

   
 
   
   printf("quaresma");
   while(1)
   {
     klavye[0]=getc();
     putc(klavye[0]);
   
   if(klavye[0]==100)
   {
     output_high(pin_a2);
     output_high(pin_a4);
     output_high(pin_a3);
     delay_ms(1000);
     output_a(0x00);
     break;
   }
   if(klavye[0]==121)
   {
     output_high(pin_a0);
     for(i=0;i<3;i++)
     {
        output_high(pin_a3);
        delay_ms(500);
        output_low(pin_a3);
        delay_ms(200);
     }
     
     output_a(0x00);
     break;
   }
   }


}


Sorun şu virtual terminal ekranında benim printf ile gönderdiğim quaresma yazısı cıkıyor. ancak daha sonra  klavyeden yazdığım herhangi bir karakter ekranda yazmıyor. Burada getch ve putch yerine getc ve putc kullanmamın sebebi unexpected identifier hatası vermesiydi. Sizce sorun nerede?

Başlık: Ynt: RS232 ile veri alımı
Gönderen: hemso - 12 Şubat 2011, 15:07:35
Arkadaşlar sürekli yazıyorum kusura bakmayın ama size elde ettiğim gelişmeleri belirtip daha kolay bir çözüm üretebilmeniz acısından bilgilendirmek istediğimden tamamen. Şimdi anladığıma göre esas problem getchar kısmında. Çünkü proteus ta Pic'in TX ve RX pinlerine led bağladım ancak bir tek RX pinindeki led yanmaktaydı. Bunu nasıl çözebilirim?
Başlık: Ynt: RS232 ile veri alımı
Gönderen: drmp - 12 Şubat 2011, 15:53:19
bak arkadaş çok güzel anlatmış dostum picte 5 bytelık bir tx -rx registeri yoktur array vardır  fakat ben kodunda gelen byteları array haline sıralayan  bir yer göremedim bu yüzden 5 bytelık bilgisinin sonuncusunu yada karışık bir şey görebilirsin her neyse bu dikkat eet  bu kısım önemli kolay gelsin
Başlık: Ynt: RS232 ile veri alımı
Gönderen: ferdem - 12 Şubat 2011, 23:01:14
Lablarının kapısına rfid sistemi labdaki mühendis adayı öğrenciler tasarlıyor, işte bu! Ahmetcim seri data almanın en temiz yolu kesme ile almaktır, while içinde getch vs. ile almak sağlıklı olmaz. Forumda int_rda diye aratıp çıkan başlıkları okumak çoook faydalı olur. Ben o başlıklardaki bir bilgiyi buraya yapıştırarak devam ediyorum:

//picproje.org
//CCS C seri veri kesmesi örnek kullanımı
#include <16F628A.h>
#fuses NOPROTECT, NOMCLR, NOWDT, NOLVP, INTRC_IO
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_b2, rcv=PIN_b1)

unsigned int veri=0;
void main(){
enable_interrupts(global);
enable_interrupts(int_rda);

   while(1){
      output_high(pin_b4);
      delay_ms(1000);
      output_low(pin_b4);
      delay_ms(1000);
   }

}

#int_rda
void seri_veri_geldi(){
veri=getc();
output_toggle(pin_b0);
}


Bu kodda PIC normal seyrindeyken b4 e bağlı led flash yapıyor, veri geldiğinde değer "veri" değişkenine yazılıyor ve b0 pini toggle ediliyor, veri değişkeni global, main içinde de sorgulatabilirsin.
   while(1){
      output_high(pin_b4);
      delay_ms(1000);
      output_low(pin_b4);
      delay_ms(1000);
      if(veri=='A') //eğer A yazarsam aynıyla cevapla ;)
         putc(veri);
   }

yapıp deneyebilirsin.

Şimdi bu kod üzerinden devam etmelisin, elinde 1 byte veri geldiğinde kaçırmadan "veri" değişkenine yazan bir kod var başka ne lazım ki! Bu şekilde gelen stringleri de kontrol edebilirsin. CCS C deki gets fonksiyonu da bu mantıkla yazılmış, kütüphanesinde görebilirsin. Mesela seri data olarak gelen GPS cümleciklerinden önce $ karakterine bakan, $ geldiyse cümle GPGGA cümlesi mi diye kontrol eden int_rda rutini şöyle olabilir:
#int_rda
void seri_veri_geldi(){

veri=getc();
output_toggle(pin_d0);

if(veri=='$'){ // $ karakterini gördük
   index=0;
   out=0;
   record=1;
   i=0;
   return;

}

if(record==1){
c[index]=veri;
index++;
if(index==5) //5 byte alındıysa
record=0;
   if(c[0]=='G' && c[1]=='P' && c[2]=='G' && c[3]=='G' && c[4]=='A'){ //GPGGA cümlesi mi kontrol et
      out=1; //GPGGA cümlesi, out=1, sıradaki bytle lar lcdye gidecek
      i=0;
      record=0;
      c[0]=0;c[1]=0;c[2]=0;c[3]=0;c[4]=0; //temizle
   }   
return;   
}
//...kod devam ediyor

Bu şekilde siz de kendi int_rda rutininizi yazmalısınız.

#int_rda
void seri_veri_geldi(){
veri=getc();
putc(veri);
output_toggle(pin_b0);
}

Yazarsan klavyeden yazdığını aynen geri alırsın.


İyi çalışmalar, kolay gelsin.
Başlık: Ynt: RS232 ile veri alımı
Gönderen: hemso - 14 Şubat 2011, 17:23:53
Hocam bunları yazdığım gün bilgisayar başında 7 saat oturduktan sonra durumu hallettim:D Daha sonra da şimdiye kadar foruma girmedim maalesef. Şimdi gördüm yazdıklarınızı. Benim elimde şu an çalışan bir kod var işlevini yapan:D. Bende paylaşım olması açısından diğer arkadaşlar da görsün diye koyuyorum buraya. Ama genede bence esas -işte bu!- denilecek şey sizin öğrencilerinize bu kadar yardımcı oluyor olmanız. Sizi çok seviyoruz hocam:D Kod şöyle:

#include "D:\rflab\rfid_kapi\deneme3(16f877)\deneme3.h"
#include "string.h"



int i;
char klavye[10];

#int_RDA
void  RDA_isr(void)
{
    disable_interrupts(int_rda);
     
    for(i=0;i<5;i++)
    {
      klavye[i]=getchar();
      putchar(klavye[i]);
    }
   
     
   if(klavye[0]=='0' && klavye[1]=='0' && klavye[2]=='d' && klavye[3]=='1' && klavye[4]=='1')/*bu kısım biraz kazmaca oldu ama artık sinir oldum en son böyle yazdım:D*/
   {
     output_b(0x0E);
     delay_ms(1000);
     output_b(0x00);
     break;
   }
   if(klavye[0]=='0' && klavye[1]=='0' && klavye[2]=='y' && klavye[3]=='1' && klavye[4]=='1')
   {
     output_b(0x05);
     
     for(i=0;i<3;i++)
     {
        delay_ms(500);
        output_b(0b00000001);
        delay_ms(200);
        output_b(0b00000101);
     }
     
     output_b(0x00);
     break;
   }
}

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);

   enable_interrupts(GLOBAL);
 
   
   
   set_tris_a(0x00);
   output_a(0x00);
   
   
   
   printf("quaresma");
   while(1)
   {
     enable_interrupts(INT_RDA);
   }

}


Başta Fatih hocama olmak üzere yardımını esirgemeyen herkese saygılar..
Başlık: Ynt: RS232 ile veri alımı
Gönderen: 50Cal - 18 Nisan 2011, 17:02:43
Rda kesmesinin içindeki şu kısım kafamı karıştırdı;

    for(i=0;i<5;i++)
    {
      klavye=getchar();
      putchar(klavye);
    }

ilk '0' karakterini geldi klavye stringine atandı. i=1 oldu. 2. karakter alındı ve yine klavye= şeklinde diziye alındı. Dizi indeksi belirtilmeden 2. gelen karakteri klavye[1]'e 3. gelen karakteri klavye[2]'ye yerleştireceğini nasıl biliyor program?

string.h kütüphanesi eklemişsiniz, bununla bir ilgisi var mı?
Başlık: Ynt: RS232 ile veri alımı
Gönderen: eseneren - 19 Nisan 2011, 11:28:03
@50Cal
for(i=5;i<10;i++)
    {
      klavye=getchar(); //a.
      putchar(klavye);  //b.
    }
yazsanda aynı işi yapar, a. ve b. satır arka arkaya yazılsa 5 defa yıne aynı ısı yapar getchar klavyeden karakterı alıyor putcharda ekrana basıyor(neyse).
bır sonrakı karakter sonrakı haneye basılıyor aynı haneye basmak ıstersen b satırından sonra bırde backsspace koymak lazım.
yani putchar karakter bastıkdan sonra ne sayacı ıse artık bır artırıyor.

Başlık: Ynt: RS232 ile veri alımı
Gönderen: 50Cal - 19 Nisan 2011, 14:58:44
Teşekkürler, fakat sanırım sormaya çalıştığım şey yanlış anlaşılmış. For döngüsüyle ilgili bir sıkıntım yok, yani fordaki i değeriyle dizi indeksini karıştırmıyorum.

Anlayamadığım satır;  klavye=getchar();

Bir stringimiz var, 2 byte olsun;  klavye="xx"  klavye[0]='x' ve klavye[1]='x'

klavye=getchar(); ile 'A' karakterini alıp klavyeye atıyoruz.Muhtemelen 0 indeksine atacaktır karakteri, yani: klavye="Ax" olmalı.
sonra bir karakter daha alıyoruz('B' olsun) ve yine klavye=getchar(); Bu satırdan sonra olmasını beklediğim durum şöyle;  klavye="Bx" . Fakat arkadaşın uygulamasına göre klavye="AB" olmuş.

Yani öğrenmeye çalıştığım; program, bir stringin en son hangi elemanına karakter ataması yapıldığını ve sıradaki elemanın hangisi olduğunu nasıl biliyor? Stringe yada diziye bir atama yapıldığında dizinin o elemanın indeksi saklanıyor mu bi yerde?


Başlık: Ynt: RS232 ile veri alımı
Gönderen: JKramer - 19 Nisan 2011, 15:44:11
O örnek düzeltilmiş sanırım :). Son halini yukarıda bir kontrol edin:
for(i=0;i<5;i++)
    {
      klavye[i]=getchar();
      putchar(klavye[i]);
    }
Başlık: Ynt: RS232 ile veri alımı
Gönderen: 50Cal - 19 Nisan 2011, 17:02:19
Teşekkürler hocam, düzeltip kaçmışlar, hiç söylemiyorlar da    :P