请选择 进入手机版 | 继续访问电脑版

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

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

[复制链接]
yygkqzh 发布时间:2017-5-3 23:25
本帖最后由 yygkqzh 于 2017-5-4 14:14 编辑
- f2 c# l5 H" z$ f! n3 [, u
+ u) L+ m4 }" ~最近买了一块STM32F407的板子,玩了较长时间,开发使用的是STM32CUBE,发现这个软件确实很实用,只要在软件界面进行选择,就可以帮你配置好各项参数。今天根据Paderboy的帖子【NUCLEO-L476RG开发】DMA-ADC1-串口不定长接收,也在自己的板子上搞了一把串口通过DMA方式接收数据,并通过显示接收到数据长度和接收到的数据
+ v4 S3 J) i* h下面上图:
  k4 z9 t7 c# f& q) u& ~3 l配置时钟为外部高速时钟 1.png
) y4 e7 J$ x3 b2 A& q) Y# Z2 X; N配置串口1为异步收发模式
  a. ^4 F5 O! k) q+ }9 E& G: @ 2.png
$ V' o% h  F" X; G! |配置时钟为外部8MHz晶振,配置系统时钟168MHz
2 D2 r4 v- S; S' t$ O  V* h 3.png
2 r7 k4 E* e; k4 z配置串口波特率115200,使能发送和接收9 B$ F" }7 U: c. T+ N. I. _
4.png & F& Y: A% M8 C
开启串口接收中断
( O% E' t4 H3 {1 r5 K8 ^9 N 5.png
3 r0 Y  Y5 T* C4 ~3 {使能DMA串口接收
* G% i' V* c: T8 U1 \* |0 {9 w! n! } 6.png
' Z$ K7 p% h9 u9 I配置NVIC# L, K4 H9 v  z% \0 n5 ^
7.png * G6 O. A2 u. u  i
NVIC生成代码7 {% D& n, a! E
8.png 0 L. `9 g1 \' M# n
然后输出代码 ,下面是在生成的代码中添加的。
8 W2 u4 d6 b+ T+ H: {# l# B- T变量定义, c. P" f" i6 h: v" ~1 O6 k
  1. /* USER CODE BEGIN PV */
    % @8 ~( q; W. o+ j. Z5 B0 m" [( J
  2. /* Private variables ---------------------------------------------------------*/
    * b' ^; h# B5 L  I
  3. /*        可以接收的最大字符个数        */3 S7 l6 i0 Q* j* ]8 v$ P
  4. #define BUFFERSIZE 255                                
    0 B& o8 B! u7 Q: k8 n) |
  5. uint8_t ReceiveBuff[BUFFERSIZE];                                                //接收缓冲区
    ! E0 ?' D  U4 m
  6. uint8_t recv_end_flag = 0,Rx_len;        //接收完成中断,接收到字符长度
    # f+ ^) W# y& e0 G9 w3 L5 `- c8 ?
  7. /* USER CODE END PV */
复制代码
函数声明
" l( R$ J6 z/ G- o
  1. /* USER CODE BEGIN PFP */
    ) @1 W" l: Y* |8 N: J
  2. /* Private function prototypes -----------------------------------------------*/
    6 v. E: [7 T4 d; ^% @( |/ [, \
  3. void uartdamget(void);2 e3 V- w2 z5 o# w% l) ]
  4. #ifdef __GNUC__
    # n- Z* @& g: f# w+ Q$ `; U5 i1 U% F
  5. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)4 g- l! C! m, }* ?' T6 [7 h
  6. #else! D5 n; S& f* |% \  |
  7. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)# L( N) {/ o# N5 x/ z# {' e
  8. #endif & A7 K7 \. w7 L( @. k' i& T. n5 Z
  9. PUTCHAR_PROTOTYPE
    , r* G8 y) O! [) j' B
  10. {. G- c  L6 R: C6 O
  11.         HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
    & R: ?6 G2 w, [* `+ d
  12. return ch;
    # K- Y2 [3 }. _& [! k- w8 ]
  13. }& D4 I' z# N1 ~* w$ L7 t
  14. /* USER CODE END PFP */
复制代码
开启串口IDLE中断
4 v/ r( v' O/ x
  1.   /* USER CODE BEGIN 2 */
    6 Q; K2 w8 o) D
  2.         printf("This is a USART DMA Receive Test!!!\r\n");
    : C. _  N/ n4 E# J. Q  [
  3.         /*        使能串口1 IDLE中断        */
    8 N2 e0 A# W7 y! U1 u4 R, g$ r
  4.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); % Q' C: \( J+ U# g' F; W
  5.         $ O9 g+ [  F% _
  6.   /* USER CODE END 2 */
复制代码
while(1)循环
, w, L: r& i2 ?2 r$ e- M
  1.   /* Infinite loop */3 U5 X6 y* K0 h! J
  2.   /* USER CODE BEGIN WHILE */9 z/ g! Y, c% D4 E1 i
  3.   while (1)% E+ |" J6 Y- H
  4.   {7 c& D' Q4 {( |# H* Y
  5.                 uartdamget();
    0 f! S- G; r6 i# z+ B- M* \. R
  6.                 3 ~3 C" b8 U* T6 J" d6 k
  7.   /* USER CODE END WHILE */
复制代码
串口DMA获取' l, O2 r) _! C7 t6 v: [* r) A
  1. /* USER CODE BEGIN 4 */9 Q% c( \$ o, r* o4 i
  2. void uartdamget(void)  }. u. F, a. u' Q* _
  3. {7 m: k3 p$ I$ c
  4.         if(recv_end_flag ==1)# E" \9 i$ ^0 @* o
  5.         {+ P# x3 k1 t$ h
  6.                 /*        打印接收到的数据长度 */  X5 O7 v( G- s0 x' ~- S
  7.                 printf("\nrx_len=%d\r\n",Rx_len);
      f9 b: |- L' S

  8. ! Z2 D( V& K0 U1 t+ I  i! U5 I
  9.                 for(int i=0;i<Rx_len;i++)
    ' h1 O8 m- q0 Q1 L$ d2 w9 O1 h' Q6 J$ X
  10.                 {
    . w3 x0 U+ t+ K, x' X* V
  11.                         /*        打印接收到的数据 */
    1 B5 G% D& t. l
  12.                                 printf("%c",ReceiveBuff[i]);
    ' D" \# d/ L& \: N
  13.                 }
    ; H/ U; C  `" ~4 ^* w. d/ F5 t
  14.                 printf("\r\n");         
    5 {* t" @& o- L
  15.                 /*        清空接收缓存区        */
    1 A. d& M7 h7 ]( l
  16.                 for(int i = 0; i < Rx_len ; i++) 2 C! g$ B( q0 @  T. I
  17.                         ReceiveBuff[i]=0;
    - F; ]2 Q/ P  E6 e8 i6 l6 i% l
  18.                 /*        接收数据长度清零        */
    # j0 @9 l: t% ^) n- Y0 P4 B& [2 ^1 v
  19.                 Rx_len=0;
    / G: E  W% [6 m* T) Z- s
  20.                 recv_end_flag=0;
    . Z6 P. n# V+ F! r
  21.         }
    ) a2 ~2 B0 P' z3 S2 U2 J* j
  22.         /*        开启下一次接收        */
    + B1 Z+ x- B% U" a! r* V# a! `
  23.         HAL_UART_Receive_DMA(&huart1,(uint8_t*)ReceiveBuff,BUFFERSIZE);+ i5 A. ~& {* h4 Z. c
  24. }
    3 M& \  l0 _$ v9 |0 f, b$ x( y+ w
  25. /* USER CODE END 4 */
复制代码
#include "stm32f4xx_it.c"文件中断外部变量引用
8 ^4 D6 B" T- q( m& v7 _) f
  1. /* USER CODE BEGIN 0 */! a% z( J" W: X( Q4 Z7 b. S
  2. #define BUFFERSIZE 255
    3 F, e5 e+ j+ _4 S) f5 E
  3. extern uint8_t recv_end_flag,Rx_len,bootfirst;
    ( k" j) c+ _* v$ A+ ?6 F
  4. /* USER CODE END 0 */
复制代码
串口1中断函数; Q: }  D; ?; a  {1 @0 H
  1. /**# z7 ~$ d( i! z. t9 W- [' M! R
  2. * @brief This function handles USART1 global interrupt., C: I% k. o1 X$ x
  3. */. e) G/ w8 g# N* R
  4. void USART1_IRQHandler(void)
    + g# ?8 i' M/ r: M- J+ `1 B7 S2 o5 B
  5. {9 ]" h* ?1 W- ~+ {0 _% L  C3 z
  6.   /* USER CODE BEGIN USART1_IRQn 0 */% o' A4 `! @3 _+ t4 I. v: ?% ~2 h
  7. . k2 u7 V2 y1 k$ ^& Z8 G6 H
  8.   /* USER CODE END USART1_IRQn 0 */
    6 @' ?0 w+ B/ a! X6 H$ {6 y* j
  9.   HAL_UART_IRQHandler(&huart1);
    4 ?, E# }( V2 u4 H, k
  10.   /* USER CODE BEGIN USART1_IRQn 1 */
    + x5 c; o0 u! f& Z6 ^- r, _
  11.         uint32_t temp;5 O. N& ~1 ^% a& g+ g1 ?4 n4 S
  12.         /*        如果是串口1中断        */9 J7 L" `6 }5 Y( G
  13.         if(USART1 == huart1.Instance)
      u, e6 y/ t- r! t, N/ B( j9 l
  14.         {        /* 如果是串口1IDLE中断        */
    / i) [, K( p" A1 F$ X# p
  15.                 if(RESET != __HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)){
    6 z% h! O9 f# [  J$ x
  16.                         /*        清除中断标志        */
    ! Q( K& O# _7 h( P7 [: V
  17.                         __HAL_UART_CLEAR_IDLEFLAG(&huart1);7 I5 b+ F0 ~# r) a. b
  18.                         /*        停止DMA接收        */
    ! k% O  B" W/ w
  19.                         HAL_UART_DMAStop(&huart1);
    2 c% ^9 y$ y9 Y7 z8 g: h8 }- c" L
  20.                         /*        获取DMA当前还有多少未填充        */" ]6 T8 f+ ^% k2 J' j! T
  21.                         temp  = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);7 X. y2 C! i) d
  22.                         /*        计算串口接收到的数据个数        */
    6 B: |' d4 p8 K* P1 m
  23.                         Rx_len =  BUFFERSIZE - temp;
    - {4 q5 ^  H  O/ `2 [' E( J
  24.                         recv_end_flag = 1;% B  g4 a: R1 j& W4 y7 t
  25.                 }4 G. ]7 \* y) G2 E5 F
  26.         }
    & ^& X7 [2 O. A( c, R
  27.   /* USER CODE END USART1_IRQn 1 */, t4 W+ @; C/ C$ I, T- `* l# h( ]
  28. }
复制代码
将程序下载到板子后,使用串口调试助手发送数据到MCU,5 q; e& @& I! O
1.png
- r7 O  L1 s3 e/ n7 o7 ?5 e下面是源代码
- e$ C8 x' T  D6 E  _0 c2 ] 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:224 [- ^0 P! f# y$ }
亲 你的这个代码 上电  包头掉一个字节  第二次通信正常  是怎么回事
8 K  }9 q2 D0 F4 f% @* ?0 w" C
需要启动串口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);
5 G" F# c0 W2 z1 I# X- j6 e, @不然第一帧会错,实测!!!
假装微风 回答时间: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! ~$ x) v' x) w

/ P$ o+ |) C& Y% g3 H  l8 s
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

2 h" A7 [' w8 S8 }- j好东西, 正需要, 谢谢了
发个人意见 回答时间:2018-7-9 15:33:32
学习学习
12下一页

所属标签

相似分享

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