条件:STM32F205RC , 主频: 120MHz ,3路串口(USART1,USART2,USART3), 内部FLASH模拟EEPROM USART1收发 (中断接收,DMA2_Stream7发送) USART2 (中断接收, DMA1_Stream6发送) USART3(中断接收, DMA1_Stream3发送)。 1. 各个串口状态如下: 串口1 用于和PC交互,1秒一次对外输出信息字节在(50-100字节),接收指令. 串口2 1秒对外输出一串14字节数据,并且接收外设输入的数据(外部设备上电后自动对外输出数据)。 串口3 2秒对外输出一串13字节数据,并且接收外设输入的数据(外部设备为问答式,只有MCU发指令,才会应答17字节数据) 2. DMA发送中断中 清中断标志,关闭DMA,清除缓冲区(各自管理各自的DMA和缓冲区)。 3. 分时去调度和处理 三路串口的数据。 问题: PC每20秒发一次控制指令写EEPROM(97字节)。串口1,串口2均可以保持正常收发, 唯独串口3经常性的发生 DMA_Streamx->CR中发送被使能,但是 DMA_Streamx->NDTR为0的情况,DMA配置如下。 DMA_InitStructure.DMA_Channel = DMA_Channelx; //指定DMA的通道 DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)( &(USARTx->DR)); //设置外设接口地址 DMA_InitStructure.DMA_Memory0BaseAddr = 0; //设置内存地址 DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //DMA方向为 内存->外设 DMA_InitStructure.DMA_BufferSize = 0; //发送数据长度0 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不变 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址自动增加 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; //外设数据基础单元: 字节 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; //内存数据基础单元:字节 DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //DMA使用默认方式,不使用 循环模式 DMA_Mode_Circular DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA发送优先级 DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //不使用内部FIFO DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; 有过如下实验: 1. FLASH操作导致无法及时响应DMA的发送中断(中断中有关闭操作),导致DMA无法关闭。于是把串口3 DMA发送中断的抢占优先级降到最低,异常依然在串口3 DMA发送上。 2. 考虑调度时间问题,把周期拉长,问题依然在串口3 DMA发送上。 3. 交互的串口1对外波特率越高,串口3出现此问题的概率越低,串口1波特率降低,串口3出现此现象频率变高。 4. 交互指令只会对内部flash操作,没有任何指令发送到串口3上。 目前对串口3 加补丁可以处理这个异常,但是还没找到为什么异常总是在串口3的DMA上,还请大家帮忙一起分析下有什么地方值得怀疑的,谢谢! |
曾经有过手误,把中断1的字符写到中断2里面去,花了很多功夫才纠正过来
评分
查看全部评分
你说你加了补丁就解决了,具体怎么操作的?也给大家一些提示或提醒。
评分
查看全部评分
在mcu内部模拟eeprom的时候,比较频繁时擦写(自己写的算法只有flash写满才会擦除),会导致MCU丢中断的响应(这点可以理解)。 中断优先级就是默认
主要问题是:串口1,串口2 ,串口3 同样在工作,DMA进不了中断的现象总出在串口3上,其他两个串口却没有这个情况,很不理解。
打的补丁操作: 查询DMA CNDTR 和 CR寄存器,如果CR使能,但是 CNDTR =0 的情况,就把DMA关闭(中断中会关,由于中断丢失导致无法关闭,所以只能查询到符合条件主动关闭,不完全依赖于中断去关闭)