OpenEdv-开源电子网

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

STM32F103 STM32F407 串口 usart1 usart2 usart3的dma收发

[复制链接]

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2018-6-27 18:12:38 | 显示全部楼层 |阅读模式
本帖最后由 nashui_sx 于 2020-12-10 10:39 编辑

介绍:
0:例子是STM32F103C8T6 STM32F407ZGT6
1:usartx.h 里面分别有个 USARTx_DMA宏,用来是否开启这个串口的dma
2:哪个串口使用printf  在sys.c  里面的#define  printf_usartx   USART1  定义 默认是串口1可以用printf
3:每个串口都分别可以使用USARTx_printf  格式化输出 内部代码已经用宏区别是否用dma发送
4:串口1 会与spi2 dma冲突  串口3会与spi1 dma 冲突
5:dma发送冲突时用死等标志量完成,发送太快第二次发送就会死等Tx_flag忙标志量,cpu干不了别的事,上系统可以干别的事
6.  开启dma就不要用printf了,用USARTx_printf,printf不受dma控制,需要自己增加控制代码
简单测试可靠性
1.jpg

f407串口1 2 3 dma和普通切换.rar

585.13 KB, 下载次数: 1168

f103串口1 2 3 dma和普通切换.rar

316.07 KB, 下载次数: 894

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

使用道具 举报

7

主题

200

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1279
金钱
1279
注册时间
2017-7-18
在线时间
257 小时
发表于 2018-7-5 12:49:51 | 显示全部楼层
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
13
金钱
13
注册时间
2018-7-5
在线时间
0 小时
发表于 2018-7-5 23:29:36 | 显示全部楼层
多谢~~~~~~~~~~
回复 支持 反对

使用道具 举报

160

主题

966

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2095
金钱
2095
注册时间
2014-3-7
在线时间
490 小时
发表于 2018-7-16 09:11:43 | 显示全部楼层
您所罗列的是存在的问题?
回复 支持 反对

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
 楼主| 发表于 2018-7-16 10:00:48 | 显示全部楼层
ssssssssssss 发表于 2018-7-16 09:11
您所罗列的是存在的问题?

是主要功能介绍
回复 支持 反对

使用道具 举报

0

主题

11

帖子

0

精华

初级会员

Rank: 2

积分
82
金钱
82
注册时间
2014-4-6
在线时间
22 小时
发表于 2019-6-6 22:00:06 | 显示全部楼层
有三个串口  例程了,我正好需要先谢了,  还有《串口3会与spi1 dma 冲突》  我的硬件已经做好了,可以用编程方法来规避冲突?
回复 支持 反对

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-6-6 22:21:02 | 显示全部楼层
本帖最后由 nashui_sx 于 2019-6-6 22:22 编辑
scybyq 发表于 2019-6-6 22:00
有三个串口  例程了,我正好需要先谢了,  还有《串口3会与spi1 dma 冲突》  我的硬件已经做好了,可以用编 ...

通道冲突不能,具体能不能分时复用,看本事了估计
串口3 和spi1 同一时刻只能有一个用dma
DMA1.png



回复 支持 反对

使用道具 举报

0

主题

17

帖子

0

精华

初级会员

Rank: 2

积分
102
金钱
102
注册时间
2019-3-5
在线时间
14 小时
发表于 2019-8-4 15:20:50 | 显示全部楼层
感谢分享
回复 支持 反对

使用道具 举报

0

主题

5

帖子

0

精华

新手入门

积分
14
金钱
14
注册时间
2019-9-4
在线时间
1 小时
发表于 2019-9-8 07:19:01 | 显示全部楼层
谢谢,学习中。。。。。
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
2
金钱
2
注册时间
2019-12-25
在线时间
0 小时
发表于 2019-12-25 12:27:46 | 显示全部楼层
GAN XIE
回复 支持 反对

使用道具 举报

0

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2019-12-20
在线时间
22 小时
发表于 2019-12-30 16:37:36 | 显示全部楼层
谢谢分享
回复 支持 反对

使用道具 举报

0

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
101
金钱
101
注册时间
2019-7-23
在线时间
39 小时
发表于 2020-1-1 19:04:21 | 显示全部楼层
学习!!!!!!!!!!!!!!!!!!
回复 支持 反对

使用道具 举报

16

主题

72

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
212
金钱
212
注册时间
2019-4-27
在线时间
44 小时
发表于 2020-1-3 13:31:06 | 显示全部楼层
感谢。。。。。。。。。。
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
7
金钱
7
注册时间
2020-3-2
在线时间
1 小时
发表于 2020-3-2 23:43:44 | 显示全部楼层
真的不错,感谢奉献。
回复 支持 反对

使用道具 举报

1

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
103
金钱
103
注册时间
2019-7-26
在线时间
18 小时
发表于 2020-6-23 08:55:49 | 显示全部楼层
感谢分享,正在学习
回复 支持 反对

使用道具 举报

8

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
163
金钱
163
注册时间
2018-4-8
在线时间
26 小时
发表于 2020-7-15 10:02:05 | 显示全部楼层
非常感谢,正好需要参考。
回复 支持 反对

使用道具 举报

8

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
163
金钱
163
注册时间
2018-4-8
在线时间
26 小时
发表于 2020-7-15 10:12:45 | 显示全部楼层
楼主你好,问个问题,我看到在主函数里面有2个while(1)无限循环函数,在进入主函数的时候系统自动就会无限循环第一个while(1),我没有看到break,那它是怎么跳到第二个while(1),还是说这只是演示,随便我们用哪个while(1)都可以,只要注释掉另一个就好。
微信截图_20200715100840.png
回复 支持 反对

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2020-7-15 11:45:36 | 显示全部楼层
zhczlzhang 发表于 2020-7-15 10:12
楼主你好,问个问题,我看到在主函数里面有2个while(1)无限循环函数,在进入主函数的时候系统自动就会无 ...

用下面的上面你的改while(0)就好了,下面是个标准模板的代码 没注释
回复 支持 反对

使用道具 举报

5

主题

19

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
255
金钱
255
注册时间
2014-2-27
在线时间
67 小时
发表于 2020-7-16 13:07:18 | 显示全部楼层
感谢楼主的无私分享,经测试,发现问题,当一次性接收大于接收buff时,会出现接收数量锁死,全部数据异常,我把它修改成超过接收极限就清零,不知道为什么发生这样
我在中断增加限制最大值后,问题解决
void USART1_IRQHandler(void)
{
        if(USART_GetITStatus(USART1_InitStructure.USARTx , USART_IT_IDLE) != RESET)  //空闲中断
        {
                USART_ReceiveData(USART1_InitStructure.USARTx);                          //清除空闲中断标志
#if USART1_DMA==1
                DMA_Cmd(USART1_InitStructure.USART_RX_DMA, DISABLE);                     //关闭DMA ,防止干扰                  
                //注意,如果中断发送数据帧的速率很快,MCU来不及处理此次接收到的数据,中断又发来数据的话,这里不能开启,否则数据会被覆盖。有2种方式解决。
                //1. 在重新开启接收DMA通道之前,将DMA_Rx_Buf缓冲区里面的数据复制到另外一个数组中,然后再开启DMA,然后马上处理复制出来的数据。
                //2. 建立双缓冲,在DMA_Uart_DMA_Rx_Data函数中,重新配置DMA_MemoryBaseAddr 的缓冲区地址,那么下次接收到的数据就会保存到新的缓冲区中,不至于被覆盖。

                //重新开始下一次接收前先把上一次接受的数据长度,和数据读出来

                USART1_RX_STA = USART1_MAX_RX_LEN - DMA_GetCurrDataCounter(USART1_InitStructure.USART_RX_DMA); //获得接收到的字节数               如果不增加下面的限制,一次性发送超过600就会锁死600个
                if (USART1_RX_STA >= USART1_MAX_RX_LEN)
                {
                        USART1_RX_STA = 0;//避免接收到超过USART1_MAX_RX_LEN,
                }
                DMA_USART1_InitStructure.DMA_MemoryBaseAddr = (u32)USART1_RX_BUF;
                DMA_Init(USART1_InitStructure.USART_RX_DMA, &DMA_USART1_InitStructure);
                USART1_InitStructure.USART_RX_DMA->CNDTR = USART1_MAX_RX_LEN;            // 重新赋值计数值,必须大于等于最大可能接收到的数据帧数目
                DMA_Cmd(USART1_InitStructure.USART_RX_DMA, ENABLE);                      // DMA 开启,等待数据。
#endif               
                USART1_RX_BUF[USART1_RX_STA&0X7FFF]='\0';                                         //添加\0,防止字符串处理函数遇不见\0一直不结束
                USART1_RX_STA|=0x8000;                                                         //标记接收完成了
                //添加处理函数,最好主函数查询处理

        }
        if(USART_GetFlagStatus(USART1_InitStructure.USARTx,USART_FLAG_ORE) == SET) // 检查 ORE 标志,防止开关总中断死机,放在接收中断前面
        {
                USART_ClearFlag(USART1_InitStructure.USARTx,USART_FLAG_ORE);
                USART_ReceiveData(USART1_InitStructure.USARTx);
        }
#if USART1_DMA==0
        if(USART_GetITStatus(USART1_InitStructure.USARTx, USART_IT_RXNE) != RESET)   
        {
                u8 res = USART_ReceiveData(USART1_InitStructure.USARTx);                  //读取接收到的数据        
                if((USART1_RX_STA&0X7FFF)<USART1_MAX_RX_LEN-1)                        //超过数组长度的舍弃,空闲中断后处理数据前来的数据会继续接上
                {
                        USART1_RX_BUF[USART1_RX_STA&0X7FFF]=res;
                        USART1_RX_STA++;
                }
        }
#endif
}

回复 支持 反对

使用道具 举报

8

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
163
金钱
163
注册时间
2018-4-8
在线时间
26 小时
发表于 2020-7-16 14:26:51 | 显示全部楼层
无语凝噎移植的时候,我只需要usart3就把.c.h拷贝过去,结果提示..\HARDWARE\scr\usart3.c(239): error:  #268: declaration may not appear after executable statement in block         va_list arg_ptr;
我把va_list arg_ptr放到while(USART3_InitStructure.Tx_flag==1);前面,然后这个提示没有了,接下来一下子8个提示全部。
Build target '工程'
compiling usart3.c...
linking...
..\OBJ\工程文件.axf: Error: L6218E: Undefined symbol DMA_ClearFlag (referred from usart3.o).
..\OBJ\工程文件.axf: Error: L6218E: Undefined symbol DMA_Cmd (referred from usart3.o).
..\OBJ\工程文件.axf: Error: L6218E: Undefined symbol DMA_DeInit (referred from usart3.o).
..\OBJ\工程文件.axf: Error: L6218E: Undefined symbol DMA_GetCurrDataCounter (referred from usart3.o).
..\OBJ\工程文件.axf: Error: L6218E: Undefined symbol DMA_GetITStatus (referred from usart3.o).
..\OBJ\工程文件.axf: Error: L6218E: Undefined symbol DMA_ITConfig (referred from usart3.o).
..\OBJ\工程文件.axf: Error: L6218E: Undefined symbol DMA_Init (referred from usart3.o).
..\OBJ\工程文件.axf: Error: L6218E: Undefined symbol USART3_printf (referred from usart3.o).
这些全部都有,他就是提示没有,我也是绝望了。
回复 支持 反对

使用道具 举报

5

主题

19

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
255
金钱
255
注册时间
2014-2-27
在线时间
67 小时
发表于 2020-7-16 16:16:29 | 显示全部楼层
zhczlzhang 发表于 2020-7-16 14:26
无语凝噎移植的时候,我只需要usart3就把.c.h拷贝过去,结果提示..\HARDWARE\scr%usart3.c(239): error:  # ...

va_list arg_ptr 这个是不定参“…”的类型,说明你复制的时候缺少头文件啦。
回复 支持 反对

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2020-7-16 21:56:21 | 显示全部楼层
zhilve 发表于 2020-7-16 13:07
感谢楼主的无私分享,经测试,发现问题,当一次性接收大于接收buff时,会出现接收数量锁死,全部数据异常, ...

这就是个简单的例子,使用肯定不要让一帧大于buff 或者就你这样处理下
回复 支持 反对

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2020-7-16 21:56:59 | 显示全部楼层
zhczlzhang 发表于 2020-7-16 14:26
无语凝噎移植的时候,我只需要usart3就把.c.h拷贝过去,结果提示..\HARDWARE\scr%usart3.c(239): error:  # ...

你头文件包含混乱了
回复 支持 反对

使用道具 举报

8

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
163
金钱
163
注册时间
2018-4-8
在线时间
26 小时
发表于 2020-7-17 08:45:03 | 显示全部楼层
zhilve 发表于 2020-7-16 16:16
va_list arg_ptr 这个是不定参“…”的类型,说明你复制的时候缺少头文件啦。

我是直接移植的.c.h文件,有对比了sys文件跟.c文件下的.h文件都包含了,还是提示。
回复 支持 反对

使用道具 举报

3

主题

43

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
409
金钱
409
注册时间
2017-1-6
在线时间
64 小时
发表于 2020-10-25 18:33:57 | 显示全部楼层
MARK MARK MARK MARK
回复 支持 反对

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3447
金钱
3447
注册时间
2017-7-4
在线时间
869 小时
发表于 2020-10-25 20:36:34 | 显示全部楼层

参考这个帖子,串口DMA收发,高速不翻车。
http://www.openedv.com/forum.php ... d=317086&extra=
回复 支持 反对

使用道具 举报

6

主题

44

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
269
金钱
269
注册时间
2017-4-5
在线时间
100 小时
发表于 2020-12-9 16:04:44 | 显示全部楼层
串口2 好像有问题,不能接收
回复 支持 反对

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2020-12-9 16:52:06 | 显示全部楼层
蒙哥马利 发表于 2020-12-9 16:04
串口2 好像有问题,不能接收

不会的 测试过的代码
回复 支持 反对

使用道具 举报

6

主题

44

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
269
金钱
269
注册时间
2017-4-5
在线时间
100 小时
发表于 2020-12-10 10:30:21 | 显示全部楼层
nashui_sx 发表于 2020-12-9 16:52
不会的 测试过的代码

不好意思  板子的37脚和38脚短路了  尴尬
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
112
金钱
112
注册时间
2015-7-14
在线时间
25 小时
发表于 2021-2-2 10:04:58 | 显示全部楼层
谢谢!
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
2
金钱
2
注册时间
2021-5-17
在线时间
0 小时
发表于 2021-5-17 16:28:48 | 显示全部楼层
感谢分享!
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-24 15:57

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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