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

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

[复制链接]
yygkqzh 发布时间:2017-5-3 23:25
本帖最后由 yygkqzh 于 2017-5-4 14:14 编辑
  g" R5 h, E" n& R; [& b1 S1 v: s2 N" O
最近买了一块STM32F407的板子,玩了较长时间,开发使用的是STM32CUBE,发现这个软件确实很实用,只要在软件界面进行选择,就可以帮你配置好各项参数。今天根据Paderboy的帖子【NUCLEO-L476RG开发】DMA-ADC1-串口不定长接收,也在自己的板子上搞了一把串口通过DMA方式接收数据,并通过显示接收到数据长度和接收到的数据
; `% g0 A8 z" i8 E# ^/ X, c: y下面上图:
5 a2 n2 O- F% a) b配置时钟为外部高速时钟 1.png
+ P% I& G9 L5 p& n) W配置串口1为异步收发模式2 g2 ~* }( }3 T; a  U  |
2.png ; Y) S- D! _. B% P' U# U$ E
配置时钟为外部8MHz晶振,配置系统时钟168MHz. E: n  P; {  U
3.png / ~8 i& e% w5 ^5 Y
配置串口波特率115200,使能发送和接收2 v, D- F' C$ z) t* q6 x; w) r
4.png / h- A8 d! E$ G, \, L9 D. \8 _
开启串口接收中断5 n7 j% ?9 a3 G9 X& n, [' V
5.png * C6 t, t5 K+ c
使能DMA串口接收
7 N+ K; M& K! {. \, g' F  L  Y 6.png ; i+ p) o" n' P$ |8 u
配置NVIC
, a. \, R" T8 G  N+ M$ `; ?# u  q( [ 7.png
" Z/ _" Y8 U  f: J4 N5 v) x, _NVIC生成代码+ m2 \- l2 k) w8 ^
8.png
( ~: R% Q1 P6 k然后输出代码 ,下面是在生成的代码中添加的。
! h8 y) X9 p( c% E+ A变量定义
1 p' y9 H* T3 D# x5 z
  1. /* USER CODE BEGIN PV */
    , Y% Z  S$ }0 F( Q
  2. /* Private variables ---------------------------------------------------------*/
    3 E3 C) ~2 l: R0 y
  3. /*        可以接收的最大字符个数        */5 \+ y' H, {  B! e6 M+ u
  4. #define BUFFERSIZE 255                                + m& m% ^  {% v/ y/ h
  5. uint8_t ReceiveBuff[BUFFERSIZE];                                                //接收缓冲区
    3 _: k. r1 l6 T0 p9 ?
  6. uint8_t recv_end_flag = 0,Rx_len;        //接收完成中断,接收到字符长度6 a4 ~0 e! K2 T: n2 n
  7. /* USER CODE END PV */
复制代码
函数声明
: k" N1 Z2 h/ L9 w( T$ T
  1. /* USER CODE BEGIN PFP */
    / C) ~: Q4 c3 e9 x$ w) w
  2. /* Private function prototypes -----------------------------------------------*/
    9 \: g% g' A; J5 @6 E% a" r
  3. void uartdamget(void);
    9 J, R' y; |  N5 {2 A4 L0 ?
  4. #ifdef __GNUC__/ p% l. t% d; B/ i4 P7 d
  5. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)* d( n6 b+ ?% d1 L) d7 _; ?; b- D
  6. #else! M" h* J0 s- l
  7. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
    / Z; \# ]* B! E4 {, @% s8 i% {
  8. #endif
      D0 t! ]: f1 C/ Y- T& b3 i2 C6 P
  9. PUTCHAR_PROTOTYPE* |4 ]3 }7 p7 w7 G) o, G( f
  10. {
    7 C* B/ o1 T8 z: e9 O* a
  11.         HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
    6 Q! k: @) z/ B) u6 ~
  12. return ch;1 g+ H; h( C8 E2 D; B, s% ?. @
  13. }0 q) G9 i: J3 e# Q2 a6 l4 o
  14. /* USER CODE END PFP */
复制代码
开启串口IDLE中断5 \/ R2 x7 K- h/ W- K/ M2 Y) R% O
  1.   /* USER CODE BEGIN 2 */0 u/ l* L% d6 ^' G( V" x2 {+ a; A7 R2 h0 \
  2.         printf("This is a USART DMA Receive Test!!!\r\n");
    . U# c# r" b0 Q
  3.         /*        使能串口1 IDLE中断        */; v& Z2 f6 A, w% j! y3 }
  4.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); 5 b- Z  m# D8 Q9 G9 r
  5.         
    $ l  p  C6 K# J# K# w$ a1 k3 @* W
  6.   /* USER CODE END 2 */
复制代码
while(1)循环
# T& M" G4 P' y3 B
  1.   /* Infinite loop */
    ! e* R0 R" Y0 r% b
  2.   /* USER CODE BEGIN WHILE */$ g: v# d9 L) Q
  3.   while (1): K  Q/ f- c; ?2 ?1 f" O5 t
  4.   {
    2 j0 ~; l! y8 z
  5.                 uartdamget();
      w/ S$ U1 `* F) V, B
  6.                 2 E: N7 z7 C; P, i  Y  ~) Y
  7.   /* USER CODE END WHILE */
复制代码
串口DMA获取
8 v' E: S# R1 D+ |
  1. /* USER CODE BEGIN 4 */
    + d" {" W# O: h9 l; T; ?8 v) u
  2. void uartdamget(void)
    . s, X+ Q  L/ {, ^5 i5 R
  3. {( T" G* z# j. \( e! E' z* d' c
  4.         if(recv_end_flag ==1)2 q, y: A  \' t. v, O+ t% Z
  5.         {. x1 e  F) A: I  n, K4 f9 N6 S7 b7 K
  6.                 /*        打印接收到的数据长度 */( w: G3 K$ Z6 f# w8 w8 j1 b8 U
  7.                 printf("\nrx_len=%d\r\n",Rx_len);
    / X* [% ^9 X% p+ \

  8. % ?" `% E3 P+ F$ `9 W, X. [  p7 K6 ]
  9.                 for(int i=0;i<Rx_len;i++)
    , X$ u+ f& o3 R6 \7 t' Z& J3 s
  10.                 {
    8 `* T" K. _$ h$ w9 |) }- O
  11.                         /*        打印接收到的数据 */
    $ r% ~  E$ m, [% a9 {9 }; r- ^
  12.                                 printf("%c",ReceiveBuff[i]);
    4 O# |: R; g: e; v" m1 [: t# u- ]
  13.                 }  M2 r4 P6 h8 F" N, Q+ P7 x
  14.                 printf("\r\n");          " a5 y  [4 x- u* y
  15.                 /*        清空接收缓存区        */
    * _' L* W: y& s+ Q
  16.                 for(int i = 0; i < Rx_len ; i++) 2 ~2 _' Z7 E4 I2 c0 m) L% P. |
  17.                         ReceiveBuff[i]=0;
    5 g1 h$ z! B0 x0 D
  18.                 /*        接收数据长度清零        */
    : W9 @! n: d3 {3 q% r7 q
  19.                 Rx_len=0;# Q: J1 M' V* C4 x& y4 M
  20.                 recv_end_flag=0;
    7 j( c. N) L# t7 i
  21.         }0 v& j' `8 Y! P
  22.         /*        开启下一次接收        */. ~1 e) A& u1 R# `/ p9 t' {! `
  23.         HAL_UART_Receive_DMA(&huart1,(uint8_t*)ReceiveBuff,BUFFERSIZE);
    . q* c! R+ I4 Y
  24. }
    * A- n2 l8 l; a  S
  25. /* USER CODE END 4 */
复制代码
#include "stm32f4xx_it.c"文件中断外部变量引用$ R; E- G- ~, ?# F, N
  1. /* USER CODE BEGIN 0 */: F  o; b( j2 t% C4 n
  2. #define BUFFERSIZE 255
    5 w9 G% j& {7 `0 g- {
  3. extern uint8_t recv_end_flag,Rx_len,bootfirst;+ m) v: O6 }% e
  4. /* USER CODE END 0 */
复制代码
串口1中断函数) w4 s' Y- a3 F& t$ V0 B
  1. /**9 I( ?& O7 O. Z- X
  2. * @brief This function handles USART1 global interrupt.4 d- M" i+ [7 V3 X, W
  3. */
    6 l+ `" w# A9 N0 k* w5 i# X" ]5 ?
  4. void USART1_IRQHandler(void)
    0 x& C/ [; T% R8 D, M
  5. {
    ) h" q! \- X+ r% ~( Q0 j% C
  6.   /* USER CODE BEGIN USART1_IRQn 0 */
    ! f! ]: i' b4 v% l
  7. . O6 p( S+ t& l% p4 u% {3 t
  8.   /* USER CODE END USART1_IRQn 0 */- y: {& ~& y3 x+ x% T
  9.   HAL_UART_IRQHandler(&huart1);
    : e0 h" N7 F; V: T
  10.   /* USER CODE BEGIN USART1_IRQn 1 */9 m7 P5 G1 e! J1 p
  11.         uint32_t temp;
      x( A* X2 ~* }; u9 x  m  H
  12.         /*        如果是串口1中断        */
    1 v& _7 W$ s) i6 W! I" B% W
  13.         if(USART1 == huart1.Instance)
    ' y) u) N" W2 Q: E. R
  14.         {        /* 如果是串口1IDLE中断        */  {. U* j3 h6 b2 U  o0 i; C- h
  15.                 if(RESET != __HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)){4 e+ C. j/ R! a
  16.                         /*        清除中断标志        */
    # L% T( _0 [$ l: b6 ^* y* [
  17.                         __HAL_UART_CLEAR_IDLEFLAG(&huart1);& N% I* L: L0 ]$ S6 x" Q$ _6 ]
  18.                         /*        停止DMA接收        */
    . v7 I9 s& ]6 {6 m; V/ \! @
  19.                         HAL_UART_DMAStop(&huart1);
    " G5 G' G" B! U/ ?
  20.                         /*        获取DMA当前还有多少未填充        */
    4 M/ C" t$ F5 x% i4 O0 }+ x
  21.                         temp  = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);8 ~8 g( }$ A0 d; n' h/ u
  22.                         /*        计算串口接收到的数据个数        */
    9 ?1 d+ E$ \: e
  23.                         Rx_len =  BUFFERSIZE - temp; 8 p4 R: p  T! }0 C* A7 W- [
  24.                         recv_end_flag = 1;
      z! \0 `$ h  k9 I
  25.                 }
    2 L/ c6 V. _2 h! d+ N
  26.         }
    / E0 Y, W: ]* T! T7 s
  27.   /* USER CODE END USART1_IRQn 1 */2 ?- C  i9 [6 }7 P$ V
  28. }
复制代码
将程序下载到板子后,使用串口调试助手发送数据到MCU,
+ s9 U( f. q$ D) s3 L 1.png
8 k4 |& h& U- }' {9 m$ k下面是源代码
) S$ t% A/ j8 ?) u/ R 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:22
0 a! ^! @- t8 `# }# b0 e8 t亲 你的这个代码 上电  包头掉一个字节  第二次通信正常  是怎么回事
- `# n5 e7 L- A/ D8 r
需要启动串口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);
( i. L& P$ a1 n  B不然第一帧会错,实测!!!
假装微风 回答时间: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
很好的资料,以前用标准库做过,现在学习一下cube4 Z; _9 u, f6 B9 O$ P- b  W& s4 _
8 }1 a, m( C5 }( L
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
5 S- x% D8 j4 h9 M4 ~6 P
好东西, 正需要, 谢谢了
发个人意见 回答时间:2018-7-9 15:33:32
学习学习
12下一页

所属标签

相似分享

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