camerart
Well-Known Member
Hi S,C, it does not matter much what kind of buffer you use, it is how you handle the interrupt and the data it gets. Think in time frames of 1 millisecond (mS)
First, try to get the interrupt RX routine to determine if the received characters are valid, and in the proper position in the string. For example, if you expect "$" as the first character and "A" as the 10th character, then the interrupt routine keeps track of what position your RX buffer is at, and if the expected character is not "correct", you zero the pointers/length and just go onto reading the next character. If length pointer happens to go past the buffer length (maximum message length), there is something wrong, and simply zero your pointers and counter in the interrupt routine and wait for next character. Do so until you get the right data stream and proper terminator. At that point, you set a flag that the UART RX buffer has a valid string and is complete. Nothing else!
All this can be done in the interrupt routine in the order of micro seconds (uS), maybe as much as 100uS for slower clock rates. That is 1/10th the rate at which characters arrive at the UART at 9600 baud (approx 1mS each). Keep it simple, use lots of flags and pointers, and parse the incoming characters as "valid" ONLY, do not interpret the string itself, that is for the main program to do! You basically filter the RX characters for valid data format only within the interrupt routine. Anything invalid, you reset things within the interrupt routine.
You have to think in terms on microseconds, a chip can do hundreds, if not thousands of instructions between each UART character. Your main program can then parse the RX buffer when it can, usually within the time frame before the next incoming string is complete and valid. After that point, the interrupt routine ignores all RX characters until the main program has processed the message and cleared the flags.
For example, I have an RX interrupt routine. looking for a string of characters. First I check OERR, FERR, and such at start of interrupt routine. First character has to be "FE", and so on, 5th character has to be a "03". End of message is "FD" If any of those requirements are not correct, I zero my pointers and wait for the proper message within the interrupt routine. Simple...
Now, I do something different in the main loop. Assume I have a valid RX buffer of 20 characters. Flags are set to show the length of message, and string is complete and correct format by the interrupt routine. Main program now detects valid message via those flags and I save the pointers/length into new variables, and start to copy the RX buffer into another buffer, a "working buffer" Since copying characters from buffer to buffer is so fast (<20uS at 8Mhz clock), I can simply transfer 5 or 10 characters and then reset the interrupt flags/pointers while I copy the rest of the working buffer. This way, I allow more messages to be received by the interrupt routine while I still work on the work buffer in the main program loop. This is perfectly safe, as it will take a whole millisecond (mS) before the interrupt routine will trigger again, and for one character only. Next character will take another whole 1mS. By then, I've saved the entire working buffer, and main program can take its time processing it. No interaction between RX interrupt routine and its RX buffer vs the main program loop and its "working buffer"
I know this can be overwhelming to some. You have to think in terms of microprocessor speeds, and your UART speeds (or other data). The micro can process so much data between UART characters, you just have to think like a microprocessor to get the timing right, and see that 1mS for a UART character is a very, very long time.
Thank you for that information. Prevously 'J' had shown me how to time the INTERRUPT in Oshonsoft and the answer is a you suggest app, 8uS.
The problem I'm having is when WRITING to the BUFFER, an increment VARIABLE is used, how do I increment through the BUFFER without affecting the next incoming DATA? So far I've been using the same VARIABLE, but I'm sure this isn't correct.
C