OpenEdv-开源电子网

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

[其他模块] 阿波罗H743串口DMA接收及发送+空闲中断

[复制链接]

31

主题

2183

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
14287
金钱
14287
注册时间
2018-8-3
在线时间
1147 小时
发表于 2019-5-9 16:38:16 | 显示全部楼层 |阅读模式
定义两个BUF 一个用于接收:uint8_t rx_buffer[100];
                    一个用于发送:uint8_t tx_buffer[10] = {"ALIENTEK\r\n"};

然后就是配置DMA H7有个优点就是,STM32H7 的 DMA 配置更加灵活,无需固定通道对应固定外设请求,可以随意设置
[mw_shl_code=c,true]void MYDMA_Config(void)
{
        __HAL_RCC_DMA2_CLK_ENABLE();//DMA2时钟使能       
       
        HAL_NVIC_SetPriority(DMA2_Stream7_IRQn,0,0);
        HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
       
        HAL_NVIC_SetPriority(DMA2_Stream6_IRQn,0,0);
        HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
       
        //Tx DMA配置
        UART1TxDMA_Handler.Instance=DMA2_Stream7;                            //数据流选择
        UART1TxDMA_Handler.Init.Request=DMA_REQUEST_USART1_TX;                                //USART1发送DMA
        UART1TxDMA_Handler.Init.Direction=DMA_MEMORY_TO_PERIPH;             //存储器到外设
        UART1TxDMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE;                 //外设非增量模式
        UART1TxDMA_Handler.Init.MemInc=DMA_MINC_ENABLE;                     //存储器增量模式
        UART1TxDMA_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_BYTE;    //外设数据长度:8位
        UART1TxDMA_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_BYTE;       //存储器数据长度:8位
        UART1TxDMA_Handler.Init.Mode=DMA_NORMAL;                            //外设流控模式
        UART1TxDMA_Handler.Init.Priority=DMA_PRIORITY_MEDIUM;               //中等优先级
        UART1TxDMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;              
        UART1TxDMA_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;      
        UART1TxDMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE;                 //存储器突发单次传输
        UART1TxDMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;              //外设突发单次传输
        HAL_DMA_DeInit(&UART1TxDMA_Handler);   
        HAL_DMA_Init(&UART1TxDMA_Handler);
        __HAL_LINKDMA(&UART1_Handler,hdmatx,UART1TxDMA_Handler);    //将DMA与USART1联系起来(发送DMA)
       
        //Rx DMA配置
        UART1RxDMA_Handler.Instance=DMA2_Stream6;                            //数据流选择
        UART1RxDMA_Handler.Init.Request=DMA_REQUEST_USART1_RX;
        UART1RxDMA_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY;             //外设到存储器
        UART1RxDMA_Handler.Init.PeriphInc=DMA_PINC_DISABLE;                 //外设非增量模式
        UART1RxDMA_Handler.Init.MemInc=DMA_MINC_ENABLE;                     //存储器增量模式
        UART1RxDMA_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_BYTE;    //外设数据长度:8位
        UART1RxDMA_Handler.Init.MemDataAlignment=DMA_MDATAALIGN_BYTE;       //存储器数据长度:8位
        UART1RxDMA_Handler.Init.Mode=DMA_NORMAL;                            //外设流控模式
        UART1RxDMA_Handler.Init.Priority=DMA_PRIORITY_MEDIUM;               //中等优先级
        UART1RxDMA_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;              
        UART1RxDMA_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;      
        UART1RxDMA_Handler.Init.MemBurst=DMA_MBURST_SINGLE;                 //存储器突发单次传输
        UART1RxDMA_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE;              //外设突发单次传输
        HAL_DMA_DeInit(&UART1RxDMA_Handler);   
        HAL_DMA_Init(&UART1RxDMA_Handler);
        __HAL_LINKDMA(&UART1_Handler,hdmarx,UART1RxDMA_Handler);    //将DMA与USART1联系起来(接收DMA)
} [/mw_shl_code]


接下来是串口空闲中断部分代码:[mw_shl_code=c,true]                        tmp_flag =__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_IDLE); //获取IDLE标志位
                        if((tmp_flag != RESET))//idle标志被置位
                        {
                                recv_end_flag = 1;  // 接收完成标志置1
                                __HAL_UART_CLEAR_IDLEFLAG(&UART1_Handler);  //清除标志位
                                 HAL_UART_DMAStop(&UART1_Handler);                     //先停止DMA,暂停接收   
                                temp  =  __HAL_DMA_GET_COUNTER(&UART1RxDMA_Handler);// 获取DMA未传输个数                     
                                rx_len =  BUFFER_SIZE - temp; //总数减去未传输个数,得到已接收数据的个数
                                         
                                HAL_UART_Receive_DMA(&UART1_Handler,rx_buffer,BUFFER_SIZE);//重新打开DMA接收
                        }[/mw_shl_code]

当从串口调试助手网串口一发送数据时会进入空闲中断 之后将串口数据通过dma往前面定义的一个接收rx_buffer里效果如图:

6cd498d8f0f5612d6a6964eaf4e8878.png

H743-DMA串口收发 空闲中断.rar

29 MB, 下载次数: 1620

售价: 1 金钱  [记录]

啊哈~加油!!
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
15
金钱
15
注册时间
2022-9-2
在线时间
4 小时
发表于 2022-9-6 17:09:07 | 显示全部楼层
这个工程只能收到一帧数据,后面的数据能进中断,进不了接收buff
回复 支持 2 反对 0

使用道具 举报

0

主题

7

帖子

0

精华

新手上路

积分
43
金钱
43
注册时间
2018-4-17
在线时间
7 小时
发表于 2019-9-23 17:52:47 | 显示全部楼层
H743可以随便指定stream给外设,这样很方便,只需要明确请求channel就好了,那么可以把同一个stream分配给不同的外设吗?
回复 支持 反对

使用道具 举报

12

主题

40

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3097
金钱
3097
注册时间
2017-2-7
在线时间
384 小时
发表于 2019-12-26 10:53:11 | 显示全部楼层
您好,看了您的例程有几处不明白的地方想跟您请教。
问题一:
HAL_Init()中使用了HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);进行中断分组。
这样后面再使用
HAL_NVIC_EnableIRQ(USART1_IRQn);                                //使能USART1中断通道
HAL_NVIC_SetPriority(USART1_IRQn,3,3);                        //抢占优先级3,子优先级3
是不是不太合适呢?
这里子优先级不是只能设置为0吗?

问题二:
HAL_NVIC_SetPriority(DMA2_Stream7_IRQn,0,0);
HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
HAL_NVIC_SetPriority(DMA2_Stream6_IRQn,0,0);
HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
中断优先级设置都是0,0, 是必须这样设置吗?设置成其他的中断优先级可以吗?
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手上路

积分
33
金钱
33
注册时间
2019-9-30
在线时间
14 小时
发表于 2019-12-28 08:37:39 | 显示全部楼层
帮顶,刚好需要,已经下载,谢谢了老师
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
28
金钱
28
注册时间
2019-12-31
在线时间
4 小时
发表于 2019-12-31 15:01:47 | 显示全部楼层
刚好用上,谢谢分享
回复 支持 反对

使用道具 举报

1

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2014-12-14
在线时间
6 小时
发表于 2020-3-15 15:32:15 | 显示全部楼层
学习了
回复 支持 反对

使用道具 举报

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
195
金钱
195
注册时间
2019-10-15
在线时间
50 小时
发表于 2020-3-16 19:24:24 | 显示全部楼层
学习打卡
回复 支持 反对

使用道具 举报

3

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
195
金钱
195
注册时间
2019-10-15
在线时间
50 小时
发表于 2020-3-17 15:02:30 | 显示全部楼层
你好,身边只有F429的板子,有空正好调试了下,关于这个问题:
if(timer!=1)   /*由于开启空闲中断的时候会进入一次中断导致第一次会将recv_end_flag置一 触发DMA串口发送*/
main()函数中DMA接收在DMA初始化之前
void uart_init(u32 bound)
{
    HAL_UART_Receive_DMA(&UART1_Handler,rx_buffer,BUFFER_SIZE);       
}
这个在初始化 MYDMA_Config();之前。导致第一次DMA传输不正确?

在F4上是这样的,F7不清楚是不是这个原因



回复 支持 反对

使用道具 举报

31

主题

2183

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
14287
金钱
14287
注册时间
2018-8-3
在线时间
1147 小时
 楼主| 发表于 2020-3-18 16:19:01 | 显示全部楼层
明月寄温柔 发表于 2020-3-17 15:02
你好,身边只有F429的板子,有空正好调试了下,关于这个问题:
if(timer!=1)   /*由于开启空闲中断的时候 ...

  MYDMA_Config();                                //初始化DMA
        uart_init(115200);                        试下了把DMA的初始化  放前面还是有这个问题  不过还是谢谢你
啊哈~加油!!
回复 支持 反对

使用道具 举报

0

主题

6

帖子

0

精华

新手上路

积分
27
金钱
27
注册时间
2020-4-20
在线时间
8 小时
发表于 2021-8-5 11:36:56 | 显示全部楼层
感谢分享
回复 支持 反对

使用道具 举报

0

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2020-2-11
在线时间
24 小时
发表于 2021-9-23 19:48:45 | 显示全部楼层
请问一下这个程序只能接受一帧数据是怎么回事呢?
回复 支持 反对

使用道具 举报

16

主题

90

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
365
金钱
365
注册时间
2019-10-24
在线时间
152 小时
发表于 2021-12-18 09:35:15 | 显示全部楼层
请问,这个串口DMA接收数据,不开空闲中断(或者不开任何中断)接收数组里是不是也应该有数据呀
回复 支持 反对

使用道具 举报

31

主题

2183

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
14287
金钱
14287
注册时间
2018-8-3
在线时间
1147 小时
 楼主| 发表于 2021-12-18 11:31:03 | 显示全部楼层
PYC1 发表于 2021-12-18 09:35
请问,这个串口DMA接收数据,不开空闲中断(或者不开任何中断)接收数组里是不是也应该有数据呀

接受buf是自己定义的一个数组 你没去把串口DR寄存器的数据存放到buf里 怎么会有数据?不处理数据只会在DR寄存器
啊哈~加油!!
回复 支持 反对

使用道具 举报

16

主题

90

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
365
金钱
365
注册时间
2019-10-24
在线时间
152 小时
发表于 2021-12-18 11:35:51 | 显示全部楼层
我的意思是只开HAL_UART_Receive_DMA(&UART1_Handler,rx_buffer,100);接收DR中数据,但不开空闲中断,按照DMA功能,DR的数据会一直往rx_buffer里面填吗,还是一定要通过RX中断来处理接收数据(楼主,我表达清楚了吗
回复 支持 反对

使用道具 举报

16

主题

90

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
365
金钱
365
注册时间
2019-10-24
在线时间
152 小时
发表于 2021-12-18 11:39:13 | 显示全部楼层
因为,我在你的工程上把UART中断去掉确实rx_buffer没有数据,我个人理解空闲中断应该只是判断RX口没有在接收数据了,但跟DR->rx_buffer是没什么直接联系的,所以请教一下问题在哪(捂脸)
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-24 22:46

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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