View previous topic :: View next topic |
Author |
Message |
Leuzi Guest
|
Problems with serial reception on 16F877 |
Posted: Wed Nov 19, 2003 1:55 am |
|
|
Hi!
I've got a problem with receiving serial data with a pic16f877:
after a startbyte (0xAA) i want to read 4 bytes of data. the transmitter repeates this 5-byte-block all the time with a delay longer than one byte between each block. the transmitter is a 16f877 as well, but it works properly.
i've recognized that the receiver doesn't finish the while loop ('j' does never become 4) and isn't able to catch every startbyte (it kind of gets blocked after a startbyte for longer than four bytes).
that's the principal part of my code:
Code: |
#include "16F877.h"
//******* define clock frequency
#use delay (Clock=16000000) // clock frequency = 16MHz
main() {
long train_number;
int ser_in;
#use fast_io(C)
set_tris_C(0b10011000);
#use RS232(baud=4800, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8)
init_interrupts(); //interrupts SSP, TIMER1 and TIMER2 are enabled
output_bit(PIN_D0, gelb);//gelb, bei no CRC-error
output_bit(PIN_D1, rot);//rot, bei STX
while (true) {
if (kbhit()) {
ser_in = getch();
if (ser_in == 0xAA) // if input is a start byte (0xAA)
train_number = extract_data();
}
} // end while
} // end main
long extract_data(void) {
int block[];
int j = 0;
long number = 0xFF;
while (j < 4) {
if (kbhit()) {
block[j] = getch();
j = j+1;
}
}
if (calc_CRC(block) == 0) {
number = (((long)(block[0]) & 0x00FF)<<8) & 0xFF00;
number = number + block[1];
}
return number;
}
|
BTW: watchdog is disabled.
The results are the same with 2400 and 9600Bauds/s.
Thanks for help!!! |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Nov 19, 2003 6:56 am |
|
|
I didn't see anything that jumped out at me. I believe that you have probably cut out some portions of the code that are the root of your problems. You are probably experiencing overrun errors in the uart. Try adding "errors" to your #use rs232 statement. Also, the following code could be optimized by making use of one of CCS's functions
Code: |
if (calc_CRC(block) == 0) {
number = (((long)(block[0]) & 0x00FF)<<8) & 0xFF00;
number = number + block[1];
}
if (calc_CRC(block) == 0)
number = make16(block[0], block[1]);
|
|
|
|
Ttemah Guest
|
|
Posted: Wed Nov 19, 2003 7:38 am |
|
|
Mark wrote: | I didn't see anything that jumped out at me. I believe that you have probably cut out some portions of the code that are the root of your problems. You are probably experiencing overrun errors in the uart. Try adding "errors" to your #use rs232 statement. Also, the following code could be optimized by making use of one of CCS's functions
Code: |
if (calc_CRC(block) == 0) {
number = (((long)(block[0]) & 0x00FF)<<8) & 0xFF00;
number = number + block[1];
}
if (calc_CRC(block) == 0)
number = make16(block[0], block[1]);
|
|
One other thing 'leaps out' at me.
The declaration of the storage buffer 'block', does not reserve any space...
Best Wishes |
|
|
Leuzi Guest
|
|
Posted: Wed Nov 19, 2003 8:51 am |
|
|
Thanks for your help.
I still didn't find the mistake, so i solved the problem with the interrupt int_rda and it works (with the same functions)!
greez |
|
|
Ttelmah Guest
|
|
Posted: Thu Nov 20, 2003 3:19 am |
|
|
Leuzi wrote: | Thanks for your help.
I still didn't find the mistake, so i solved the problem with the interrupt int_rda and it works (with the same functions)!
greez |
And, I bet that when using the interrupt driven version, you use a static data buffer, with a size defined...
The problem with the old code, is that you are declaring an array with no size. C in general allows this, _but_ you are then required to ensure that the array is pointing at suitable storage. Since variable storage is by default assigned more or less sequentially, as soon as you write data to the array, you are corrupting the contents of the variables stored after it (j and number).
Best Wishes |
|
|
Guest
|
Re: Problems with serial reception on 16F877 |
Posted: Fri Jan 13, 2006 5:11 am |
|
|
Leuzi wrote: | Hi!
I've got a problem with receiving serial data with a pic16f877:
after a startbyte (0xAA) i want to read 4 bytes of data. the transmitter repeates this 5-byte-block all the time with a delay longer than one byte between each block. the transmitter is a 16f877 as well, but it works properly.
i've recognized that the receiver doesn't finish the while loop ('j' does never become 4) and isn't able to catch every startbyte (it kind of gets blocked after a startbyte for longer than four bytes).
that's the principal part of my code:
Code: |
#include "16F877.h"
//******* define clock frequency
#use delay (Clock=16000000) // clock frequency = 16MHz
main() {
long train_number;
int ser_in;
#use fast_io(C)
set_tris_C(0b10011000);
#use RS232(baud=4800, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8)
init_interrupts(); //interrupts SSP, TIMER1 and TIMER2 are enabled
output_bit(PIN_D0, gelb);//gelb, bei no CRC-error
output_bit(PIN_D1, rot);//rot, bei STX
while (true) {
if (kbhit()) {
ser_in = getch();
if (ser_in == 0xAA) // if input is a start byte (0xAA)
train_number = extract_data();
}
} // end while
} // end main
long extract_data(void) {
int block[];
int j = 0;
long number = 0xFF;
while (j < 4) {
if (kbhit()) {
block[j] = getch();
j = j+1;
}
}
if (calc_CRC(block) == 0) {
number = (((long)(block[0]) & 0x00FF)<<8) & 0xFF00;
number = number + block[1];
}
return number;
}
|
BTW: watchdog is disabled.
The results are the same with 2400 and 9600Bauds/s.
Thanks for help!!! |
|
|
|
nickwch
Joined: 10 Jan 2006 Posts: 1
|
|
Posted: Fri Jan 13, 2006 8:52 am |
|
|
Mark wrote: | I didn't see anything that jumped out at me. I believe that you have probably cut out some portions of the code that are the root of your problems. You are probably experiencing overrun errors in the uart. Try adding "errors" to your #use rs232 statement. Also, the following code could be optimized by making use of one of CCS's functions
Code: |
if (calc_CRC(block) == 0) {
number = (((long)(block[0]) & 0x00FF)<<8) & 0xFF00;
number = number + block[1];
}
if (calc_CRC(block) == 0)
number = make16(block[0], block[1]);
|
|
Hi,
Would like to know what is the effect of adding "errors" in #use rs232 staements? |
|
|
treitmey
Joined: 23 Jan 2004 Posts: 1094 Location: Appleton,WI USA
|
|
Posted: Fri Jan 13, 2006 9:15 am |
|
|
From the help file that you don't have or can't read yourself
Quote: | ERRORS= Used to cause the compiler to keep receive errors in the variable RS232_ERRORS and to reset errors when they occur.
|
Second part of sentence is the important part. It clears error bit. If you don't clear errors and you get an error you will hang at that point. I think most people don't even look at the error value put in the variable RS232_ERRORS. |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Fri Jan 13, 2006 10:29 am |
|
|
nickwch wrote: Quote: |
Would like to know what is the effect of adding "errors" in #use rs232 staements?
|
You should start a new topic with this question for two reasons:
1) It's out of the discussion followed in the thread.
2) The thread was 'pasted' by 'Guest' if you see the posted date:
Posted: Thu Nov 20, 2003 5:19 am
We would not respond to any 'full pasted thread' to stop this noises.
Humberto |
|
|
|