View previous topic :: View next topic |
Author |
Message |
tavioman
Joined: 22 Feb 2006 Posts: 65
|
RS232 Random garbage |
Posted: Sun Jul 22, 2007 8:48 am |
|
|
Hi again.
I have this weird problem.
I'm communicating with a GSM module.
I receive a weird character. Almost all the time this bad character is 4th in a string.
Example:
Code: | String that should be received:
41 54 23 4D 4F 4E 49 0D 0D 0A 45 52 52 4F 52 0D 0A
String received:
41 54 23 CD 4F 4E 49 0D 0D 0A 45 52 52 4F 52 0D 0A |
As you can see the 4th character wich is 0x4D becomes 0xCD.
I have noticed something interesting about this:
In binary
Code: | 4D = 01001101
CD = 11001101 |
Somethimes the character "0x0D" becomes "0x8D".
Code: | 0D = 00001101
8D = 10001101 |
It seems that there is one binary "1" added.
What could cause this kind of problem. Does anybody ever got into this? Really weird thing...
By the way, the routine I use to receive characters:
Code: |
char ReceiveBuffer[256];
int8 ReceiveCounter = 0;
#int_RDA
void RDA_isr( void ){
char buff = 0;
TMR0IF = false;
ProcessMessage = false;
disable_interrupts( INT_TIMER0 );
buff = fgetc( GSM );
ReceiveBuffer[ReceiveCounter] = buff;
ReceiveCounter++;
SET_TIMER1( 0 );
enable_interrupts( INT_TIMER0 );
} |
Another interesting thing is that I'm trying to mask the received character with 0b01111111:
Code: | ReceiveBuffer[ReceiveCounter] = ( buff & 0b01111111 ); |
The result is the same.
How could this be???
The print function:
Code: | int x = 0;
char c;
do{
c = ReceiveBuffer[x];
if( c == 0 )
break;
fputc( c, PC );
x++;
}while( c != 0 ); |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jul 22, 2007 10:35 am |
|
|
Quote: |
Another interesting thing is that I'm trying to mask the received character with 0b01111111:
Code:
ReceiveBuffer[ReceiveCounter] = ( buff & 0b01111111 );
The result is the same.
How could this be??? |
You are using a software UART to transmit chars to your PC.
If an interrupt occurs during a putc(), one of the bits will be stretched out.
This is probably what's happening. |
|
|
Ttelmah Guest
|
|
Posted: Sun Jul 22, 2007 10:40 am |
|
|
There is nothing obviously to cause this here, but some comments do apply.
First, presumably the timer is being used to handle a 'late' character?. Code: |
void RDA_isr( void ){
char buff = 0;
ProcessMessage = false;
buff = fgetc( GSM );
ReceiveBuffer[ReceiveCounter] = buff;
ReceiveCounter++;
SET_TIMER1( 0 );
//At this point the timer is reset, and hence the interrupt can't
//occur. If it has already occured since the start of the handler
//we clear it.
TMR0IF=false;
enable_interrupts( INT_TIMER0 );
}
|
The problem is that as originally posted, if the interrupt occurs after you clear it, and before the set_timer1, the flag will be set, and responded to immediately this handler is exited. Disabling a interrupt, does not stop it's flag being set, but stops the hardware response to the flag. Hence you need to first prevent the interrupt occuring, and then clear any existing triggers.
Separately, I'd do the printout differently, but only because it reduces the work the processor has to do (testing twice):
Code: |
while (c = ReceiveBuffer[x++]) {
fputc( c, PC );
}
|
Remember that anything 'non zero', is 'true'. Hence, this just assigns the character to c, testing it at the same time, and prints the character if it is non zero.
Now, looking back at the problem, though I'd have expected it to show on other characters, the normal 'reason', is a tiny timing error. What is your clock source?. What is the frequency?. What is your clock define?. What is your RS232 define?.
Best Wishes |
|
|
tavioman
Joined: 22 Feb 2006 Posts: 65
|
|
Posted: Sun Jul 22, 2007 11:51 pm |
|
|
Thanks.
I'm starting the timer after every received character since what I'm trying to do is t receive the full response from a GSM module.
I'll try out your solution.
Thanks again. |
|
|
tavioman
Joined: 22 Feb 2006 Posts: 65
|
|
Posted: Mon Jul 23, 2007 1:07 am |
|
|
PCM programmer wrote: | Quote: |
Another interesting thing is that I'm trying to mask the received character with 0b01111111:
Code:
ReceiveBuffer[ReceiveCounter] = ( buff & 0b01111111 );
The result is the same.
How could this be??? |
You are using a software UART to transmit chars to your PC.
If an interrupt occurs during a putc(), one of the bits will be stretched out.
This is probably what's happening. |
There is a problem.
You're right, I'm using software UART for transmitting chars to PC, but I have no interrupt source active when I'm transmitting.
I have made a debug and seen that the 4th char in the buffer allways gets an extra "1" at bit 7.
This is even when I'm doing the masking.
I don't know what to think. Why is always the 4th char? |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 23, 2007 1:26 am |
|
|
1. You need to answer all of the questions that Ttelmah asked at the end
of his last post.
2. How do you know that no interrupt source is active ? Have you disabled Global interrupts at the start of your fputc() loop and then
re-enabled them at the end ? Your posted code doesn't show that. |
|
|
tavioman
Joined: 22 Feb 2006 Posts: 65
|
|
Posted: Mon Jul 23, 2007 1:45 am |
|
|
Clock source XTAL 20MHz.
Fuse set to HS.
Code: | #use rs232( baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8, stream=GSM )
#use rs232( baud=9800,parity=N,xmit=PIN_A0,rcv=PIN_A1,bits=8, stream=PC ) |
I believe that there is some memory problem.
I'll try to malloc the buffer. The buffer size is 255. |
|
|
tavioman
Joined: 22 Feb 2006 Posts: 65
|
Problem solved -unexpected solution- |
Posted: Wed Jul 25, 2007 12:40 am |
|
|
Hi again.
I have solved the problem by replacing PIC18F4525 with a PIC18F452.
I don't know what was happening on 4535 but now all works fine. |
|
|
|