CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Problem with int_rda of PIC18f2550

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
hainguyen



Joined: 12 May 2011
Posts: 2

View user's profile Send private message

Problem with int_rda of PIC18f2550
PostPosted: Wed May 18, 2011 7:55 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed May 18, 2011 8:24 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed May 18, 2011 8:33 pm     Reply with quote

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

View user's profile Send private message

Problem with int_rda of PIC 18F2550
PostPosted: Wed May 18, 2011 9:27 pm     Reply with quote

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. Smile

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

View user's profile Send private message

PostPosted: Wed May 18, 2011 11:24 pm     Reply with quote

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:
Code:

c = bgetc();

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).
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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