|
|
View previous topic :: View next topic |
Author |
Message |
hainguyen
Joined: 12 May 2011 Posts: 2
|
Problem with int_rda of PIC18f2550 |
Posted: Wed May 18, 2011 7:55 pm |
|
|
Hi all,
I'm trying to write a program to communicate between PIC18f2550 and SIM300cz, which includes int_rda to get characters, and send characters, but there are problems and i can't solve,
here is the code:
Code: | include <18F2550.h>
#device adc=10
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#include "lcd_routine.c"
#include "sms_routine.c"
#define BUFFER_SIZE 200
BYTE buffer[BUFFER_SIZE];
char ptr[50];
int i=1,j=0;
int1 sms = 0;
unsigned int16 next_in = 0;
unsigned int16 next_out = 0;
#int_rda
void serial_isr()
{
sms=1;
for (i = 0;i<=14;i++)
{
buffer[i]=getc();//delay_ms(10);
printf(lcd_putc,"%c",buffer[i]);
}
}
void main()
{
lcd_init();
lcd_gotoxy(1,1); lcd_putc("Start... ");
lcd_gotoxy(1,2); lcd_putc(" ");
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL) ;
while(1)
{
if (sms==1)
{
lcd_gotoxy(1,1);
for (i = 0;i<=14;i++)
{printf(lcd_putc,"%c",buffer[i]);}
[b]disable_interrupts(INT_RDA); [/b] //(*)
CHAR SDT[] = {"0914289089"};
CHAR SMS1[] = {"Door is open"};
printf("AT+CMGS=");putc(34);//"
printf(SDT);putc(34);//"
putc(13);//enter CR
delay_ms(500);//waiting for character
printf(SMS);
delay_ms(100);//
putc(26);//CTRL+Z
Message(SMS1,SDT);
[b]enable_interrupts(INT_RDA); [/b] (**)
lcd_gotoxy(1,1); lcd_putc("Done ... ");
delay_ms(100);
sms = 0;
lcd_gotoxy(1,1); lcd_putc("Start... ");
lcd_gotoxy(1,2); lcd_putc(" ");
}
}
} |
The problems are:
- if i don't use the command (* -disable_interrupts(INT_RDA); ) - the printf(), never can be executed, it means that i can't send characters to SIM300cz to make it sends message.
- if i use (*-disable_interrupts(INT_RDA);), i can send message (i can use printf() after that), but i never get any character next time. The int_rda executes only one time.
Any body help me pls, thank so much! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed May 18, 2011 8:24 pm |
|
|
Quote: |
#int_rda
void serial_isr()
{
sms=1;
for (i = 0;i<=14;i++)
{
buffer[i]=getc();//delay_ms(10);
printf(lcd_putc,"%c",buffer[i]);
}
}
|
Don't do it this way. Get one byte per interrupt. See the example file
ex_sisr.c, which shows how to make a circular buffer for #int_rda.
Here's the file location:
Quote: | c:\program files\picc\examples\ex_sisr.c |
|
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Wed May 18, 2011 8:33 pm |
|
|
Hi,
You are using the serial ISR incorrectly as you are trying to read multiple characters each time the interrupt is serviced. The int_rda interrupt will fire each time a character is received, so you need to fill your serial receive buffer one character at a time inside the serial ISR, and then process it in Main. How you determine when the entire transmission has been received will depend on the data being sent. It might be a start/end sequence, or it might be a total number of characters, etc.
So, pehaps set a global CharacterCount variable, and increment it inside the serial ISR. Test this variable in Main, and when the correct number of characters are received, set the variable to zero and process the receive buffer.
Also add 'Errors' to the #use_rs232 function. This will prevent the PIC from hanging if the serial buffer is over-run....
John |
|
|
hainguyen
Joined: 12 May 2011 Posts: 2
|
Problem with int_rda of PIC 18F2550 |
Posted: Wed May 18, 2011 9:27 pm |
|
|
PCM programmer wrote: | Quote: |
Don't do it this way. Get one byte per interrupt. See the example file
ex_sisr.c, which shows how to make a circular buffer for #int_rda.
Here's the file location:
c:\program files\picc\examples\ex_sisr.c |
|
Thank for your helps PCM Programmer and ezflyr, I've used ex_sisrc.c and it's ok now.
But there is one more thing that I need your helps again.
Now I want to receive a string instead of each character, I've used the test code below:
Code: | #int_rda
void serial_isr() {
int t;
buffer[next_in]=getc();
t=next_in;
next_in=(next_in+1)%BUFFER_SIZE; //
if(next_in==next_out)
next_in=t; // Buffer full !!
}
#define bkbhit (next_in!=next_out)
BYTE bgetc()
{
while(!bkbhit);
c=buffer[next_out];
next_out=(next_out+1)%BUFFER_SIZE;
printf(lcd_putc,"%c",c);
delay_ms(100);
}
void main()
{
lcd_init();
lcd_gotoxy(1,1); lcd_putc("Start... ");
lcd_gotoxy(1,2); lcd_putc(" ");
enable_interrupts(INT_RDA); //
enable_interrupts(GLOBAL) ;
do {
while(bkbhit)
bgetc();
} while (TRUE);
}
|
each character appears one by one after every 100ms correctly.
But when i add
Code: | printf(lcd_putc,"%s",buffer) |
after
Code: | next_in=t; // Buffer full !! |
I didn't get anything.
I've tried another way, I use a new string array as this way:
Code: | BYTE bgetc()
{
while(!bkbhit);
c=buffer[next_out];
next_out=(next_out+1)%BUFFER_SIZE;
//printf(lcd_putc,"%c",c);
temp_s[i] = c;i++;
if (i>BUFFER_SIZE)
{
i = 0;
printf(lcd_putc,"%s",temp_s);
}
delay_ms(100);
} |
There were incorrect characters appear on my LCD.
Do you know where the problem is? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed May 18, 2011 11:24 pm |
|
|
Don't put debug code such as lcd_putc() inside the bgetc() and #int_rda
routines. Don't attempt to use the 'buffer' array in your own code.
Call bgetc() in main() and get the character from the buffer.
Example:
If you want to build a string, then put each byte in a new array (not
the 'buffer' array). Then put a 0x00 byte at the end of the characters
in the array. This 0x00 byte makes it a string and it indicates the end of
the string. Don't writes bytes past the end of the array. (Make it large
enough for the characters AND for the 0x00 byte at the end).
Make sure that the characters that you put into the array actually are
ASCII characters. (Alphabetic characters and numbers. All should be
in ASCII format). |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|