野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 11622|回复: 2

关于STM32CUBE 串口 DMA 问题请教

[复制链接]
发表于 2018-3-19 11:19:14 | 显示全部楼层 |阅读模式
1、关于DMA固定长度接收,只能接少于指定长度的数据,而且少于指定长度数据也不产生中断,满了才中断,如果固定收20个字符,另一边一次连续发送30个,就是会丢失10个,不知我理解的对不对,把固定长度设成比实际一次连续传输数据大是可以接收全数据的,我是新手,大家是怎么处理的?

看了关于不定长DMA空闲接收方式,下列程序段:

void UsartReceive_IDLE(UART_HandleTypeDef *huart)  
{  
    uint32_t temp;  

    if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))  
    {   
        __HAL_UART_CLEAR_IDLEFLAG(&huart1);  
        HAL_UART_DMAStop(&huart1);  
        temp = huart1.hdmarx->Instance->CNDTR;  
        UsartType.RX_Size =  RX_LEN - temp;   
        UsartType.RX_flag=1;  
        HAL_UART_Receive_DMA(&huart1,UsartType.RX_pData,RX_LEN);  
    }  
}  
这里的定义的Size赋给了DMA_SxNDTR。使能之后,只能读取,表示还有多少字节需要被“传送”。所以空闲中断里面
temp  = hdma_usart1_rx.Instance->CNDTR;  //读取还没有被传送的个数            
rx_len =  BUFFER_SIZE - temp;                    //DMA缓存大小减去没有被传送的个数,就等于已经被传送的个数,也就是接收到的个数。
所以感觉如果是DMA接收,即使外部过来的数据个数不等于设定的Size,那么数据也还是被接收到了指定的buffer中。

2、看了关于不定长DMA接收方式,测试也是可行,就是有点不理解的是,在串口中断接收完成后,最行一行代码,又开始立即接收,HAL_UART_Receive_DMA(&huart1,UsartType.RX_pData,RX_LEN),假设发送端传两段数据间隔很短,那么这边接收的数据还没开始处理,又被接收的数据给充掉了,有这可能吗?

回复

使用道具 举报

发表于 2018-3-19 11:23:18 | 显示全部楼层
for(;;)
        {
                now_cnt = DMA1_Channel5->CNDTR;
                if ((now_cnt != buffer_lenth) && (now_cnt == old_cnt))/* êÕμ½óDD§êy¾Y*/
                {
                        /* DMAxμÄ′«êä¼Ä′æÆ÷(DMA_CNDTRx)Ö»Äü DMA_CCRx μÄEN=0 ê±D′èë*/
                        DMA1_Channel5->CCR &= 0xfffe;                //ê§Äü
                        DMA1_Channel5->CNDTR = buffer_lenth;
                        DMA1_Channel5->CCR |= 0x0001;                        //ê1Äü
                        rec_byte = buffer_lenth - now_cnt;
                        //        #if DEBUG
                        dma_buffer[rec_byte] = '\0';
                        printf("rec_byte lenth is %d, data is %s\n",rec_byte,dma_buffer);
                       
                }
               
                old_cnt = now_cnt;

                vTaskDelay(20);
        }
我自己使用的,仅供参考
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-3-19 11:52:18 | 显示全部楼层
浪费 发表于 2018-3-19 11:23
for(;;)
        {
                now_cnt = DMA1_Channel5->CNDTR;

谢谢提供参考,刚开始用STM32CUBE生成,最开始接多少回发多少,如果少于指定数据,发现发上来很多空的数据,后来细看了确实now_cnt = DMA1_Channel5->CNDTR;判断来取出实际多少数据,再回传。
回复 支持 反对

使用道具 举报

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

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-24 04:39 , Processed in 0.025918 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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