你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32CUBE F407ZET6串口1通过DMA方式接收不定长数据  

[复制链接]
yygkqzh 发布时间:2017-5-3 23:25
本帖最后由 yygkqzh 于 2017-5-4 14:14 编辑 6 H# S" R0 E8 _4 R+ O" x

$ S8 Q7 y# f- F最近买了一块STM32F407的板子,玩了较长时间,开发使用的是STM32CUBE,发现这个软件确实很实用,只要在软件界面进行选择,就可以帮你配置好各项参数。今天根据Paderboy的帖子【NUCLEO-L476RG开发】DMA-ADC1-串口不定长接收,也在自己的板子上搞了一把串口通过DMA方式接收数据,并通过显示接收到数据长度和接收到的数据。/ R7 K& w2 N, t& ~! y' Y6 ~
下面上图:
% ?0 w5 `* k1 T$ ]: i% F* E- n# U: K配置时钟为外部高速时钟 1.png % ]( Z7 l/ o! d9 o7 V' H
配置串口1为异步收发模式
; O/ L0 i2 i7 W- g 2.png , P4 Q" Y. _6 @4 y! w
配置时钟为外部8MHz晶振,配置系统时钟168MHz+ J% Q$ ?3 g% Y2 t  E
3.png 5 z. k9 U1 i; h$ F) U& Z6 r! S( m
配置串口波特率115200,使能发送和接收
( ~1 ^8 i2 p' R2 f* B0 c 4.png / _# o/ i$ _5 u/ p6 q# e
开启串口接收中断9 r( X' F  p" Z( I. k1 W/ _
5.png
9 D6 B8 _0 W/ u9 o" o3 K3 Q使能DMA串口接收9 }  Z' J4 A' T! q; @7 y
6.png
' ~& @9 d- X; w7 p0 X配置NVIC
' X( M1 f+ Y% J( x+ { 7.png   c9 e! w6 g# S; F
NVIC生成代码1 R& Z0 {0 Q3 Y- G
8.png , {+ G  R( V1 d" d+ P
然后输出代码 ,下面是在生成的代码中添加的。
" j2 f# i, c. }4 K& B+ H7 L& E( ^变量定义" D5 N8 e9 Q; J: m& M$ l& Z# R% _
  1. /* USER CODE BEGIN PV */5 c7 Y6 {9 }+ Y
  2. /* Private variables ---------------------------------------------------------*/
    $ U1 K+ N, Z. U9 X' A
  3. /*        可以接收的最大字符个数        */9 d) ?' T2 l5 K# Z: k& p
  4. #define BUFFERSIZE 255                                , [( g* G/ l9 I8 _9 Q0 u
  5. uint8_t ReceiveBuff[BUFFERSIZE];                                                //接收缓冲区) `4 ]: i7 |5 m$ s5 [
  6. uint8_t recv_end_flag = 0,Rx_len;        //接收完成中断,接收到字符长度
    $ X* c( L8 u( y9 [1 S
  7. /* USER CODE END PV */
复制代码
函数声明
( J$ Y5 @3 {8 a, v  U' s1 y
  1. /* USER CODE BEGIN PFP */; ?/ H4 h& D" h' A5 p) y
  2. /* Private function prototypes -----------------------------------------------*/
    ) h  q' A4 g; n" |& {+ f! R7 N$ K
  3. void uartdamget(void);
    1 z, u* }9 y% B
  4. #ifdef __GNUC__* c( Q% y  B, e- Z
  5. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    , T% [, E2 m8 o6 Y
  6. #else& {5 C. j% ?$ R6 m6 n6 m
  7. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)# V0 o1 ^0 Y0 y, F
  8. #endif / S9 R* [' l' X4 u: R
  9. PUTCHAR_PROTOTYPE
    0 p4 b5 f. Q2 L
  10. {; A; }0 r8 K2 ~
  11.         HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);2 R: d! z- y: p4 r0 n9 V
  12. return ch;
    # o$ @0 f7 e; s+ H5 s) s5 x6 k9 }: n
  13. }9 h, J7 l( y: }8 _4 N# W3 Z
  14. /* USER CODE END PFP */
复制代码
开启串口IDLE中断/ \; R2 k% x( }$ Q# [6 s5 J
  1.   /* USER CODE BEGIN 2 */
    9 j. a& [7 K( y  N. H
  2.         printf("This is a USART DMA Receive Test!!!\r\n");
    5 h% G  Y& {* _4 k3 `$ u  z
  3.         /*        使能串口1 IDLE中断        */
    " z% c0 n4 `# K
  4.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); ) a, q/ x( S' V
  5.         7 q+ }$ Z0 N2 Q
  6.   /* USER CODE END 2 */
复制代码
while(1)循环& V/ Q$ j0 l- m+ s( k4 a& v; Y
  1.   /* Infinite loop */
    5 _: i, b* `$ Y& d, X: e! h
  2.   /* USER CODE BEGIN WHILE */
    6 I2 h8 X1 n! N5 n- X. y9 ~
  3.   while (1)3 o$ }5 E2 y: l+ q/ ~
  4.   {/ ^7 L( {  ^" |; v# N
  5.                 uartdamget();2 Z% ~- x3 e, y0 V  |
  6.                
    & p, o0 I; x% P6 N# `* {4 b
  7.   /* USER CODE END WHILE */
复制代码
串口DMA获取  Q' m2 E& j, \! Q! J5 l; t
  1. /* USER CODE BEGIN 4 */
    ' p2 T5 F7 a! l9 _3 w4 O6 n
  2. void uartdamget(void)
    & v* l, J: I$ R' n- R. i7 T
  3. {
    9 t4 Q+ C+ k1 d- \( T5 i
  4.         if(recv_end_flag ==1)
    : @1 _) |: f" N+ P( D
  5.         {0 e: K  F( u: N" Y" I9 F3 {
  6.                 /*        打印接收到的数据长度 */
    2 B- r2 `* S# l* J5 ]+ s
  7.                 printf("\nrx_len=%d\r\n",Rx_len);
    & ~, b% F- I( W: L% W

  8. , I4 ~. A% G3 d
  9.                 for(int i=0;i<Rx_len;i++)
    : T3 n2 l6 ~& ^$ z' J6 x
  10.                 {
    * q- j; v- @/ H4 V& n
  11.                         /*        打印接收到的数据 *// V, [; Y* f5 \. B
  12.                                 printf("%c",ReceiveBuff[i]);
    , h- r8 \9 U* B  z
  13.                 }
    ( D7 p1 Y& M, \" ]2 s2 x# g5 X
  14.                 printf("\r\n");          2 \7 c1 M, u5 h1 ^" |" u- }
  15.                 /*        清空接收缓存区        */
    ! r, y* @6 o* D  }( _- M6 }
  16.                 for(int i = 0; i < Rx_len ; i++) 5 g, z4 ^, I5 H  w3 N- A; G
  17.                         ReceiveBuff[i]=0;
    + ?" E9 m6 c: Y) _$ U
  18.                 /*        接收数据长度清零        */
    6 U: u6 E) g5 A) L& I& P1 ^
  19.                 Rx_len=0;
    , G  x2 K9 G. J
  20.                 recv_end_flag=0;5 o6 c) R# \% n5 r
  21.         }$ m- \1 K' F6 ?1 e+ Q% r
  22.         /*        开启下一次接收        */$ j) [. w: f; C; B) C
  23.         HAL_UART_Receive_DMA(&huart1,(uint8_t*)ReceiveBuff,BUFFERSIZE);
    ; a" L% h/ `2 d6 N, Z- y$ m/ Z
  24. }1 {, h1 R# R3 q4 Z3 v; v
  25. /* USER CODE END 4 */
复制代码
#include "stm32f4xx_it.c"文件中断外部变量引用
' H7 m# k8 I3 c1 R0 |
  1. /* USER CODE BEGIN 0 */
    . [( R5 Z7 A1 {% V
  2. #define BUFFERSIZE 255
    ! d, D! j8 C( f8 m6 j
  3. extern uint8_t recv_end_flag,Rx_len,bootfirst;
    9 x& h& S, G( K: u
  4. /* USER CODE END 0 */
复制代码
串口1中断函数' B  U2 l  ]6 I8 p. B$ ?
  1. /**
    ' M4 D& @  p- X+ Q0 o" r
  2. * @brief This function handles USART1 global interrupt.# M- B+ A; V) ~% H) r' U! V* Q$ A
  3. */
    0 z! g  K! }& E5 S
  4. void USART1_IRQHandler(void)
    # o3 j/ H0 k/ l3 g
  5. {, D9 a: `* B4 s( z7 ?' f1 S( C
  6.   /* USER CODE BEGIN USART1_IRQn 0 */
    ) F, s& _% A$ L1 r& L6 \& O% l; x
  7. 9 Y/ _: K0 S) H6 j% V' l0 f
  8.   /* USER CODE END USART1_IRQn 0 */2 [- i6 d$ d% A$ f: ]4 U0 C
  9.   HAL_UART_IRQHandler(&huart1);* Z' r* p; H; `- R6 c9 ]) @
  10.   /* USER CODE BEGIN USART1_IRQn 1 */
    0 G) K0 l4 b: E8 i# M
  11.         uint32_t temp;
    * Y- N9 u) U, }; v- ~
  12.         /*        如果是串口1中断        */
    & W# _! e7 j5 r# V5 V
  13.         if(USART1 == huart1.Instance)6 D& L  \3 [4 N
  14.         {        /* 如果是串口1IDLE中断        */; C7 j- x2 ^( b: ~0 ~7 o6 b1 C
  15.                 if(RESET != __HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)){
    & {! ^. o% q$ Q4 }) ?
  16.                         /*        清除中断标志        */
    ; C* S' H0 @3 i* Y. \3 P& I
  17.                         __HAL_UART_CLEAR_IDLEFLAG(&huart1);; T: f6 D% \+ d: n: z- J
  18.                         /*        停止DMA接收        */7 w4 _2 J' k8 f* E' R; x1 [
  19.                         HAL_UART_DMAStop(&huart1);. A' Y/ m; C/ T4 H
  20.                         /*        获取DMA当前还有多少未填充        */5 [3 Q6 m. j7 J+ f  f# }) ?
  21.                         temp  = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    $ Z2 f3 s7 J9 r) g
  22.                         /*        计算串口接收到的数据个数        */& ]/ A- [5 ~# W' n6 s, O. g
  23.                         Rx_len =  BUFFERSIZE - temp;   t: O7 Q9 C6 r
  24.                         recv_end_flag = 1;
    # u, d% q, b, M, C, q# l7 R4 {
  25.                 }0 J" b: k* A; K" ]; i3 `
  26.         }
    1 M, ]% d0 g. _# t8 A7 s
  27.   /* USER CODE END USART1_IRQn 1 */5 s. Z  |7 A+ Z- }6 m
  28. }
复制代码
将程序下载到板子后,使用串口调试助手发送数据到MCU,2 a' M! T9 Z( r% B3 x" [
1.png
0 Z) B' r% W) c下面是源代码7 z) K; |" u% g
USART DMA Receive.zip (578.77 KB, 下载次数: 904)

评分

参与人数 1 ST金币 +2 收起 理由
kardel + 2 很给力!

查看全部评分

赞 收藏 8 评论24 发布时间:2017-5-3 23:25

举报

24个回答
super_me 回答时间:2019-1-7 16:23:09
假装微风 发表于 2017-7-10 17:22
; `8 R5 g8 L8 s7 A9 n! W- J亲 你的这个代码 上电  包头掉一个字节  第二次通信正常  是怎么回事

( s- Y5 A* C/ k2 Y5 p需要启动串口DMA接收,HAL_UART_Receive_DMA(&huart5,ReceiveBuff_usb,BUFFERSIZE);
super_me 回答时间:2019-1-7 16:21:48
在使能串口IDLE中断后面需要加一句,来启动串口DMA接收,HAL_UART_Receive_DMA(&huart5,ReceiveBuff_usb,BUFFERSIZE);
2 ~' p+ r5 I6 V6 d2 Y不然第一帧会错,实测!!!
假装微风 回答时间:2017-7-10 17:22:48
亲 你的这个代码 上电  包头掉一个字节  第二次通信正常  是怎么回事
zero99 回答时间:2017-5-15 15:34:57
谢谢分享
luocheng1234 回答时间:2017-9-21 15:02:06
6666666666666666666666666
耘灬耔 回答时间:2017-11-20 19:03:46
感谢 学习了
kardel 回答时间:2018-3-9 10:31:29
非常好用,已经参考这个结局了
lifengliu1 回答时间:2018-3-16 11:53:40
好东西, 正需要, 谢谢了
Ziv.Lin 回答时间:2018-4-27 01:47:07
Rx_len =  BUFFERSIZE - temp;
andey 回答时间:2018-4-27 07:30:45
提示: 作者被禁止或删除 内容自动屏蔽
_瞬_ 回答时间:2018-4-27 08:42:36
很好的资料,以前用标准库做过,现在学习一下cube2 S! d! a6 l( ^8 h

' S) t: F. |! ?
ml1306 回答时间:2018-5-7 17:36:13
感觉好麻烦啊,库也有不方便的时候
karzn 回答时间:2018-5-14 08:38:42
谢谢分享!!
木子小龙 回答时间:2018-5-23 14:55:13
谢谢分享
li77leprince 回答时间:2018-5-23 15:25:16
. t% D& Z7 I, V# H& W" v5 X
好东西, 正需要, 谢谢了
发个人意见 回答时间:2018-7-9 15:33:32
学习学习
12下一页

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版