View previous topic :: View next topic |
Author |
Message |
Chibouraska
Joined: 11 May 2007 Posts: 57 Location: Montreal,Canada
|
USART wait for character |
Posted: Thu Aug 13, 2009 3:59 pm |
|
|
Hi i would like to know what is a good way to wait for a certain character to arrive on the USART (in my case it's 0xFF). Is this a good way Code: | while (fgetc(UART2) != 0xFF) { } | but a would like to have a certain timeout period to wait, i guess if i include a variable that i increment and then with a IF statements exit the function if the variable reaches a certain amount. thanks! AC |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Aug 13, 2009 4:40 pm |
|
|
Quote: | would like to have a certain timeout period to wait |
If you need a feature, read the CCS manual to see if it's available.
Read the manual first, before posting a question.
Quote: |
Syntax: #use rs232 (options)
TIMEOUT=X
To set the time getc() waits for a byte in
milliseconds. If no character comes in within
this time the RS232_ERRORS is set to 0 as
well as the return value form getc(). This works
for both UART and non-UART ports. |
Link to manual:
http://www.ccsinfo.com/downloads/ccs_c_manual.pdf |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
|
Posted: Thu Aug 13, 2009 7:22 pm |
|
|
hint; have you wondered about the KBHIT() function ?
and what could possibly be done with it ?? |
|
|
Chibouraska
Joined: 11 May 2007 Posts: 57 Location: Montreal,Canada
|
|
Posted: Thu Aug 13, 2009 7:23 pm |
|
|
Ya i know i had a lot of frustration to spill out today.
Can i use this command >> #use rs232 (TIMEOUT=x) just before
i input data from the uart to set a timeout specific to this section of code, and then put another preprocessor #use rs... to define a different time out periods somewhere else. tks
AC
------------ |
|
|
Chibouraska
Joined: 11 May 2007 Posts: 57 Location: Montreal,Canada
|
|
Posted: Thu Aug 13, 2009 7:28 pm |
|
|
tks asmboy i'm very much at the beginning of my leaning curve with this compiler, but i like it :0 |
|
|
Ttelmah Guest
|
|
Posted: Fri Aug 14, 2009 2:32 am |
|
|
The 'nicest' way, is to use streams.
Code: |
//Processor defintion and clock etc., here
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,\
bits=8,STREAM=NORM,ERRORS)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,\
bits=8,TIMEOUT=250,STREAM=TIMED,ERRORS)
void main(void) {
int8 c;
//Initialisations etc.
//Then to read a character without timeout
c=fgetc(NORM);
//Then with timeout
do {
c=fgetc(TIMED);
if (RS232_ERRORS==0 && c==0) {
//Here you timed out - error processing.....
}
} while (c!=0xFF);
//Here you received a character
while(true);
}
|
If your 'timeout', wants to include the possibility of multiple 'wrong' characters coming, and not just 'no characters', then use the same base do..while loop, but also initialise a timer before starting. If the tmer flag gets set (to say the timer has timed out), have an exit/error handling routine.
Best Wishes |
|
|
Chibouraska
Joined: 11 May 2007 Posts: 57 Location: Montreal,Canada
|
|
Posted: Fri Aug 14, 2009 6:28 am |
|
|
Hi Ttelmah! Thanks i will do just that. |
|
|
ksp
Joined: 20 Jul 2007 Posts: 3
|
Timeout for Soft UART |
Posted: Fri Aug 14, 2009 12:59 pm |
|
|
Hi,
Does this TIMEOUT work for software uart ? |
|
|
Chibouraska
Joined: 11 May 2007 Posts: 57 Location: Montreal,Canada
|
|
Posted: Fri Aug 14, 2009 6:35 pm |
|
|
Yes it does |
|
|
neverlog
Joined: 02 May 2010 Posts: 36
|
|
Posted: Fri Jul 16, 2010 3:31 am |
|
|
Hi,
Does this timeout work with the sample file EX_SISR.c?
I have try a few time, the program will hang after sometime.
Can anyone help? Please.... |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Fri Jul 16, 2010 5:02 am |
|
|
With EX_SISR, it is up to _you_ whether to wait for a charcater.
Using interrupt driven receive, the actual receive code, is _only_ called, whan a character has already arrived. Hence no need for a 'timeout'.
In your code that looks at bkbhit, it is then up to you what you do if a character has not arrived in a time period. The EX_SISR example itself will just output it's 'Buffered data' message whether any characters have arrived or not. Making the precise point, that it doesn't need a timeout.
Now, things that are 'wrong' with EX_SISR, are:
1) Needs 'errors' in the RS232 definition - won't matter as it is meant to be used, with a human typing, but will if you start sending data at high rates.
2) Shouldn't use the modulus function in the interrupt. It works OK with the demo buffer size (or any binary multiple size 2,2,8,16,32 etc.), but with other sizes will cause problems.
3) If anything faster than human typing is involved, characters will be lost. 32 characters of buffer to handle 10 seconds.....
4) Again if higher speeds are involved, it is possible to run out of time to send the data (especially since 19 characters are being added to the output each time round the loop - won't cause a hang though, but just loss of data...)
If you are running at the standard 9600bps, and are actually getting this to 'hang', then I'm afraid you almost certainly have a fault with your hardware, and the hang is coming from something else (spike, brownout etc....).
Best Wishes |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
soem backup info would help |
Posted: Sun Jul 18, 2010 11:52 am |
|
|
- I have used a tweaked interrupt driven version serial handler with a buffer sized by modulo (%) math -for many even numbers that are not powers of 2 = admittedly - but at baud rates up to 260400 baud
and never had any issue or problem with buffer sizes of 48, 96 etc.
Always hardware driven never software based -
and this code is on the loose in the world - with no complaints about malfunction.
TTELMAH help me here - what is the problem you refer to
with non power of 2 buffersize ??? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Sun Jul 18, 2010 1:43 pm |
|
|
First, time.
The % function, on non binary buffer sizes, performs a division. 113 machine cycles minimum. If you instead simply perform a test, you can save over 100 machine cycles.
Second, the risk of interrupts being disabled. If an 8 bit integer division is used anywhere in the external maths, interrupts will be disabled for this. Unecessary....
It is badly written code for an interrupt.
Best Wishes |
|
|
asmboy
Joined: 20 Nov 2007 Posts: 2128 Location: albany ny
|
ok then |
Posted: Sun Jul 18, 2010 2:30 pm |
|
|
so if i read what you said correctly
for any size buffer of buf_size,
then of course with a buf_size of 255 bytes
we could even skip the new test line for
unsigned int 8 fill pointers
Code: |
#int_rda
void serial_isr() {
int t;
buffer[next_in]=getc(); // from UART Rx register
t=next_in;
// next_in=(next_in+1) % buf_size changed to
++next_in;
if (next_in==BUF_SIZE) next_in=0; // new test line
if(next_in==next_out) next_in=t; // Buffer full !!
}
|
better no?
as to ints -
whenever i use interrupt driven RS-232 RX, my habit is to not use
other int# driven functions if i can help it. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19537
|
|
Posted: Sun Jul 18, 2010 2:46 pm |
|
|
Yes.
Similar versions have been posted many dozens of times here.
The 'ints' part, is nothing to do with using other interrupts. The point is that code in the PIC, is not re-entrant. There is no 'data stack'. You _can_ write re-entrant code, but it is hard. Hence, since you can't call a function from inside itself, if you call a simple 8bit division _anywhere_ in the code outside the interrupt, the compiler will _automatically_ disable interrupts around this to avoid the one in the interrupt being called while inside this external division.... :(
If you try the simple expedient of compiling EX_SISR, then change the buffer size to a non binary value, you will get a compiler warning that "interrupts disabled during call to prevent re-entrancy (@Div88)". This now means that interrupts are being turned off for the block of code comprising the division in the external code. Doubles the potential performance cost.
Best Wishes |
|
|
|