• AVR Freaks

Hot!UART1 interrupt READS off by 1

Author
fsonnichsen
Super Member
  • Total Posts : 330
  • Reward points : 0
  • Joined: 2009/08/13 11:00:11
  • Location: 0
  • Status: offline
2021/01/09 09:31:20 (permalink)
0

UART1 interrupt READS off by 1

IDE 5.3
XC 1.60
MCC 4.01
PIC24FJ128GA010
 
This should be simple--
1) wait on a receive interrupt to UART1
2) check the receive status--if it is FALSE write out a "$"
3) I the receive status is TRUE, receive the data, and write it
I have put all the code in the interrupt to make the attached simpler.
 
   The problem is this:
I type a character---- an "A"
    The first time through, I get a $. Even though the interrupt was set I get no data.??!!
Now I type a different character---- a "B"
    This time the UART1_IsRxReady shows data---but---it is the "A" from the prior time
Seems like I am always off by "1". 
 
Too much quarantine? Maybe just a bad day?
There is a zip of the code attached. My main.c is below
 
Any ideas appreciated
thanks
Fritz
=========================
#include "mcc_generated_files/system.h"
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/pin_manager.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define FCY 500000UL
#include <libpic30.h> //This must occur AFTER the FCY definition
void uart1_intp(void); //UART1 interrupt routine
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
int main(void)
{
SYSTEM_Initialize();
UART1_SetRxInterruptHandler(uart1_intp);
__delay_ms(100); //settle time for UART
while(1) { } //wait for UART1 interrupt
return(0);
} //end main
////////////////////////////////////////////////////////////////////////////////////////////////////
//UART1 interrupt routine
////////////////////////////////////////////////////////////////////////////////
void uart1_intp(void)
{//uart1 interrupt
uint8_t byte_in;

if( UART1_IsRxReady() ) //if data waits in the Q print it
{
byte_in = UART1_Read();
UART1_Write(byte_in);
}
else
{
UART1_Write('$'); //if no data write a $
}
} //end uart1_intp
 
 
 
post edited by fsonnichsen - 2021/01/09 09:32:35
#1

7 Replies Related Threads

    fsonnichsen
    Super Member
    • Total Posts : 330
    • Reward points : 0
    • Joined: 2009/08/13 11:00:11
    • Location: 0
    • Status: offline
    Re: UART1 interrupt READS off by 1 2021/01/19 10:46:01 (permalink)
    4 (1)
    For the benefit of others:
        This was addressed (but not fixed) by the support center.
    Looking at their code for uart1.c they call the user interrupt handler first, and THEN they set the "head" and "tail" on the stack for the UART1_Read. 
      They suggested I modify their code to do it the other way around preparing the stack BEFORE calling the user handler.
     
      Unless you want to modify their code (I never do):
    The workaround is to only set a flag in the handler indicating that the interrupt tripped, and then have your calling routine checking this flag to finish the  job with Uart reads. This way the interrupt code can finish setting up the stack first. As you retrieve the data this way you would push it on your own stack.
      Conventionally doing very little in the handler and then getting the heck outta there is the right way to go--but in the time it takes to call the user code, further interrupts could have happened flooding the user stack. Always a risk with serial IO.
       Maybe I am the last guy in the solar system still using serial iO?
     
    Thanks
    Fritz
    #2
    du00000001
    Just Some Member
    • Total Posts : 4114
    • Reward points : 0
    • Joined: 2016/05/03 13:52:42
    • Location: Germany
    • Status: offline
    Re: UART1 interrupt READS off by 1 2021/01/19 11:06:23 (permalink)
    0
    fsonnichsen
    Maybe I am the last guy in the solar system still using serial iO?

     
    Certainly not. Maybe the last guy in the universe having issues with using serial I/O.
    (No - it's not really difficult.)
    • Start with removing the __delay_ms(100) - a UART doesn't need a settling time!
    • Even with high(er) baud rates, there's usually enough time available for the ISR to read RXREG (and store the value read somewhere).
    • Maybe it's not the best idea to use the MCC-generated functions unaltered as these might generate too much overhead. (MCC is meant to help starting - not exactly to provide "production code".)
    • The rest: a bit of work. Nothing really difficult . . .

    PEBKAC / EBKAC / POBCAK / PICNIC (eventually see en.wikipedia.org)
    #3
    fsonnichsen
    Super Member
    • Total Posts : 330
    • Reward points : 0
    • Joined: 2009/08/13 11:00:11
    • Location: 0
    • Status: offline
    Re: UART1 interrupt READS off by 1 2021/01/19 11:48:02 (permalink)
    3 (1)
    Thanks.
       Don't forget that there is an "other end" to most serial constructs and the 100ms is to give the other side a change to set up. Now why they need settling time, i do not know--but they request this.
      Usually with one port I agree that time is not an issue unless I end up with stacked completing interrupts. I've gotten snagged with multiple ports however. I had some devices (not pic24) reading 9 ports and it got sticky.
      You are right about MCC--I was good with the old PLIBS, but Mchip stopped publishing documents etc. I always try to stay "generic" so I can hand things off easily.
      All that said I generally have brought up serial rather quickly with other processors but Mchip seems to be pretty clunky in this regard-it changes depending upon processor and should not require user workarounds.  I think their attitude is "No doc needed--just read the code". Jeeesh-I wish I could get away with this!
      Happy to see that the whole world has not gone USB yet. I have to do a lot of work with low power and serial along with its I2C and SPI breeds is pretty low power.
     
    cheers
    Fritz
     
    #4
    Jerry Messina
    Super Member
    • Total Posts : 666
    • Reward points : 0
    • Joined: 2003/11/07 12:35:12
    • Status: offline
    Re: UART1 interrupt READS off by 1 2021/01/19 11:58:36 (permalink)
    0
    I think you're just not using the routines the way they're intended.
     
    Get rid of your uart1_intp RxInterruptHandler and just put that code in your main 'while(1)' loop.
     
    #5
    fsonnichsen
    Super Member
    • Total Posts : 330
    • Reward points : 0
    • Joined: 2009/08/13 11:00:11
    • Location: 0
    • Status: offline
    Re: UART1 interrupt READS off by 1 2021/01/19 13:15:52 (permalink)
    0
    Jerry
      I think you are saying that the MCC code in uart.c is not to be called via the handler? Eg. to cut and paste it to the main routine?
     
    tnx
    fs
    #6
    Jerry Messina
    Super Member
    • Total Posts : 666
    • Reward points : 0
    • Joined: 2003/11/07 12:35:12
    • Status: offline
    Re: UART1 interrupt READS off by 1 2021/01/19 13:26:55 (permalink)
    0
    Yes, that's right. The MCC code is already handling the interrupt and buffering the data for you.
     
    All you want to do is in your main routine:
    - check and see if there's data available, and ...
    - if there is then get the buffered data
     
     
    #7
    fsonnichsen
    Super Member
    • Total Posts : 330
    • Reward points : 0
    • Joined: 2009/08/13 11:00:11
    • Location: 0
    • Status: offline
    Re: UART1 interrupt READS off by 1 2021/01/19 14:17:10 (permalink)
    0
    OK---yes--that is what I did. I only set a "got-data" flag in the interrupt. 
    Thanks for the feedback
    fs
    #8
    Jump to:
    © 2021 APG vNext Commercial Version 4.5