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

A question on getc() and UART interaction

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



Joined: 14 Nov 2005
Posts: 14

View user's profile Send private message

A question on getc() and UART interaction
PostPosted: Mon Nov 14, 2005 3:55 am     Reply with quote

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







    PostPosted: Mon Nov 14, 2005 6:14 am     Reply with quote

    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

    View user's profile Send private message

    PostPosted: Mon Nov 14, 2005 6:48 am     Reply with quote

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