![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
Tagge
Joined: 23 Aug 2005 Posts: 93
|
RS232 |
Posted: Mon Jan 02, 2006 7:07 am |
|
|
Hi, I'm trying to get a interrupt driven (UART in 16F876A) to trigg an external function.
But I want to save the chars in the buffer, and use them in the function.
The incomming chars are, /?! CR LF, I tryed to read them into a global buffer, end then compare against a string, but it wont work.
If I only read them into that buffer in ISR() and then compare against a couple of chars (?!) it works fine. But I need to have the possibility to compare against a whole string later.
Do anyone has an idea why it wont work?
Code:
in main file:
#use rs232(baud=300, xmit=PIN_C6, rcv=PIN_C7, bits=7, parity=E, ERRORS)
#int_rda
void serial_isr() {
rs232_flag=ON;
}
Then I poll for that flag in main and jump to:
void func(){
char i, sign, string[], string1[];
strcpy(string1, "/?!");
get_str(string,BUF_SIZE);
if(!strcmp(string, string1))
// 1. All must respond with ID
printf(USER_ID"\n\r");
//2. If ACK
sign=getc();
if(sign==0x06){ //if it wants to speak, ASCII for ACK
}
The code has been cut down for easy reading |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Jan 02, 2006 9:26 am |
|
|
First of all: when posting source code use the 'code' button, this ensures your code will be easier to read.
Setting a flag in your interrupt routine and then polling this flag in the main routine is not a good way of handling serial communications, among several other problems your main function might be too slow in responding and you miss data.
A better way for handling the serial port is to have your interrupt routine fill a buffer and then handle the contents of this buffer from your main function. For the buffer you can use either a linear or circular buffer type, see this thread for a description of when to use which buffer type.
An example of a circular buffer implementation is ex_sisr.c in the CCS example directory. An explanation of the internal workings of this example is given at http://www.ccsinfo.com/forum/viewtopic.php?t=19083
An example of a linear buffer can be found in the post of Humberto in http://www.ccsinfo.com/forum/viewtopic.php?t=19117
Searching this forum you can find many more circular buffer implementations. |
|
![](templates/subSilver/images/spacer.gif) |
Tagge
Joined: 23 Aug 2005 Posts: 93
|
|
Posted: Tue Jan 03, 2006 4:25 am |
|
|
Thanks, god hints. But I still think I have to have a flag in the isr(), because I cant do all things in isr, it would take to long time?
And I must know when a string has arrived. Or the right sequence of chars. The incoming string can be from 4 to 32 bytes(chars), starts with a '/' and ends with a CR and then a LF.
Can I decode this string in the isr(), by get_string(), it doesnt seem to work with this strings, and inside a isr()??
beside the strings arrive in between 10-20sec, good time to poll for the flag?
The string is by the format of: 1 start bit, 7-data, 1 par, 1 stop.
Code: |
#use rs232(baud=300, xmit=PIN_C6, rcv=PIN_C7, bits=7, parity=E, ERRORS)
#int_rda
void serial_isr() {
buffer[next_in]= getc();
if(buffer[next_in]=='!' && buffer[next_in-1]=='?') //look for this chars
rs232_flag=ON;
if(buffer[next_in]=='\n')
next_in=0;
if(next_in==BUFFER_SIZE)
next_in=0; // Buffer full !!
next_in++;
}
main(){
if(rs232_flag=ON)
func();
//.......
}
void func(){
//checking for a special string
//would like to use the bufferd chars or
// by get_string()....
// if(strcmp(!str1, str2)).....
rs232_flag=OFF; //reset flag
for(i=0;i<=BUFFER_SIZE;i++) //clear buffer
buffer[i]=0;
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Tue Jan 03, 2006 5:13 am |
|
|
The normal approach, assuming the incoming data follows some known 'format', is to use a 'state machine' in the ISR. What happens is that the first time the routine is called, the 'state' is 0, and in this state, it checks the single character, against 'acceptable' first characters. If the character is recognised, the state is advanced, and the routine exits. For each character as it arrives, there is a similar behaviour. So (for instance), you could have a string, that if it begins with 'n', then has a 3 digit number. The state machine when it finds 'n' in the incoming data, moved the state, to one which saves the next three digits as a number, and then starts looking for the next 'key' value.
Done properly, each state, needs only check one character, and the state value. Though it still makes the ISR slower than may be 'ideal', this can easily handle complex input tasks. As an example, I have one, looking for 'keywords' in an input stream, which uses an alphabetically organised table of words, and a row/column counter. It 'walks' the table with subsequent characters, to either find a match, or fail.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|