Seri port okuma

Başlatan mcn, 27 Temmuz 2010, 18:51:42

mcn

Merhaba üstadlar,

Daha önce birçok seri port dan data gönderimi uygulaması yaptım ama hiç okumadım.Şimdi böyle birşey yapmam gerek ve getc(); gets('') vb gibi bir kaç komutu denedim,geleni okuyup lcd ye yazdırmaya çalışıyorum ama hep garip garip simgeler çıkıyor.

Okumam gereken datalar hex formatında,burda tanımlamam gereken değişkeni hangi formatta tanımlamam gerek ve hangi komutla seri porttan oku emrini verebilirim.
Şimdiden teşekkürler...
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

stlg

Neden donanımı kullanmıyorsun
ALLAHA EMANET OLUNUZ Hoştur bana senden gelen,  Ya gonca gül yahut diken,  Ya kaftandır yahut kefen,  Kereminde hoş lütfunda hoş.

mcn

Donanımı kullanmak derken?

Gelen seri datayıda tabi ki kesme ile almaya çalışıyorum.Okumam gereken cihaz şu şekilde data gönderiyor,örneğin ben ona seri porttan "01 0f" kodunu gönderiyorum o da bana "01" gönderiyor,bu tarz haberleşiyor.bunu bilgisayar da yapıyorum seri port programıyla,ama pic le yapmam gerek.Şimdi bu gönderdiği "01"  datasını nasıl alabilirim?
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

stlg

 Pic icinde bu iş icin ayrılmıs uart adında bir modul var, bunun yapısını ogrenmek gerekli pinleri kullanmak ve hangi dil ile program yazıyorsan programını yazman gerekiyor
ALLAHA EMANET OLUNUZ Hoştur bana senden gelen,  Ya gonca gül yahut diken,  Ya kaftandır yahut kefen,  Kereminde hoş lütfunda hoş.

mcn

denediğim kodları burda paylaşıyorum,
Bu okumak için yazdığım kod;

#include <16f887.h>

#FUSES NOWDT                    //No Watch Dog Timer

#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
            //Brownout reset at 2.0V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
                  //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
                 //Data EEPROM not write protected

#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#include <string.h>
#include <stdlib.h>
#include <string.h>
#use fast_io(a)

#define GLCD_CS1                 PIN_B0
#define GLCD_CS2                 PIN_B1
#define GLCD_RST                 PIN_B5
#define GLCD_RS                  PIN_B2
#define GLCD_E                   PIN_B4
#define GLCD_RW                 PIN_B3

//-----------{}------------------------------

#include "HDM64GS12.c"
#include "graphics.c"

   char text[] = "MCN";
   char text1[] = "kesmedeyim";
  int8 digit;
 //SERİ PORT KESMESİ
#int_rda
void rs232_kesme()
{

disable_interrupts(INT_RDA); 
 glcd_init (ON);
 
digit=getc();


glcd_text57 (20, 24,text1, 1, ON) ;
glcd_text57 (10, 40,digit, 1, ON) ;
delay_ms(2000);

}
 
 
void main()
{


   setup_adc(ADC_CLOCK_DIV_2);
 
   setup_spi(SPI_SS_DISABLED);
 
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
 
  enable_interrupts(INT_RDA);
  enable_interrupts(global);

//Setup_Oscillator parameter not selected from Intr Oscillator Config tab

   // TODO: USER CODE!!
   set_tris_a(0xff);
       
   glcd_init (ON);
   
   
   int i;
   
 glcd_text57 (10, 24,text, 1, ON) ; //yeni kodu ekrana yaz
while(1)
{

 enable_interrupts(INT_RDA);
glcd_text57 (10, 24,text, 1, ON) ; //yeni kodu ekrana yaz
delay_ms(10);
glcd_init (ON);
glcd_text57 (10, 24,text, 2, ON) ;
delay_ms(10);


while(input(pin_a1))
{
printf("01");
printf("0f");

while(input(pin_a1))
{}
}}}


Şimdi haberleşmem gereken cihaza serial port monitor programı ile seri portla bağlanıyorum,
programdaki data gönderme kısmından string olarak "01 0f" gönderdiğimde dönüş olarak "01" alıyorum.
Seri port programının görüntüsü:
[IMG]http://img231.imageshack.us/img231/1540/asdcq.jpg[/img]

Uploaded with ImageShack.us

Bunu pic le yapmam gerek ama çeşitli kodlar denememe rağmen bunu başaramadım.Grafik lcd de sürekli digit değişkeninin yazmaıs gereken yerde karman çorman bişeyler yazıyor.

Değişkenlerimi,ya da kodlarımı nasıl düzenlemem nerek?
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

JKramer

Kesme içerisindeki glcd fonksiyonlarını ve delay'i kaldırın, bir bayrağı set edip ana programdan okuyun. Bence glcd işine girmeden seri porta sadece karakter alıp gönderin, sorun çözüldüğünde diğer aşamaya geçersiniz.

mcn

JKramer hocam,
Haberleştiğim cihazla doğru haberleştiğimi görebilmem için tek yol bu.Cihaz sadece bir kart ve tepki verebilecek başka birşeyi yok.O yüzden okuduğumu lcd ye yazdırmalıyım.
Dediğiniğz gibi yapmak için kodu şu şekilde düzenledim ancak sonuç değişmedi:
#include <16f887.h>

#FUSES NOWDT                    //No Watch Dog Timer

#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
            //Brownout reset at 2.0V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
                  //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
                 //Data EEPROM not write protected

#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#include <string.h>
#include <stdlib.h>
#include <string.h>
#use fast_io(a)

#define GLCD_CS1                 PIN_B0
#define GLCD_CS2                 PIN_B1
#define GLCD_RST                 PIN_B5
#define GLCD_RS                  PIN_B2
#define GLCD_E                   PIN_B4
#define GLCD_RW                 PIN_B3

//-----------{}------------------------------

#include "HDM64GS12.c"
#include "graphics.c"

   char text[] = "MCN";
   char text1[] = "kesmedeyim";
  int8 digit;
 //SERİ PORT KESMESİ
#int_rda
void rs232_kesme()
{
 
digit=getc();
}
 
 
void main()
{


   setup_adc(ADC_CLOCK_DIV_2);
 
   setup_spi(SPI_SS_DISABLED);
 
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
 
  enable_interrupts(INT_RDA);
  enable_interrupts(global);

//Setup_Oscillator parameter not selected from Intr Oscillator Config tab

   // TODO: USER CODE!!
   set_tris_a(0xff);
       
   glcd_init (ON);
   
   
   int i;
   
 glcd_text57 (10, 24,text, 1, ON) ; //yeni kodu ekrana yaz
while(1)
{

 enable_interrupts(INT_RDA);
glcd_text57 (10, 24,text, 1, ON) ; //yeni kodu ekrana yaz
delay_ms(10);
glcd_init (ON);
glcd_text57 (10, 24,text, 2, ON) ;
delay_ms(10);

glcd_text57 (10, 40,digit, 1, ON) ;

while(input(pin_a1))
{
printf("01");
printf("0f");

while(input(pin_a1))
{}
}}}
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

JKramer

Yanlış anlamadıysam bilgisayar ile cihaz arası bir sorununuz yok. O zaman şöyle yapın; devrenizi bilgisayarın seri portuna bağlayın ve devre ile bilgisayar arası seri haberleşmeye çalışın. Bu aşamayı da geçtikten sonra devrenizle cihazı bağlarsınız.

01, 0F gibi hex sayıları göndermek için printf yerine putc(0x01); kullanmayı deneyin. Bir de yine yanlış görmediysem seri porttan cihaza veri gönderirken 01 ile 0F arası boşluk kullanmışsınız. Eğer öyleyse arada 0x20 (space) göndermeniz gerekiyor olabilir.

mcn

Şimdi hocam,dediklerinizle bi kaç hatamı düzelttim,dün istediğim şekilde çalışmıştı devre.Ancak bugün nedensene yaptımsa birtürlü aşağıda videosunu da ekliyorum,düzgün bi çalışma elde edemedim.Önceden karman çorman dediğimiz tek bir karakter çıkarken şimdi sırayla hepsini sayıyor mu ne yapıyor anlamadım.Kodlara bakıyorum,neden böyle yapıyoy anlamadım.Kodların son halini ekliyorum.

videonun linki:
http://www.akilli.tv/video/497926/grafik-lcd.aspx

#include <16f887.h>

#FUSES NOWDT                    //No Watch Dog Timer

#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT               //No brownout reset
            //Brownout reset at 2.0V
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOCPD                    //No EE protection
                  //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOWRT                    //Program memory not write protected
                 //Data EEPROM not write protected

#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

#include <string.h>
#include <stdlib.h>
#include <string.h>
#use fast_io(a)

#define GLCD_CS1                 PIN_B0
#define GLCD_CS2                 PIN_B1
#define GLCD_RST                 PIN_B5
#define GLCD_RS                  PIN_B2
#define GLCD_E                   PIN_B4
#define GLCD_RW                 PIN_B3

//-----------{}------------------------------

#include "HDM64GS12.c"
#include "graphics.c"

   char text[] = "MCN";
   //char text1[] = "kesmedeyim";
  int8 digit;
 //SERİ PORT KESMESİ
#int_rda
void rs232_kesme()
{
 
digit=getc();
}
 
 
void main()
{


   setup_adc(ADC_CLOCK_DIV_2);
 
   setup_spi(SPI_SS_DISABLED);
 
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
 
  enable_interrupts(INT_RDA);
  enable_interrupts(global);

//Setup_Oscillator parameter not selected from Intr Oscillator Config tab

   // TODO: USER CODE!!
   set_tris_a(0xff);
       
   glcd_init (ON);
   
   
   int i;
   
 glcd_text57 (10, 24,text, 1, ON) ; //yeni kodu ekrana yaz
while(1)
{

 enable_interrupts(INT_RDA);
glcd_text57 (10, 24,text, 1, ON) ; //yeni kodu ekrana yaz
delay_ms(10);
glcd_init (ON);
glcd_text57 (10, 24,text, 2, ON) ;
delay_ms(10);

glcd_text57 (10, 40,digit, 1, ON) ;

while(input(pin_a1))
{
putc(0x01);
//putc(0x20);
putc(0x0f);


while(input(pin_a1))
{}
}}}
www.teknikyazi.com --üşenme,erteleme,vazgeçme...

JKramer

Daha önce glcd kullanmadığım için bir şey diyemeyeceğim ama ekranı her çevrimde tazelediğiniz için neler olup bittiği görülemiyor. 500 ms'de bir tazeleme yapmak için Timer_1'i kullanabilirsiniz:

#define T1_PRELOAD (65536-62500)

int1 refresh=0;

#INT_TIMER1
void timer1_isr()
{
   refresh=1;
   set_timer1(T1_PRELOAD);
}

...

setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
set_timer1(T1_PRELOAD);
enable_interrupts(INT_TIMER1);

...

if(refresh)
{
   glcd_text57 (10, 24,text, 1, ON) ; //yeni kodu ekrana yaz
   delay_ms(10);
   glcd_init (ON);
   glcd_text57 (10, 24,text, 2, ON) ;
   delay_ms(10);
   glcd_text57 (10, 40,digit, 1, ON) ;
   refresh=0;
}

...

mcn

şu şekilde istediğim cevabı aldığımı anlıyorum,

yani 01 0f gönderince 01 alıyorum.

char mcn[]="ok";
int digit;
putc(0x01);
putc(0x0f);
digit=getc();
if(digit == 0x01)
{
glcd_text57(1, 1, mcn, 1, ON);
}

Şimdi şunu yapmak istiyorum,bu aldığım 0x01 ile işlem yapmak istiyorum,ekrana yazdırmak istiyorum.Gelen bu hex datayı nasıl tamsayıya çevirebilirim.

Birde bu aldığım datayı direk digit değişkenine atıyorum koddada görüldüğü gibi,ancak  şu kodla
" glcd_text57(1, 1, mcn, 1, ON);" ekrana yazdırmaya çalıştığda saçma sapan değerler çıkmaya devam ediyor.


www.teknikyazi.com --üşenme,erteleme,vazgeçme...