SCI0SR1_RFRD set 0 before I read SCI0DRL'value

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

SCI0SR1_RFRD set 0 before I read SCI0DRL'value

Jump to solution
1,585 Views
xianyu
Contributor II

UINT8

xReadCH376Data( void )  /* CH376读数据 */

{

 

INT8U ch;

    while(SCI0SR1_RDRF == 0) { /* Is the transmitter empty? */

    }

    ch=SCI0DRL;

   return ch;

}

 

void Init_SCI0(INT16U sci_ytpe)

{

 

    #ifdef Enable_SCI_Interrupt

       //SCI0BD = BUS_CLOCK/16/BAUD; //设置SCI0波特率为9600

       SCI0CR1 = 0x00; //设置SCI0为正常模式,八位数据位,无奇偶校验

       SCI0CR2 = 0x2c; //允许接收和发送数据,允许接收中断功能

    #else

       SCI0CR1 = 0x00;

       SCI0SR2 = 0x80; /* Switch to the alternative register set */         //SCI使用发射器禁用接收器

       SCI0ASR1 = 0x83; /* Clear alternative status flags */

       SCI0ACR1 = 0x00;

       SCI0ACR2 = 0x00;

       SCI0SR2 = 0x00; /* Switch to the normal register set */

       (void) SCI0SR1; /* Reset interrupt request flags */

       //SCI0CR2 = 0x0C; /* Disable error interrupts */

//定义波特率115200

       SCI0CR2 |= (SCI0CR2_TE_MASK | SCI0CR2_RE_MASK);

     

    #endif

   

    

 

    switch(sci_ytpe)

     {

      case InitBaud:

        SCI0BD = BUS_CLOCK/16/UART_INIT_BAUDRATE;

        break;

      case WorkBaud:

        SCI0BD = BUS_CLOCK/16/UART_WORK_BAUDRATE;

        break;

      default:

        break;

     }

 

this is my code,

when I debug my program I found when a data is coming, RDRF register will be set 1,and SCI0DRL's value is correct.

But,when I clicked single step,

the RDRF reset,become 0

It makes me cant read what is coming in xReadData and code will be run in a dead loop.

 

 

141636_141636.pngpastedImage_1.png141637_141637.pngpastedImage_2.png

Labels (1)
Tags (1)
0 Kudos
1 Solution
781 Views
RadekS
NXP Employee
NXP Employee

This is known debugging issue.

The problem is that RDRF flag is cleared by reading of SCISR register followed by reading SCIDR register.

When we stop MCU at start of interrupt routine by breakpoint, debugger will automatically read content of registers (and memory) and this way also clear RDRF flag.

Solution: You have to store SCISR register value to some variable at begin of interrupt routine and place breakpoint below this command. After that you could test that variable instead SCISR register for flags.

So, after reaching breakpoint, you could continue in stepping over code.

For example:

#pragma CODE_SEG NON_BANKED

interrupt 20 void SCI0_Isr(void)

{

//---------------

//prection against randomly flag clearing

unsigned char scisr1;

scisr1 = SCI0SR1;                          // save status register actual status

//---------------

//******************************************************************************

//Interrupt runtine RECEIVER part

//******************************************************************************

//if receiver interrupt is enabled and corresponding interrupt flag is set

if((SCI0CR2 & SCI0CR2_RIE_MASK) && ((scisr1 & (SCI0SR1_OR_MASK | SCI0SR1_RDRF_MASK))))

  {

    if(scisr1 & SCI0SR1_OR_MASK)            // if overrun error do nothing/something

      {

        (void)SCI0DRL;                            // clear interrupt flag

        // do something

      }

    else

      {

        //ninth_bit=SCI0DRH_R8;              //R8 is the ninth data bit received when the SCI is configured for 9-bit data format (M = 1).

        sc0_data_in = SCI0DRL;            // read received character + clear interrupt flag

        }

//…


I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

2 Replies
782 Views
RadekS
NXP Employee
NXP Employee

This is known debugging issue.

The problem is that RDRF flag is cleared by reading of SCISR register followed by reading SCIDR register.

When we stop MCU at start of interrupt routine by breakpoint, debugger will automatically read content of registers (and memory) and this way also clear RDRF flag.

Solution: You have to store SCISR register value to some variable at begin of interrupt routine and place breakpoint below this command. After that you could test that variable instead SCISR register for flags.

So, after reaching breakpoint, you could continue in stepping over code.

For example:

#pragma CODE_SEG NON_BANKED

interrupt 20 void SCI0_Isr(void)

{

//---------------

//prection against randomly flag clearing

unsigned char scisr1;

scisr1 = SCI0SR1;                          // save status register actual status

//---------------

//******************************************************************************

//Interrupt runtine RECEIVER part

//******************************************************************************

//if receiver interrupt is enabled and corresponding interrupt flag is set

if((SCI0CR2 & SCI0CR2_RIE_MASK) && ((scisr1 & (SCI0SR1_OR_MASK | SCI0SR1_RDRF_MASK))))

  {

    if(scisr1 & SCI0SR1_OR_MASK)            // if overrun error do nothing/something

      {

        (void)SCI0DRL;                            // clear interrupt flag

        // do something

      }

    else

      {

        //ninth_bit=SCI0DRH_R8;              //R8 is the ninth data bit received when the SCI is configured for 9-bit data format (M = 1).

        sc0_data_in = SCI0DRL;            // read received character + clear interrupt flag

        }

//…


I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

781 Views
xianyu
Contributor II

Does it means when I use debugger and click single step,the data1 window's change do read SCISR1 register. 

That operation makes RDRF register turn to 0 and Flag be cleared.

let me try to save SCISR1 register when the data come.

oh It's always you

thanks a lot

0 Kudos