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

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

[复制链接]
yygkqzh 发布时间:2017-5-3 23:25
本帖最后由 yygkqzh 于 2017-5-4 14:14 编辑
9 G0 M2 F- `3 W2 `; H! z/ U
2 `( B  v! ?% w$ w: T  B) e  _8 p最近买了一块STM32F407的板子,玩了较长时间,开发使用的是STM32CUBE,发现这个软件确实很实用,只要在软件界面进行选择,就可以帮你配置好各项参数。今天根据Paderboy的帖子【NUCLEO-L476RG开发】DMA-ADC1-串口不定长接收,也在自己的板子上搞了一把串口通过DMA方式接收数据,并通过显示接收到数据长度和接收到的数据- a* n$ i+ f3 g) N
下面上图:2 K  `1 r. ?) h- k, O) W* D9 Q
配置时钟为外部高速时钟 1.png ; K, r% Y' K# {" R
配置串口1为异步收发模式
' ?0 b  Y  d( `4 o$ x/ Z 2.png & B, |: g2 t- @) Q. P- M% ?
配置时钟为外部8MHz晶振,配置系统时钟168MHz
  v' @' v- s. H 3.png : q8 G$ q5 o. ?) c. P4 s. ^
配置串口波特率115200,使能发送和接收
; f$ s, j* T- \  S 4.png 9 {) q' q0 I, c2 C0 q  A
开启串口接收中断
; H) V0 E1 U  D* |! o 5.png 3 G/ ]# h  v/ F, b
使能DMA串口接收
  b  S' [4 Z9 N# _) C0 ` 6.png $ b# W; k2 R: n
配置NVIC
5 d% ~' K9 B+ m+ O9 [& j: ? 7.png
9 y& i# D- Y9 w: D" s  UNVIC生成代码$ I% I! j6 |# `
8.png
+ z, R. h2 _* E4 @然后输出代码 ,下面是在生成的代码中添加的。4 `3 @: a+ ?; Z/ P" l+ u
变量定义& S- O  f: X% r$ e2 `% }( p1 I
  1. /* USER CODE BEGIN PV */( Y: q/ U1 z( h9 }0 Z- C+ B
  2. /* Private variables ---------------------------------------------------------*/7 C  E5 R8 h0 o
  3. /*        可以接收的最大字符个数        */8 ~# R. ~" z! F5 @6 H1 R7 j# T; }  }
  4. #define BUFFERSIZE 255                                ' K1 o7 ?0 N! Z; {8 H. `7 s
  5. uint8_t ReceiveBuff[BUFFERSIZE];                                                //接收缓冲区: X4 E; [. c( k5 M' o
  6. uint8_t recv_end_flag = 0,Rx_len;        //接收完成中断,接收到字符长度, Y, o; }+ @! N$ u/ M" b
  7. /* USER CODE END PV */
复制代码
函数声明
& P, ~0 t% L6 g& F# ?+ [9 q
  1. /* USER CODE BEGIN PFP */
    : k; l+ p9 K: L0 l
  2. /* Private function prototypes -----------------------------------------------*/
    + [' i7 q, A5 X" R
  3. void uartdamget(void);# G# H  [4 \6 g" f6 u
  4. #ifdef __GNUC__" Q$ j9 Y3 ?4 x  M
  5. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    6 G5 g$ _; N3 O6 i
  6. #else% a/ q- Y2 Z3 ]
  7. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)- N# G& }# c8 G1 F2 q' N/ ~! {
  8. #endif
    & J7 E+ _% A9 v3 T2 G
  9. PUTCHAR_PROTOTYPE
    , m3 a: N5 R2 k1 ]
  10. {
    + G: v: m& c$ B5 j+ g0 _9 n) l
  11.         HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
    0 Y7 u: o4 r$ b1 ~" ?: I! M! V/ w) E
  12. return ch;; ^. E$ U2 N9 |" K
  13. }
    0 o3 ?7 j2 Y; Q, J5 V) O; ~; ^: T
  14. /* USER CODE END PFP */
复制代码
开启串口IDLE中断
  U3 w: Y' H! n' v
  1.   /* USER CODE BEGIN 2 */- X9 ^9 W) p/ Z0 F) s
  2.         printf("This is a USART DMA Receive Test!!!\r\n");
    6 G- _+ ~( ~# y$ r
  3.         /*        使能串口1 IDLE中断        */  a) D5 n2 x( z* [3 L6 |+ P9 O% b
  4.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); 5 i$ O9 N% G$ s  w& }7 l
  5.         - g( w+ I& L3 j1 q; f
  6.   /* USER CODE END 2 */
复制代码
while(1)循环
6 L5 @" G$ M8 d! b! S! s9 a
  1.   /* Infinite loop */# u! {; j3 t! |0 F
  2.   /* USER CODE BEGIN WHILE */
      b: L6 y( s, e  j; r( B( P
  3.   while (1)
    1 ?; {6 O# Q+ a$ n. C5 L+ T, }
  4.   {
    ! d9 T9 ?  ^* t' e* t1 W
  5.                 uartdamget();+ Z9 K; o6 p( f2 g3 K
  6.                
    : g0 q& T- X2 l2 q7 K
  7.   /* USER CODE END WHILE */
复制代码
串口DMA获取1 K  K' _5 I- m" g4 |- x
  1. /* USER CODE BEGIN 4 */
    5 M+ M9 m% u/ y7 P
  2. void uartdamget(void)0 ?3 K. Q' t# ~
  3. {
    ( f  X$ u" G" h: m4 L, b
  4.         if(recv_end_flag ==1)" W1 Z+ y1 E- a9 x6 d
  5.         {
    3 q5 Y: [1 s7 @/ S- l0 u- A4 |
  6.                 /*        打印接收到的数据长度 */( ?5 l1 @1 I- F' B& D" Z
  7.                 printf("\nrx_len=%d\r\n",Rx_len);
      U6 n1 z& Z) c$ G

  8. : b+ y  C; _' _& K- [4 _
  9.                 for(int i=0;i<Rx_len;i++)
    $ F3 ^9 s" h! i! Q3 P
  10.                 {: Z( V5 k. I( d5 h6 b5 M6 X9 Q" y
  11.                         /*        打印接收到的数据 */
    $ h  }/ q& \7 q# \/ {4 d; R) ~, e
  12.                                 printf("%c",ReceiveBuff[i]);
    ( v( ]; \8 Y* ]" R" B, `9 n
  13.                 }
    - p* H3 T6 r/ \6 v. P3 f" P
  14.                 printf("\r\n");         
      Z; y( {1 D( v. T: U% [* n" t
  15.                 /*        清空接收缓存区        */
    5 N7 k9 M) y( ?, W1 T
  16.                 for(int i = 0; i < Rx_len ; i++)   x! b) o% j2 {0 G# _' ]& E
  17.                         ReceiveBuff[i]=0;
    * A+ J, ?+ j; p: W; X
  18.                 /*        接收数据长度清零        */
    , ?+ F1 E/ A0 Z1 Z& o
  19.                 Rx_len=0;
    + r6 u/ T. H6 b) ~+ A
  20.                 recv_end_flag=0;
    # I2 w1 I  p1 c
  21.         }$ x( C9 H9 J" i+ q8 r5 y! m; v
  22.         /*        开启下一次接收        */# B$ h4 I6 G" I' ]
  23.         HAL_UART_Receive_DMA(&huart1,(uint8_t*)ReceiveBuff,BUFFERSIZE);8 o2 Y7 \% a5 {# `/ m
  24. }
    ) I9 W/ ?; d) L9 x3 Q" w  G
  25. /* USER CODE END 4 */
复制代码
#include "stm32f4xx_it.c"文件中断外部变量引用+ s. P! K. d5 x
  1. /* USER CODE BEGIN 0 */
    2 B3 ^/ S8 L1 _3 e
  2. #define BUFFERSIZE 255
    , w& T1 ^' V0 a- S8 X+ @
  3. extern uint8_t recv_end_flag,Rx_len,bootfirst;; I; [5 a- v, l
  4. /* USER CODE END 0 */
复制代码
串口1中断函数7 J" J  E" b/ w2 f; A. y$ L
  1. /**
      |1 w8 @6 r$ v0 s$ S( F
  2. * @brief This function handles USART1 global interrupt.
    : @. h4 h2 X; h0 B) ~' M& Z6 X
  3. */3 E: W9 C$ H( H0 x/ Z
  4. void USART1_IRQHandler(void); c: X4 {& [3 [$ h! s& u
  5. {7 F% g6 I- s+ H6 ?- I
  6.   /* USER CODE BEGIN USART1_IRQn 0 */
    + c4 ~) M5 t6 w% V

  7. 3 {: Z+ a8 Z9 b" ^: M: h! o
  8.   /* USER CODE END USART1_IRQn 0 */: p6 \6 @$ s; P2 ?% N. H7 S1 x
  9.   HAL_UART_IRQHandler(&huart1);
    / |( O7 Q/ m1 @9 V: F
  10.   /* USER CODE BEGIN USART1_IRQn 1 */% |# M2 r( Y1 I" E. [7 @. m) J
  11.         uint32_t temp;
    $ f, k' |( R9 m2 V# H/ Q( u* Q( \
  12.         /*        如果是串口1中断        */$ c) s, _- D# ^5 ^
  13.         if(USART1 == huart1.Instance)
    + J" w1 c: H1 ]
  14.         {        /* 如果是串口1IDLE中断        */
    / y2 u" V- t; G& K# K
  15.                 if(RESET != __HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)){: |3 p% x* r! k" r; p! ~+ k
  16.                         /*        清除中断标志        */& F5 A$ `1 E9 N
  17.                         __HAL_UART_CLEAR_IDLEFLAG(&huart1);/ k+ k1 M- c' m' h& ~$ R) S
  18.                         /*        停止DMA接收        */
    " D. R+ U. v6 a
  19.                         HAL_UART_DMAStop(&huart1);
    . L' T! q7 `/ d( x. q
  20.                         /*        获取DMA当前还有多少未填充        */: b6 E% k- w9 h% K
  21.                         temp  = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    8 j: o" o' U9 V  D
  22.                         /*        计算串口接收到的数据个数        */0 O: F( S6 t: M3 C2 p5 [
  23.                         Rx_len =  BUFFERSIZE - temp;
    1 C( x5 z+ N: X
  24.                         recv_end_flag = 1;
    8 {, m: Y. _2 L% d% `$ o& ~
  25.                 }! m, Y" A3 a7 c' B. t' W8 g
  26.         }
    ! ], `# ?- Y( f# o
  27.   /* USER CODE END USART1_IRQn 1 */' E( K4 ]( i$ `2 f' ~6 @2 u
  28. }
复制代码
将程序下载到板子后,使用串口调试助手发送数据到MCU,! V/ C+ ?5 s& t5 v
1.png " n. L& I. r( ^; |- f, o
下面是源代码1 w* F2 F4 n% w/ d) n% @3 B/ |- f
USART DMA Receive.zip (578.77 KB, 下载次数: 903)

评分

参与人数 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:221 @5 V( {' H# F* u# K
亲 你的这个代码 上电  包头掉一个字节  第二次通信正常  是怎么回事

* e5 W, [. i  |% p  D. Q& e3 }* o需要启动串口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);
& A, C; F5 n- E- x, C- q# 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
很好的资料,以前用标准库做过,现在学习一下cube! f" y2 H3 Z  @6 K, g" y" F

, M/ Q  ~7 W* d8 z# X+ {; Y; z
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
0 I- ~0 a4 r8 B% X
好东西, 正需要, 谢谢了
发个人意见 回答时间:2018-7-9 15:33:32
学习学习
12下一页

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版