OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2992|回复: 0

STM32 DMA空闲中断求助 缓存接收只有一帧数据

[复制链接]

3

主题

8

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2022-4-7
在线时间
5 小时
发表于 2023-5-24 17:50:49 | 显示全部楼层 |阅读模式
5金钱
当用DMA处理中断时,接收的字符数组rx_buffer如果用DMA_Usart_Send(rx_buffer, rx_len)发送,可以实现发什么回什么,但是加一个缓存数组memcpy(usart1_tx_buffer, rx_buffer, rx_len),用DMA_Usart_Send(usart1_tx_buffer, rx_len)发送后只有第一帧数据,后面只进入空闲中断但不发送,且debug时发现rx_buffer和usart1_tx_buffer地址对应的内存值相同,也就是说rx_buffer的值也不随着发送的改变而改变,但是是却能够被DMA_Usart_Send函数发送成正确的值,属实令人头大


voi USART1_IRQHandler(void)                       
{
       
#if SYSTEM_SUPPORT_OS                 //使用OS
        OSIntEnter();   
#endif
        uint32_t tmp_flag = 0;
        uint32_t temp;
        HAL_UART_IRQHandler(&UART1_Handler);

                if(USART1 == UART1_Handler.Instance)
                {
                        tmp_flag =__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_IDLE); //获取IDLE标志位
                        if((tmp_flag != RESET))//idle标志被置位
                        {
                                __HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);  //清除标志位
                                if(ins_flag == 1)
                                {
                                        HAL_UART_DMAStop(&UART1_Handler);                     //先停止DMA,暂停接收   
                                        temp  =  __HAL_DMA_GET_COUNTER(&UART1RxDMA_Handler);// 获取DMA未传输个数                     
                                        rx_len =  BUFFER_SIZE - temp; //总数减去未传输个数,得到已接收数据的个数
                                        ins_flag = 0;
                                        recv_end_flag = 1;  // 接收完成标志置1
                                }
                                HAL_UART_Receive_DMA(&UART1_Handler,rx_buffer,BUFFER_SIZE);//重新打开DMA接收
                                //memcpy(usart1_tx_buffer, rx_buffer, rx_len);
                        }
                       
                }
       
#if SYSTEM_SUPPORT_OS                 //使用OS
        OSIntExit();                                                                                           
#endif
}

while(1)
        {
                delay_ms(100);
                if(recv_end_flag == 1)   //接收完成标志
                {
                        if(timer!=1) /*由于开启空闲中断的时候会进入一次中断导致第一次会将recv_end_flag置一 触发DMA串口发送
                                                    这里加个简单的判断避免下,这种情况应该是H7的HAL底层处理问题导致 ,大家也可以找下问题在分享一下*/
                        {
                                memcpy(usart1_tx_buffer, rx_buffer, rx_len);
                                DMA_Usart_Send(usart1_tx_buffer, rx_len);
                                DMA_Usart_Send(rx_buffer, rx_len);
                                //HAL_UART_Transmit(&UART1_Handler,(uint8_t*)rx_buffer,rx_len,100);
                                rx_len = 0;//清除计数
                                recv_end_flag = 0;//解除结束计数标志位rx_buffer
//                                delay_ms(10);
                        }
                        else
                        {
                                recv_end_flag = 0;//解除结束计数标志位
                                timer++;
                        }
                }
                ins_flag = 1;
        }

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-24 11:37

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表