STM32CubeMX开发,解决串口DMA接受第一次接收不到数据
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Wekic/article/details/83040285
本次生成的串口:
使用芯片:STM32F215ZE
端口:USART3
波特率:115200
数据位:8位
校验 :无校验
第一次使用STM32CubeMX开发,本人觉得HAL库还是有些问题,本次开发搞那个串口就使用了我好多时间
本次遇到的问题:
1.串口使用CubeMX生成的工程有点问题,串口接受与发送有个互锁的问题,具体请看链接
使用链接的解决方法还是无法解决,15个数据1MS周期发送还是出现死机现象
2.上面的方法不能解决,然后我想到了串口使用DMA接受与发送加空闲中断,加快接受发送速度,全都是硬件自动完成具体生成过程请看链接STM32—cubeMX+DMA+USART 接收任意长度的数据
使用cubeMX+DMA+USART后,再也没有出现死机卡死的问题,但是第一次发送数据后无法产生空闲中断(这是我调试跟踪验证的),那这就意味这第一次数据是无法收到,我尝试过初始化是清除所有的标志,和发送数据清除标志位,但还是无法解决第一次无法收到数据问题
解决方法:
上面的问题困扰我蛮久的,最后我想到了了一个跳过开机第一次接收数据的空闲中断,方法也不难,就是开机时不使用空闲中断,接收的第一个数据是普通的中断,到第一个数据接收完成后,在回调函数里开启DMA空闲中断,这样就跳过开机第一次数据无空闲中断问题,下面我会贴一下我改的一些代码
放在main(void)初始化里
/* USER CODE BEGIN 2 */
// __HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);/*开启串口空闲中断*/
// HAL_UART_Receive_DMA(&huart3, Rx_tempBuff,BufferMax);//打开DMA接收,数据存入Rx_tempBuff数组中。
HAL_UART_Receive_IT(&huart3,&FirstRBuffer,1); //不开空闲中断,第一次接收数据
Usart3_Dat.Penetrate = 1; //透传模式 1 ; 命令提取模式 0
/* USER CODE END 2 */
stm32f2xx_it.c的中断函数
void USART3_IRQHandler(void)
{
/* USER CODE BEGIN USART3_IRQn 0 */
/* USER CODE END USART3_IRQn 0 */
HAL_UART_IRQHandler(&huart3);
/* USER CODE BEGIN USART3_IRQn 1 */
uint32_t temp;
u16 Ai = 0;
if((__HAL_UART_GET_FLAG(&huart3,UART_FLAG_IDLE)) != RESET)//获取IDLE标志位,检查idle标志是否被置位
{
__HAL_UART_CLEAR_IDLEFLAG(&huart3);//清除标志位
temp = huart3.Instance->SR; //清除状态寄存器SR,读取SR寄存器可以实现清除SR寄存器的功能
temp = huart3.Instance->DR; //读取数据寄存器中的数据
HAL_UART_DMAStop(&huart3); //
temp = hdma_usart3_rx.Instance->NDTR;// 获取DMA中未传输的数据个数,NDTR寄存器分析见下面
temp = BufferMax - temp; //总计数减去未传输的数据个数,得到已经接收的数据个数
for(Ai = 0; Ai <temp ;Ai++)
{
RingBuffWrite ( &Usart3_Dat, (u16)Rx_tempBuff[Ai]);
}
HAL_UART_Receive_DMA(&huart3, Rx_tempBuff,BufferMax);//打开DMA接收,数据存入rx_buffer数组中。(数组重新复位)
}
/* USER CODE END USART3_IRQn 1 */
}
修改一下串口的回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
UNUSED(huart);
// HAL_UART_Transmit(&huart3,(uint8_t*)RBuffer,1,0xFF);//(uint8_t*)aRxBuffer为字符串地址,10为字符串长度,0xFFFF为超时时间
//=====================
if(huart->Instance == USART3)
{
if(FirstDMA == 0) //第一次回调,转为DMA接收
{
FirstDMA ++;
RingBuffWrite ( &Usart3_Dat, (u16)FirstRBuffer); //接收数据,缓存到数组里
__HAL_UART_CLEAR_IDLEFLAG(&huart3); //清除标志位
__HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE);//使能idle中断
HAL_UART_Receive_DMA(&huart3, Rx_tempBuff, BufferMax); //打开DMA接收,数据存入rx_buffer数组中。
}
}
}
就写到这了,如有不足请指出
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇:支付对接- 微信,支付宝
- 下一篇:原生ajax代码