FRDM K82f uart中断仅发射约8次

时间:2018-02-02 13:23:54

标签: c arm embedded interrupt uart

我目前无法使用NXP FRDM K82f board使用MCUXpresso IDE使MCUXpresso SDK上的LPUART中断正常工作。

LPUART中断仅触发6-8次,之后再也不会。 此行为独立于代码中的当前位置。我通过在程序进入无限循环后很长时间发送第一批数据并在程序开始时(在lpuart中断初始化之后)发送它来测试它。两种情况都有相同的行为。

这是我的初始化例程和中断处理程序。

#include <stdint.h>
#include "fsl_lpuart.h"

#define OSCERCLK_SOURCE 2U
#define ESP_UART LPUART0
#define UART_IRQ LPUART0_IRQn
#define UART_RECEIVE_INTERRUPT LPUART0_IRQHandler
#define BUFFER_SIZE 2048

volatile uint8_t ringBuffer[BUFFER_SIZE] = {0x00};
volatile uint16_t rxIndex = 0;
volatile uint16_t txIndex = 0;


void init(uint32_t baudRate){
    lpuart_config_t config;
    CLOCK_SetLpuartClock(OSCERCLK_SOURCE);
    LPUART_GetDefaultConfig(&config);
    config.baudRate_Bps = baudRate;
    config.enableRx = true;
    config.enableTx = true;
    uint32_t clockFrequency = CLOCK_GetFreq(kCLOCK_Osc0ErClk);
    LPUART_Init(ESP_UART, &config, clockFrequency);
    LPUART_EnableInterrupts(ESP_UART, kLPUART_RxDataRegFullInterruptEnable);
    EnableIRQ(UART_IRQ);
}

void UART_RECEIVE_INTERRUPT(void){
    uint8_t data;
    uint32_t flags = kLPUART_RxDataRegFullFlag & LPUART_GetStatusFlags(ESP_UART);
    if (flags){
        data = LPUART_ReadByte(ESP_UART);
        if((rxIndex + 1) % BUFFER_SIZE != txIndex){
            ringBuffer[rxIndex] = data;
            rxIndex++;
            rxIndex %= BUFFER_SIZE;
        }
    }
}

是否有人遇到类似行为并能够提供帮助?

编辑: 正如@Lundin建议我更正了非标准的gcc语法。 还没有成功,但我能够跟踪当ISR不再发射时设置的标志。 设置标志是:

kLPUART_TxDataRegEmptyFlag, 
kLPUART_IdleLineFlag, 
kLPUART_RxOverrunFlag, 
kLPUART_RxFifoEmptyFlag

这对我来说看起来很模糊,因为RX FIFO为空并且RX溢出。

2 个答案:

答案 0 :(得分:2)

您需要弄清楚的第一件事就是使用FIFO,或者只是处理单字符接收数据寄存器。如果你没有使用FIFO,那么FIFO标志是无关紧要的,它显示为空是不足为奇的。

关于超限标志,程序员的手册不出所料解释:

  

接收器超限标志

     

当软件无法防止接收数据寄存器溢出数据时,设置OR。 OR位是   在完全接收到溢出缓冲区的数据字的停止位之后立即置位   并且阻止设置所有其他错误标志(FE,NF和PF)。移位寄存器中的数据是   丢失,但LPUART数据寄存器中已有的数据不受影响....

这表明,在过去的某个时刻,您在覆盖之前未能声明数据,设置超限标志的可能性很小。但是,如果您对原始接收数据中断的响应延迟,则可以在不了解问题的情况下读取原始数据。但是,如果你这样做了,并且打开了超限标志,这将是你收到的最后一个数据。

您似乎至少需要做三件事:

  1. 完全实现或完全忽略可选的FIFO模式

  2. 检查溢出标志,清除它以查看它是否有所不同,但也找到一种方法来指示(设置粘性易失性软件标志,在一次触发模式下切换由示波器监视的GPIO,无论如何)表示发生了问题,以便您可以采取措施进行调查。

  3. 分析并测试整个程序的设计故障,这可能导致无法快速响应串行数据。这可能包括切换ISR中的GPIO并观察范围内的串行数据线,将定时器检查放入代码,以及审核所有其他必须禁用中断的ISR和前台选项。同时尝试剥离你的程序,直到你只需要接收和回声字符并试验​​它,在终端程序中一次按键一次,并让程序以保持串行线100%繁忙的速率注入字符串

  4. 还要记住,虽然断点调试可以非常强大,但是任何必须响应外部事件的程序,很可能在第一次遇到断点后操作将不再正常,因此接近这样一个问题,你经常需要设计在断点被击中时结束的测试,并且只分析截至该点收集的状态。有时这意味着你需要一个&#34; if&#34;条件,以便你可以在其中放置一个断点。

答案 1 :(得分:0)

问题很可能与Receiver Overrun标志有关。如处理器参考手册中所述,设置溢出标志后,即使有足够的空间,也没有更多的新数据到达接收器缓冲区/ FIFO。

不要忘记,即使您不调用LPUART_ReadByte()函数,输入到UART端口的字符也已保存到UART缓冲区中,并且在您调用ReadByte之后,它会首先读取之前输入的字符。如果您过量使用UART端口并填充其缓冲区,它将设置Overrun标志,并拒绝从该端口获取更多输入字符。

您应该做的是,无论如何都要清除Overrun标志。最好检查溢出标志,如果已设置,请手动将其清除。

if(kLPUART_RxOverrunFlag & LPUART_GetStatusFlags(ESP_UART))
{LPUART_ClearStatusFlags(ESP_UART,kLPUART_RxOverrunFlag);}

您可以在要从UART读取数据之前检查此标志并将其清除。