|
|
View previous topic :: View next topic |
Author |
Message |
Loio
Joined: 22 Apr 2014 Posts: 3
|
PIC24 RS232 Multiple byte read problem |
Posted: Tue Apr 22, 2014 2:03 am |
|
|
Hi,
I am working with PIC24EP512GP806. I am trying to use UART of this PIC.
I have no problem with this code. I can read correct values from my computer.
Working correct code:
Code: |
#include <24EP512GP806.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOJTAG //JTAG disabled
#device ICSP=3
#use delay(crystal=16000000)
#pin_select U1TX=PIN_G6
#pin_select U1RX=PIN_G8
#use rs232(UART1, baud=9600, stream=UART_PORT1)
void main()
{
int8 serialData[15];
int8 k=0;
while(true)
{
if(kbhit() )
{
putc(getc());
}
}
}
|
However when I try to read multiple bytes (8 byte in code), It reads first byte always as 0xFF and shifts other bytes.
Here is the code,
Code: |
#include <24EP512GP806.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOJTAG //JTAG disabled
#device ICSP=3
#use delay(crystal=16000000)
#pin_select U1TX=PIN_G6
#pin_select U1RX=PIN_G8
#use rs232(UART1, baud=9600, stream=UART_PORT1)
void main()
{
int8 serialData[15];
int8 k=0;
while(true)
{
if(kbhit() )
{
for(k=0;k<8;k++)
{
serialData[k]=getc();
}
for(k=0;k<8;k++)
{
printf("%X",serialData[k]);
}
}
}
}
|
And here is the sent and received values(hex).
1st Pack sent: 00 11 22 33 44 55 66 77
1st Pack Rec: FF 00 11 22 33 44 55 66
2nd pack sent: 00 11 22 33 44 55 66 77
2nd pack rec: 77 00 11 22 33 44 55 66
3rd pack sent: 00 11 22 33 44 55 66 77
2nd pack rec: 77 00 11 22 33 44 55 66
And I changed sent pack ;
4th pack sent: A0 A1 A2 A3 A4 A5 A6 A7
4th pack rec: 77 A0 A1 A2 A3 A4 A5 A6
5th pack sent: A0 A1 A2 A3 A4 A5 A6 A7
5th pack Rec: A7 A0 A1 A2 A3 A4 A5 A6
6th pack sent: A0 A1 A2 A3 A4 A5 A6 A7
6th pack Rec: A7 A0 A1 A2 A3 A4 A5 A6
I tought it maybe because of kbhit. I tried code below but result were same, always there is 0xFF as first byte and shifts others.
Code: |
//if(kbhit() )
{
for(k=0;k<8;k++)
{
serialData[k]=getc();
}
for(k=0;k<8;k++)
{
printf("%X",serialData[k]);
}
|
I think its a buffer problem. I tried to clear buffer before read data as in the code below. But no luck.
Code: |
#include <24EP512GP806.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOJTAG //JTAG disabled
#device ICSP=3
#use delay(crystal=16000000)
#pin_select U1TX=PIN_G6
#pin_select U1RX=PIN_G8
#use rs232(UART1, baud=9600, stream=UART_PORT1)
#byte U1STA=0x0222
void main()
{
int8 serialData[15];
int8 k=0;
while(true)
{
bit_clear(U1STA,1);
{
for(k=0;k<8;k++)
{
serialData[k]=getc();
}
for(k=0;k<8;k++)
{
printf("%X",serialData[k]);
}
}
}
}
|
Seems I am missing somethnig or I dont know thing
that causes this problem.
Can you help me to solve this problem? Have you faced such problem?
Thanks |
|
|
Loio
Joined: 22 Apr 2014 Posts: 3
|
|
Posted: Tue Apr 22, 2014 2:30 am |
|
|
I forget to add compiler version,
I use PCD v5.023 |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19480
|
|
Posted: Tue Apr 22, 2014 2:55 am |
|
|
Let the RX line have time to go high _before_ you start trying to receive.
So:
Code: |
#include <24EP512GP806.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOJTAG //JTAG disabled
#device ICSP=3
#use delay(crystal=16000000)
#pin_select U1TX=PIN_G6
#pin_select U1RX=PIN_G8
#use rs232(UART1, baud=9600, stream=UART_PORT1, NOINIT)
void main()
{
int8 serialData[15];
int8 k=0;
delay_ms(20); //Allow time for the input to settle
setup_uart(9600); //actually wake the UART
while(true)
{
if(kbhit() ) //only actually means there is one character...
{
for(k=0;k<8;k++)
{
serialData[k]=getc();
}
for(k=0;k<8;k++)
{
printf("%X",serialData[k]);
}
}
}
}
|
It looks like the classic problem where a MAX232, takes a little time to raise it's output line after starting. With your code as written (since there is nothing to mark the end of a packet etc..), it you start out of sync, you will stay out of sync forever. It sees the momentary 'low' as the start of a character, so receives a 0xff, from this.
As a comment, kbhit being 'true' implies one character is available. As written the code will then stall waiting for seven more characters to arrive... |
|
|
Loio
Joined: 22 Apr 2014 Posts: 3
|
|
Posted: Thu Apr 24, 2014 1:57 am |
|
|
Thanks Ttelmah, it solved my problem.
By the way, I dont use MAX232, I use FT232, also I tried Bluetooth-Rs232 Converter.
Thanks for your comment, Let me explain what I am plannig
I wanted to use kbhit instead of RS232 interrupt. PIC will have very short time loop in program and will check RS232 data always. When get 1sr char, will get other 7 ones too.
I will get rest of bytes with "timed getc()" function.
I will have Start and Stop bytes to check data pack.
Is it the Sync what you mentioned about, or is it somethnig other?
Thanks again Ttelmah
Thanks again |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19480
|
|
Posted: Thu Apr 24, 2014 2:23 am |
|
|
Seriously, 9600bps, implies characters arrive about 1/mSec. Your PIC can execute 8000 instructions between characters. For 8 characters, about 58000 instructions before they all arrive....
Not a 'very short time' at all.... |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1342
|
|
Posted: Thu Apr 24, 2014 6:23 am |
|
|
Just wanted to echo something Ttelmah mentioned. You use kbhit to see if a character is ready, but then read all 8 chars without re checking kbhit for each one. This is dangerous. In the event all 8 characters don't make it through, your code will hang until all 8 characters come, which might be the first byte(s) from your next block of 8. If it does that, you'll have accidentally split your block between 2 processing sessions, and that is probably the best case issue you'll run into. Depending on how the rest of your code works (I'm not sure how your processing loop works), you could hang forever. |
|
|
bkamen
Joined: 07 Jan 2004 Posts: 1611 Location: Central Illinois, USA
|
|
Posted: Thu Apr 24, 2014 9:41 am |
|
|
If you really want to do it right,
Write an ISR that handles incoming serial data into a FIFO.
Interrupts are your friend.
-Ben _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
|
|
|
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
|