中级会员
- 积分
- 255
- 金钱
- 255
- 注册时间
- 2014-2-27
- 在线时间
- 67 小时
|
发表于 2020-7-16 13:07:18
|
显示全部楼层
感谢楼主的无私分享,经测试,发现问题,当一次性接收大于接收buff时,会出现接收数量锁死,全部数据异常,我把它修改成超过接收极限就清零,不知道为什么发生这样
我在中断增加限制最大值后,问题解决
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1_InitStructure.USARTx , USART_IT_IDLE) != RESET) //空闲中断
{
USART_ReceiveData(USART1_InitStructure.USARTx); //清除空闲中断标志
#if USART1_DMA==1
DMA_Cmd(USART1_InitStructure.USART_RX_DMA, DISABLE); //关闭DMA ,防止干扰
//注意,如果中断发送数据帧的速率很快,MCU来不及处理此次接收到的数据,中断又发来数据的话,这里不能开启,否则数据会被覆盖。有2种方式解决。
//1. 在重新开启接收DMA通道之前,将DMA_Rx_Buf缓冲区里面的数据复制到另外一个数组中,然后再开启DMA,然后马上处理复制出来的数据。
//2. 建立双缓冲,在DMA_Uart_DMA_Rx_Data函数中,重新配置DMA_MemoryBaseAddr 的缓冲区地址,那么下次接收到的数据就会保存到新的缓冲区中,不至于被覆盖。
//重新开始下一次接收前先把上一次接受的数据长度,和数据读出来
USART1_RX_STA = USART1_MAX_RX_LEN - DMA_GetCurrDataCounter(USART1_InitStructure.USART_RX_DMA); //获得接收到的字节数 如果不增加下面的限制,一次性发送超过600就会锁死600个
if (USART1_RX_STA >= USART1_MAX_RX_LEN)
{
USART1_RX_STA = 0;//避免接收到超过USART1_MAX_RX_LEN,
}
DMA_USART1_InitStructure.DMA_MemoryBaseAddr = (u32)USART1_RX_BUF;
DMA_Init(USART1_InitStructure.USART_RX_DMA, &DMA_USART1_InitStructure);
USART1_InitStructure.USART_RX_DMA->CNDTR = USART1_MAX_RX_LEN; // 重新赋值计数值,必须大于等于最大可能接收到的数据帧数目
DMA_Cmd(USART1_InitStructure.USART_RX_DMA, ENABLE); // DMA 开启,等待数据。
#endif
USART1_RX_BUF[USART1_RX_STA&0X7FFF]='\0'; //添加\0,防止字符串处理函数遇不见\0一直不结束
USART1_RX_STA|=0x8000; //标记接收完成了
//添加处理函数,最好主函数查询处理
}
if(USART_GetFlagStatus(USART1_InitStructure.USARTx,USART_FLAG_ORE) == SET) // 检查 ORE 标志,防止开关总中断死机,放在接收中断前面
{
USART_ClearFlag(USART1_InitStructure.USARTx,USART_FLAG_ORE);
USART_ReceiveData(USART1_InitStructure.USARTx);
}
#if USART1_DMA==0
if(USART_GetITStatus(USART1_InitStructure.USARTx, USART_IT_RXNE) != RESET)
{
u8 res = USART_ReceiveData(USART1_InitStructure.USARTx); //读取接收到的数据
if((USART1_RX_STA&0X7FFF)<USART1_MAX_RX_LEN-1) //超过数组长度的舍弃,空闲中断后处理数据前来的数据会继续接上
{
USART1_RX_BUF[USART1_RX_STA&0X7FFF]=res;
USART1_RX_STA++;
}
}
#endif
}
|
|