|
|
View previous topic :: View next topic |
Author |
Message |
s.jaglowski
Joined: 14 Nov 2005 Posts: 14
|
A question on getc() and UART interaction |
Posted: Mon Nov 14, 2005 3:55 am |
|
|
Hello.
I hope someone can help.
I have a question on how getc() is supposed to work. I have an application where I wanted to use the gets(string) function which repeatedly uses getc() to read charachters in to the string. I was not able to do this so I commenced some tests.
I used the standard example UART interrupt routines and built-in functions. (see code below). At a ANSI terminal emulation on a PC, I typed in two number sequences from 0 to 9 and obtained the following results.
Start of Test - Test 1
01234567890123456789
Start of Test - Test 2
25893
Start of Test - Test 3
....
Start of Test - Test 4
012
Start of Test - Test 5
4
Test 1 worked fine. All other tests failed with most output for tests 2 to 5 occuring on the second sequence of numbers 0 to 9.
Test 1 demonstrates that interrupts are being detected and managed and that getc() works within the interrupt handler. But as soon as you use the built in functions getc() or kbhit() in the main loop problems arise. There is no apparent problem with putc() or printf().
I'm using CCS compiler PCW 3.219. Can some one explain what is going on?
CODE
#include <16F873.h>
#if __device__ ==873
#define Tx1 PIN_C6
#define Rx1 PIN_C7
#fuses XT, NOLVP, NOWDT, NOCPD, NOPROTECT, PUT, NOBROWNOUT
#endif
#use delay(clock=8000000)
#use rs232(baud=9600,xmit=Tx1,rcv=Rx1)
#define BUFFER_SIZE 16
BYTE buffer[BUFFER_SIZE];
BYTE next_in = 0;
BYTE next_out = 0;
BYTE t_buffer[BUFFER_SIZE];
BYTE t_next_in = 0;
BYTE t_next_out = 0;
/*-------------- UART Rx interrupt handler ----------------*/
#int_rda
void serial_Rx_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()
{
BYTE c;
while(!bkbhit) ;
c=buffer[next_out];
next_out=(next_out+1) % BUFFER_SIZE;
return(c);
}
/*-------------- UART Tx interrupt handler ----------------*/
#int_tbe
void serial_Tx_isr()
{
putc(t_buffer[t_next_out]);
t_next_out=(t_next_out+1) % BUFFER_SIZE;
if(t_next_in==t_next_out)
disable_interrupts(int_tbe);
}
void bputc(char c)
{
short restart;
int ni;
restart=t_next_in==t_next_out;
t_buffer[t_next_in]=c;
ni=(t_next_in+1) % BUFFER_SIZE;
while(ni==t_next_out);
t_next_in=ni;
if(restart)
enable_interrupts(int_tbe);
}
/*-------------- MAIN PROGRAMME ----------------*/
void main()
{
enable_interrupts(INT_TBE);
enable_interrupts(INT_RDA);
enable_interrupts(global);
printf("\n\rStart of Test - Test 1\n\r");
while(true)
{
//if(kbhit()) //Tests 3,4,5
//{
//printf("."); //Test 3
//putc(bgetc()); //Test 4
//putc(getc()); //Test 5
//}
putc(bgetc()); //Test 1
//putc(getc()); //Test 2
}//end of while(true)
}//end of main() |
|
|
Ttelmah Guest
|
|
Posted: Mon Nov 14, 2005 6:14 am |
|
|
Don't use kbhit, getc, or gets, in your main.
If you are using interrupt driven UART handling, then _use_ this.
The problem of using the 'polled' instructions (kbhit etc.), in the main, is that if the flag gets set getc is called, the _interrupt_ , and will retrieve the data, so kbhit, never goes true.
You are using two mutually exclusive technologies. If using an interrupt driven receive, then instead of using 'kbhit', you should use the bkbhit test (which says there is a character in the buffer). Instead of getc, you use the bgetc code.
Getc, will hang for ever.
Best Wishes |
|
|
s.jaglowski
Joined: 14 Nov 2005 Posts: 14
|
|
Posted: Mon Nov 14, 2005 6:48 am |
|
|
Thank you very much Ttelmah.
This is the first time I've used PICs and CCS for serial comms. My previous experience in other embedded environments has been that
getc() and other I/O functions have been interrupt driven rather than polled.
There doesn't appear to be a problem using printf(), which I think I understand why, now. But suppose I want/need my printf() to use interrupt driven transmission, what do I do then?
Regards,
S.Jaglowski |
|
|
|
|
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
|