Question. The FIFO of the RCREG in the UART mode of the PIC is 2 bytes deep, right? So when I first start receiving data, and the program goes into the ISR for the first time because of the RCIE interrupt flag, and I read the RCREG once, this is not the byte that just arrived, right? I am asking because I am trying to receive 2 bytes at a time, the LS and the MS bytes of a certain number. But I keep getting weird results. The only way it worked was when I assigned the MS bit of each byte a certain value that I check when I read the RCREG in order to differentiate between the LS and MS bytes. Please help.
Let me clarify the weird things that I receive. Actually, I read the 2 bytes and output the MS on PORTB and the LS on PORTD so that they light LEDs. However, the weird thing that I cannot explain is that the LS bit of both is not changing (RB0 and RD0 don't go on), whereas the rest of the bits of both bytes are received correctly and are changing as expected. The data is sent by another PIC. The ISR responsible for reading the bytes is:
void interrupt (){
switch (i){
case 0: {datalow = RCREG; i = 1; break;}
case 1: {datahigh = RCREG; i = 0;}
}
The thing is you don't receive two bytes at a time, you receive one, then the other, your program should have sufficient time to process the first byte while the UART is receiving the next (the advantage of a hardware UART).
It sounds like you may have a speed issue?, with the receive routine not being quite the same as the transmit one, or perhaps a polarity problem, so the wrong bit is being considered the start bit?.
Post your full pic code please, the snippet above is too vague.
Are you sure you are sending the right format to the pic (nr of Databits, parity, nr of stop bits) ??
The FIFO of the RCREG in the UART mode of the PIC is 2 bytes deep, right? So when I first start receiving data, and the program goes into the ISR for the first time because of the RCIE interrupt flag, and I read the RCREG once, this is not the byte that just arrived, right?
Why wouldn't it be the byte that just arrived? If it weren't then RCIF is pointless, as it wouldn't allow sending just one byte. I've used receive interrupts and the byte it receives is indeed the byte that triggers the interrupt.
1 MAJOR error i can see is that variables wich are used in an interrupt routine AND in main code (datalow and datahigh for example) Should be declared volatile...
volatile unsigned short datalow;
volatile unsigned short datahigh;
Well I've tried everything. I have figured out the problem but can't find a solution yet! The problem is not in the least significant bit. I only thought so because the bytes being sent by my program are counting up in binary so it appeared that everything is ok except the LSB. What happens is that the program sends a byte, doesn't send the next one, then sends the next byte, then doesn't send the one after that, ...etc. So it appears as though the byte is increasing 2 at a time, and not 1 (makes sense?)
I got the same thing when I connected the PIC to the serial port of a PC and read the bytes sent by the PIC. I read a tutorial from Microchip. In the transmission section, they had a warning about this. They had an example in which the program appears to be sending the characters 'A' then 'B' then 'C'. But what is actually received on the other end is 'A' then 'C'. This is because the write register flag indicates that it is full one instruction late so the user shouldn't check it immediately after a write procedure but should add some NOPs.
Well I've added a delay of 200ms after each sending and before checking for the appropriate flags (PIR1.TXIF and TXSTA.TMRT) and still no difference. I really want to be able to send those bytes correctly without missing any data and without having to use the interrupt. Any suggestions? Thanks.