View previous topic :: View next topic |
Author |
Message |
Nino
Joined: 27 Jan 2005 Posts: 4 Location: Milano Italy
|
pic 18f6621 uart receiver buffer |
Posted: Thu Jun 09, 2005 8:24 am |
|
|
Hello
Excuse me for bad english!
I've a problem whit USART2 of my pic; I've got the main function that must make some things, at the same time another device try to communicate with my pic in USART2.
I've wrote an int routine for take one caracter from usart2 when it's arrive but in a piece of program I must disable int_sda2 because the function must be atomic (without interruction).
If more than 2 caracter arrive into disabled time of interrupt the "getc" becomes insensible for all other caracters.
If I disable the "atomic function" all work correctly and if I haven't try to communicate all work but for my job together must run .
How can I solve this problem?
Thank's
Nino |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jun 09, 2005 1:58 pm |
|
|
Quote: | If more than 2 character arrive into disabled time of interrupt the "getc" becomes insensible for all other characters. |
The UART is locking up, due to a receiver overrun condition.
You can add the ERRORS parameter to your #use rs232() statement
to automatically clear the error. You will still lose the characters,
but the UART will not lock up. Example:
Code: | #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS) |
|
|
|
Nino
Joined: 27 Jan 2005 Posts: 4 Location: Milano Italy
|
|
Posted: Fri Jun 10, 2005 3:05 am |
|
|
I tryed but if I use ERRORS my program don't work correctly! I haven't understand why but I've got some problem with int1 routine if I enable ERRORS!
His behavior is like Uncertainty Principle of Heisenberg , if I watch what appened with printf on com1 port all work logical correctly but timing are wrong; if I remove printf program dont work ! |
|
|
Douglas Kennedy
Joined: 07 Sep 2003 Posts: 755 Location: Florida
|
|
Posted: Fri Jun 10, 2005 7:30 am |
|
|
The "Uncertainty Principle of Heisenberg" is a feature of the universe and can't be avoided. The issue you are having most likely can be avoided.
You could use buffers to save the inbound chars as soon as they arrive .
The interrupt service routines will do a getc a write to a buffer and update a pointer then return and nothing else ( especially dont use putc or printf in the service routine ). The main routine will in a loop examine the buffers. The extended buffers using PIC ram smooth the peak demand by having a place for inbound chars to live till you get to look at them. If the chars on average ( averaged over the buffer size) arrive faster than you can handle them then this is not "uncertainty" it is guaranteed not to work. However usually the PIC with a fast clock frequency and an appropriate baud rate will work well. |
|
|
Nino
Joined: 27 Jan 2005 Posts: 4 Location: Milano Italy
|
|
Posted: Mon Jun 13, 2005 4:01 am |
|
|
I tryed to made a light int routine but problem is the same! But why ERRORS didn't work correctly? Someone have an idea? |
|
|
Ttelmah Guest
|
|
Posted: Mon Jun 13, 2005 4:53 am |
|
|
Post your 'light' interrupt routine.
You should be using as your 'example' for this, the ex_sisr code. Notice that this _allways_ calls the getc, in the interrupt (this is vital when using 'ERRORS', since it is only 'invoked' when a character is actually fetched). What will your code actually do, when characters are missed?. Remember that if the other interrupt is long enough that characters are lost, these are gone for ever. Your receive code must be 'smart' enough to perform some form of error recovery whan data is lost.
Best Wishes |
|
|
Nino
Joined: 27 Jan 2005 Posts: 4 Location: Milano Italy
|
|
Posted: Mon Jun 13, 2005 6:38 am |
|
|
My USART initialisation:
#use delay(clock=4000000)
#use rs232(stream=com1, baud=9600, xmit=PIN_c6, rcv=PIN_c7,PARITY=N, BITS =8,ERRORS)
#use rs232(stream=com2, baud=9600, xmit=PIN_g1, rcv=PIN_g2,PARITY=N, BITS =8,ERRORS)
My heavy "routine":
#int_rda2
void riceve2(void)
{
ch2=fgetc(com2);
newchar2=1;
}
If I use ERRORS (into #use rs232..) program stop into this routine:
void ricevi(void)
{
enable_interrupts(INT_TIMER1);
while (conta<300);
disable_interrupts(INT_TIMER1);
}
with this int1 routine
#int_timer1
void step(void)
{
set_timer1(65435);
if (campionamento!=0)
massimi[conta]=read_adc();
conta++;
}
If I didn't use ERRORS all work good but when a caracter was received and the Pic was busy the receiver buf come in overrun condition.
Have you any idea?
Thank's Nino |
|
|
|