在 PIC32 上启用中断时,不等于运算符不工作

Not Equals Operator not working when interrupts are enabled on PIC32

我目前正在尝试通过 UART 接收中断协议解析通过 UART 从 PIC32MZ2048EFG100 微控制器上的 GPS 模块接收到的字符串。我正在为我的 IDE 和编译器使用 MPLAB X IDE v4.10 和 XC32 v2.05。

当我启用 UART4 接收中断时,!= 运算符停止正常运行。我的主函数中有一段代码永远不会执行,但它确实执行了。

我已将问题范围缩小到启用中断。如果我注释掉 ISR 中的所有工作代码,我仍然面临 myCounter 递增的问题。

这是我的主要功能中的代码。

int myCounter = 0;

void main ( void ){

    hal_sys_init();
    hal_uart4_init();
    gps_init();

    //Setup interrupt
    asm volatile("di"); //Disable all interrupts
    asm volatile("ehb"); //Disable all interrupts

    INTCON = 0; //Clear interrupt control register

    IEC0 = 0;
    IEC1 = 0;
    IEC2 = 0;
    IEC3 = 0;
    IEC4 = 0;
    IEC5 = 0;
    IEC6 = 0;

    INTCONbits.MVEC = 1; //Enable multi-vectored interrupts

    IFS5bits.U4RXIF = 0; //Clear interrupt flag
    IPC42bits.U4RXIP = 1; //Set priority level to 7
    IPC42bits.U4RXIS = 0; //Set sub-priority to 0
    IEC5bits.U4RXIE = 1; //Enable interrupt

    asm volatile("ei"); //Enable all interrupts

    while(1){
        int x = 0;
        if(x != 0){
            myCounter++;  //Should never be executed
        }
    }
}

当运行在启用中断的情况下在我的 PIC 上使用此代码时,myCounter 会递增。

这是我的中断服务例程的代码。

void __ISR(_UART4_RX_VECTOR, ipl7SRS) UART4_Interrupt(void) {
    while (U4STAbits.URXDA) {
        char c = U4RXREG;
        if (c == '\n') {
            currentLine[--lineIndex] = 0; //Overwrite /r as null terminator for string
            parseStringFlag = 1;
            lineIndex = 0;

            if (currentLine == buff_1) {
                currentLine = buff_2;
                previousLine = buff_1;
            } else {
                currentLine = buff_1;
                previousLine = buff_2;
            }

        } else if (lineIndex < MAX_LINE_LENGTH) {
            currentLine[lineIndex++] = c;
        } else {
            currentLine[--lineIndex] = c;
        }
    }
    IFS5bits.U4RXIF = 0; //Clear interrupt flag
    return;
}

这是仍然使 myCounter 递增的基本 ISR 代码。

void __ISR(_UART4_RX_VECTOR, ipl7SRS) UART4_Interrupt(void) {
    while (U4STAbits.URXDA) {
        char c = U4RXREG;
    }
    IFS5bits.U4RXIF = 0; //Clear interrupt flag
    return;
}

是什么导致了不应该执行的代码执行?如果我 运行 main 中的中断代码禁用了中断,则代码可以工作,并且不执行不应执行的代码。

这里:

    if (c == '\n') {
        currentLine[--lineIndex] = 0; //Overwrite /r as null terminator for string

如果收到的第一个字符是\n并且lineIndex初始化为零,lineIndex将从零开始递减。假设它是无符号的,那么 lineIndex < MAX_LINE_LENGTH 将为假并且:

    } else {
        currentLine[--lineIndex] = c;
    }

将 运行 重复,直到 lineIndex 最终减少到 MAX_LINE_LENGTH - 1 - 占用大量内存 - 这很可能是这种情况下发生的情况。

建议:

    if( lineIndex != 0 && c == '\n' && ) 
    {
        currentLine[--lineIndex] = 0; //Overwrite /r as null terminator for 

或:

    if( c == '\n' ) 
    {
        if( lineIndex != 0 ) 
        {
            lineindex-- ;
        }
        currentLine[lineIndex] = 0; //Overwrite /r as null terminator for 

取决于您需要的语义。发送系统对 line-ends 使用 CR+LF 对并不确定,您不应该这样假设。可能应该进一步修改代码以在递减 lineindex 之前检查前面的字符是否确实是 CR。 reader.

的练习

最后的 else 也类似:

    } 
    else if( lineIndex != 0 )
    {
        currentLine[--lineIndex] = c;
    }

    } 
    else
    {
        if( lineIndex != 0 ) 
        {
            lineindex-- ;
        }
        currentLine[lineIndex] = c;
    }

后一种保护可能不是必需的,但保护可能对清晰度和维护很有用 - 它是防御代码 - 你的决定。

让 ISR 简单地将任何接收到的字符放入 ring-buffer,然后在中断上下文之外处理 line-input 可能是一种更安全、更高效的中断设计。您可以在收到的每个 \n 上增加一个计数器,并在 \n 未缓冲时减少它,以便接收者知道当前有多少行被缓冲以进行处理。