|
|
View previous topic :: View next topic |
Author |
Message |
Oliver Lai
Joined: 12 Dec 2003 Posts: 16
|
question of getc() |
Posted: Mon Apr 12, 2004 6:36 pm |
|
|
I have got a problem with getc() when I use RS3227 data output -----> RS232 data input.
It is often stuck on the third getc(), I check the manual, it wrote:
If a built-in USART is used the hardware can buffer 3 characters otherwise GETC must be active while the character is being received by the PIC.
Is the above reason why I got stuck on the third getc()? How can I solve this problem? How can I 'active' as the manual mentioned?
Thanks,
Oliver |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
Posted: Mon Apr 12, 2004 7:14 pm |
|
|
PIC can buffer two charcters. If it receives a third character before the software reads the previous one it will report an overrun error and stop receiving anymore data:
Quote: |
The RCREG is a double buffered register (i.e., it is a two deep FIFO). It is possible for two bytes of data to be received and transferred to the RCREG FIFO and a third byte to begin shifting to the RSR register. On the detection of the STOP bit of the third byte, if the RCREG register is still full, the overrun error bit OERR (RCSTA<1>) will beset. The word in the RSR will be lost. The RCREG register can be read twice to retrieve the two bytes in the FIFO. Overrun bit OERR has to be cleared in software.
This is done by resetting the receive logic (CREN is cleared and then set). If bit OERR is set, transfers from the RSR register to the RCREG register are inhibited, and no further data will be received. It is therefore, essential to clear error bit OERR if it is set. |
You may not be reading the data from the receive buffer fast enough. Check the OERR bit and see if it getting set. |
|
|
Oliver Guest
|
How to clean and set CREN |
Posted: Tue Apr 13, 2004 11:33 am |
|
|
Hi, Ali:
Thanks for your reply, it is really helpful!
Would you tell me how to cleared and set CREN with CCS compiler?
I want to try it.
Oliver |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
Re: How to clean and set CREN |
Posted: Tue Apr 13, 2004 11:47 am |
|
|
Oliver wrote: | Hi, Ali:
Thanks for your reply, it is really helpful!
Would you tell me how to cleared and set CREN with CCS compiler?
I want to try it.
Oliver |
Using the ERRORS option when declaring the serial port will cause the compiler to do this automaticly.
You can also access the OERR and FERR from the RS232_ERRORS byte. |
|
|
DragonPIC
Joined: 11 Nov 2003 Posts: 118
|
gets() |
Posted: Tue Apr 13, 2004 12:46 pm |
|
|
You could try using gets(). This will receive a string of characters until a RETURN is received. If this is not an option, try using some sort of handshaking to let the transmitter know the receiver is ready to receive another byte.
//transmitter
printf("a"); //or putc('a');
getc();
printf("b");
getc();
printf("c");
getc();
//receiver
char data;
data = getc();
printf("1");
do_something(data);
data = getc();
printf("1");
do_something(data);
data = getc();
printf("1");
do_something(data); |
|
|
Oliver Lai
Joined: 12 Dec 2003 Posts: 16
|
my source code |
Posted: Tue Apr 13, 2004 7:07 pm |
|
|
Thanks ALL for very helpful advices!
I have added ERROR option in my program, but still have got stuck. The transmiter side is out of my control, I can just received data stream, eg. 10 02 9D 03 45 56 78 91 F0 67 4D EB 10 03, totally 14 bytes, the first two 10 20 are start bytes, the next two 9D 03 are function bytes (9D 06 are another function for example), 10 03 are stop bytes.
Below is my code, it is quite simple:
Code: |
#include <18F452.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#include <input.c>
#include <lcd.c>
#include <readFloat64.c>
unsigned int dataArray[15], data1, data2, data3, data4;
int stop=1, i, j=0;
float flowRate;
void main() {
lcd_init();
while (stop) {
dataArray[0] = getc(); //sometimes it stuck here
if (dataArray[0] == 0x10) {
dataArray[1] = getc();
if (dataArray[1] = 0x02) {
for (i=2; i< 15; i++) //The most it stuck here
dataArray[i] = getc();
if (dataArray[2] == 0x9D && dataArray[3] == 0x03) {
data1 = dataArray[12];
data2 = dataArray[11];
data3 = dataArray[10];
data4 = dataArray[9];
flowRate = READ_FLOAT(data1, data2, data3, data4);
flowRate = 3600*flowRate;
if (j%10) {
lcd_gotoxy(1,1);
printf (LCD_PUTC, "FR: %12.8f", flowRate);
}
j++;
}
}
}
}
}
|
When starting to run the program, sometimes it can start immediately, sometimes have to be pressed RESET until it works. After the program works properly, it will be stucked in 2 minutes or longer.
By the way, from the transmitter it is RS3227, the receiver is SP232A (similar to MAX232).
The baud rate is 57600
Any advises and test suggestions to find why it stuck!
Thanks,
Oliver |
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Tue Apr 13, 2004 8:36 pm |
|
|
I would gess that it is hung on the LCD and not the serial port at all. If you have the printf statement changed to print a static value does it still hang? If you just print random values without the serial port involved does it still hang? |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Tue Apr 13, 2004 8:55 pm |
|
|
Quote: |
#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
|
Why do you make a UART hardware setup and then you never enable the interrupt
to handle it ?
Quote: |
I have added ERROR option in my program, but still have got stuck. The transmiter side is out of my control, I can just received data stream, eg. 10 02 9D 03 45 56 78 91 F0 67 4D EB 10 03, totally 14 bytes, the first two 10 20 are start bytes, the next two 9D 03 are function bytes (9D 06 are another function for example), 10 03 are stop bytes.
|
It will be easier to receive and store the stream in a buffer and then you will recover the data to analize it.
Code: |
// your packet
// DLE STX Dd Dd Dd Dd Dd Dd Dd Dd Dd Dd DLE ETX
//
#define Buffer_Size 14
#define Header STX
#define Trailer ETX
#INT_RDA
void isr_serial_rcv()
{
int char rcved;
char_rcved = getc();
if( !data_valid )
{
if( char_rcved == Header) // Start of mssge flag
{
next_in = 1;
dataArray[next_in] = char_rcved;
data_valid = TRUE;
}
}
else
{
next_in++;
if( next_in > Buffer_Size )
{
data_valid = FALSE; // Stop receiving
next_in = Buffer_Size;
}
if( char_rcved == Trailer ) // End of mssge flag
{
data_valid = FALSE;
}
if( !data_valid )
{
stream_complete = TRUE; // We get full mssge !!!
}
dataArray[next_in] = char_rcved;
}
}
//------------------------------------------------------------
//------------------------------------------------------------
void main()
{
stream_complete = FALSE;
data_valid = FALSE;
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
while()
{
// do other stuff ... while stream_complete == FALSE
if( stream_complete )
{
disable_interrupts(INT_RDA);
// Disable receiving further char while
// analising the received stream
if(( dataArray[2]==0x9D) && (dataArray[3]==0x03))
{
data1 = dataArray[12];
data2 = dataArray[11];
data3 = dataArray[10];
data4 = dataArray[9];
....................
// your code...
....................
}
enable_interrupts(INT_RDA);
}
}
}
//------------------------------------------------------------
//------------------------------------------------------------
|
Hope you understand the idea,
Humberto |
|
|
|
|
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
|