兆讯MH1902S-UART FIFO丢失数据问题分析
目前有一个项目,使用MH1902S-UART与蓝牙模块连接通讯。在使用的过程中,对蓝牙通讯做压力测试,
发现MH1902S-UART通讯时FIFO丢失数据,导致蓝牙通讯不稳定,现象是随机出现的,没有一定的规律。
压力测试方法:
手机与蓝牙模块配对连接后,手机发送64字节的随机数,MH1902S收到后回传收到的64字节,
手机收到后,与之前发送的数据进行比对,一致则继续发下一次的随机64字节,不一致则停止。
MH1902S-UART的配置情况:
115200 8个数据位 无奇偶校验位 1个停止位
FIFIO - Tx FIFO触发使能,Tx、Rx阀值均为1/4 FIFO,不使用DMA模式,使能FIFO
Rx - 开中断
Tx - 开中断
调试分析时,使能UART的Receiver Line Status Interrupt(ELSI)中断,出现问题时打印LSR的值为
0x63,
查找MH1902S芯片手册UART章节,确定Overrun error bit(过载错误标志位)置1,即:UART会预留先前FIFO
中接收的数据而丢弃当前接收的数据。
为什么会出现接收FIFO丢数据的情况呢?关闭调试时UART的Receiver Line Status Interrupt(ELSI)中
断,
再进一步分析发现,接收中断是可以产生的,只不过好像有点滞后,即:当接收FIFO中的数据达到Rx阀值
后,
MH1902S-UART并没有及时产生接收中断,从而不能及时取出FIFO中的数据。接收FIFO满后,后续的数据只
能
丢弃,导致蓝牙通讯不稳定。这可能是兆讯MH1902S芯片不稳定造成的原因。(没办法啦,国产的芯片,大
家
凑合着用吧!)
解决的办法:
要求在发送数据时,进行分包处理,即:发送时每个包的数据为16个字节(因为兆讯MH1902S-UART Tx/Rx
FIFO大小为16字节 ),不足16字节的按实际长度发送。这样的话,每个包的数据都会在FIFO中,从而
不会丢失数据。
MH1902S-UART的配置:
static int mh1902_uart_startup(struct bluetooth_device *port, unsigned int baudrate, unsigned
int parity)
{
UART_TypeDef * UART = (UART_TypeDef *)port->regaddr;
UART_InitTypeDef UART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
UART_FIFOInitTypeDef UART_FIFOInitStruct;
UART_InitStructure.UART_BaudRate = baudrate;
UART_InitStructure.UART_Parity = parity;
UART_InitStructure.UART_StopBits = UART_StopBits_1;
UART_InitStructure.UART_WordLength = UART_WordLength_8b;
UART_Init(UART, &UART_InitStructure);
/* FIFO */
UART_FIFOInitStruct.FIFO_TX_TriggerIntEnable = ENABLE;
UART_FIFOInitStruct.FIFO_DMA_Mode = UART_FIFO_DMA_Mode_0;
UART_FIFOInitStruct.FIFO_RX_Trigger = UART_FIFO_RX_Trigger_1_4_Full;
UART_FIFOInitStruct.FIFO_TX_Trigger = UART_FIFO_TX_Trigger_1_4_Full;
UART_FIFOInitStruct.FIFO_Enable = ENABLE;
UART_FIFOInit(UART, &UART_FIFOInitStruct);
NVIC_SetPriorityGrouping(NVIC_PriorityGroup_0);
NVIC_InitStructure.NVIC_IRQChannel = port->irqno;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
评论0