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

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

[复制链接]
yygkqzh 发布时间:2017-5-3 23:25
本帖最后由 yygkqzh 于 2017-5-4 14:14 编辑
/ f# D8 z( f7 A7 S! a( n6 A/ B; q! U- }5 C' w
最近买了一块STM32F407的板子,玩了较长时间,开发使用的是STM32CUBE,发现这个软件确实很实用,只要在软件界面进行选择,就可以帮你配置好各项参数。今天根据Paderboy的帖子【NUCLEO-L476RG开发】DMA-ADC1-串口不定长接收,也在自己的板子上搞了一把串口通过DMA方式接收数据,并通过显示接收到数据长度和接收到的数据
' C8 A; P2 i( [& [* I) Y/ m下面上图:
# ]' {3 Z& Z, i/ M6 o4 e5 O8 d配置时钟为外部高速时钟 1.png 3 }* `3 m, M( w/ J
配置串口1为异步收发模式
% c, L% S/ k" t" O8 o" S 2.png
+ q: S+ I0 w8 t) [5 t* U6 v配置时钟为外部8MHz晶振,配置系统时钟168MHz
% D7 c$ ?: `7 H7 C! l$ x 3.png   D/ p4 M& x9 W) I) D6 }* U" T3 |
配置串口波特率115200,使能发送和接收, M' x3 O' z" Q( t1 j) K
4.png 8 T) m' M0 Z% s9 }
开启串口接收中断( C; c- e/ [) }
5.png
! k; |9 ]* H# {使能DMA串口接收
- S- b) U! f" O9 Y$ [ 6.png 7 U6 G  e& ?' s! N7 F9 W: d
配置NVIC
3 X; c; |! _5 {# t; Z; d+ B 7.png
! Z4 r/ ^+ O7 Y1 tNVIC生成代码. J  F1 V, \6 _8 q- s1 f, k
8.png
1 J( ?! R, Z4 Y  S0 t然后输出代码 ,下面是在生成的代码中添加的。
* ^2 u  v& B) Z  v7 ?: }0 A变量定义9 c7 `" P7 u, w) o( P1 ^- }- A
  1. /* USER CODE BEGIN PV */$ B/ W/ t4 f( A, j- v; s) }
  2. /* Private variables ---------------------------------------------------------*/
    - c- ]& h. H, J+ f/ p
  3. /*        可以接收的最大字符个数        */
    % H, p& Y: A+ l/ @& R" U  w
  4. #define BUFFERSIZE 255                                5 j% B. V' @; \1 H
  5. uint8_t ReceiveBuff[BUFFERSIZE];                                                //接收缓冲区& v4 F( N9 h2 j. ~% _' Z  p+ n4 L
  6. uint8_t recv_end_flag = 0,Rx_len;        //接收完成中断,接收到字符长度
    9 ]( k9 p: k) h) g) w6 ^, E8 w
  7. /* USER CODE END PV */
复制代码
函数声明# X/ _! u. ~5 e9 b* l* L
  1. /* USER CODE BEGIN PFP */
    $ {" Y: K' h8 f+ s
  2. /* Private function prototypes -----------------------------------------------*/
    + T6 J) O) C! e+ U
  3. void uartdamget(void);
    3 }0 O. z. T. g$ V! s! X5 _
  4. #ifdef __GNUC__
    - r) l* S( I; _
  5. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    . t, G& f  `+ @7 ]" @
  6. #else: |: ]% K+ N1 ^# F! E$ Y7 L
  7. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)' t! s+ D. _0 y, q; _% r
  8. #endif $ D7 u% [3 v' `5 j* e1 W
  9. PUTCHAR_PROTOTYPE
    $ j3 _, b: W# t
  10. {' k5 B) T0 ~3 M5 a
  11.         HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);' }3 x3 p- r/ V2 m- Z
  12. return ch;
    4 {! S  N: F- B3 B1 z
  13. }
      {' L1 V0 `( X  L
  14. /* USER CODE END PFP */
复制代码
开启串口IDLE中断
( S* `8 f" @/ D; n' c
  1.   /* USER CODE BEGIN 2 */# P5 P1 R2 q  Z0 b' i
  2.         printf("This is a USART DMA Receive Test!!!\r\n");+ V5 a; F6 c" r* M* {7 W
  3.         /*        使能串口1 IDLE中断        */( g3 Y9 K/ o. G
  4.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
    ; F4 l7 u; i+ J7 n
  5.         
    ! U( O6 `) X# V2 P$ Z: i
  6.   /* USER CODE END 2 */
复制代码
while(1)循环
/ Q, w* }, s% P/ m
  1.   /* Infinite loop */4 a1 j3 ^  R- ~/ X4 T* Q+ U' b
  2.   /* USER CODE BEGIN WHILE */
    1 ~$ U, x8 x7 l. }
  3.   while (1)
    2 \  }+ N  b6 |& f9 Z. h0 D% _
  4.   {
    : m8 k1 J7 }& M+ y, ?0 }- a
  5.                 uartdamget();
    8 b4 m/ s; x: D- e8 s
  6.                 4 q' `; \. q& z9 G
  7.   /* USER CODE END WHILE */
复制代码
串口DMA获取
2 _7 M- e' t# _
  1. /* USER CODE BEGIN 4 */
    0 n. g- Y/ b7 |+ g' @6 J, y% c
  2. void uartdamget(void)% V& m1 F. x$ K9 V
  3. {
    : {: X9 M* ~# K$ m
  4.         if(recv_end_flag ==1)9 g0 o$ G, c2 l7 f% m& m
  5.         {
    ( h+ `2 n* D! j; n. l9 p# E
  6.                 /*        打印接收到的数据长度 */
      L' z+ U% g( @" ?" Z- d
  7.                 printf("\nrx_len=%d\r\n",Rx_len);. m- c6 H" O+ W9 t6 t+ V* Q

  8. * t7 q* g3 I4 G# c5 y( ?
  9.                 for(int i=0;i<Rx_len;i++)# ^- @0 y& W- Z3 ^1 {& k
  10.                 {
    9 P* K5 k1 ^0 W/ K
  11.                         /*        打印接收到的数据 */3 W5 ~1 w) @/ X5 R. m$ p
  12.                                 printf("%c",ReceiveBuff[i]);
    ; o! E0 {+ j$ M! x" l
  13.                 }% [0 r6 J) l0 s3 V
  14.                 printf("\r\n");          ; N: ?- O' J  g% N
  15.                 /*        清空接收缓存区        */! H5 |1 J% S) ~% r, X
  16.                 for(int i = 0; i < Rx_len ; i++) 7 `" _( h% }2 |3 f  Z" I
  17.                         ReceiveBuff[i]=0;( S  {: A- H  H! K- l& G+ s
  18.                 /*        接收数据长度清零        */
    6 @! ^/ Y7 F4 n! G6 b0 b
  19.                 Rx_len=0;  e2 R& w& W8 M; a' z
  20.                 recv_end_flag=0;5 x6 x3 N; W' b: p/ o  V& U( T
  21.         }
    $ U5 K8 J# B2 _
  22.         /*        开启下一次接收        */2 i9 j! P/ [' ~9 S8 ?5 x2 I$ M
  23.         HAL_UART_Receive_DMA(&huart1,(uint8_t*)ReceiveBuff,BUFFERSIZE);
    ) r& u( k- D8 ?, ^. v$ f6 U% x
  24. }: g5 O) H/ p! v5 Y: F
  25. /* USER CODE END 4 */
复制代码
#include "stm32f4xx_it.c"文件中断外部变量引用4 i7 q  m0 {6 ^
  1. /* USER CODE BEGIN 0 */$ A- S, M8 q" ?/ ^& r6 [  G
  2. #define BUFFERSIZE 255
    7 U$ K0 G6 S+ g/ C
  3. extern uint8_t recv_end_flag,Rx_len,bootfirst;7 m: J# ?- i- e: }- l
  4. /* USER CODE END 0 */
复制代码
串口1中断函数
  Q  B. p" F. M$ K1 N' e6 S
  1. /**1 t: ~+ N: O. s
  2. * @brief This function handles USART1 global interrupt.1 p' X  |4 g9 V$ W+ n( S& @
  3. */
    2 C/ ^3 J& }+ i& ?1 `% h# j
  4. void USART1_IRQHandler(void)9 L9 j* I, L( t8 g+ L0 h
  5. {6 A" X. H1 F/ ]$ h$ P. b( V
  6.   /* USER CODE BEGIN USART1_IRQn 0 */
    % O9 v( c) X- |
  7. 5 u9 Y9 q! ^$ A5 u) H- A
  8.   /* USER CODE END USART1_IRQn 0 */
    & g" h% V, Z% v
  9.   HAL_UART_IRQHandler(&huart1);
    0 y5 w! o5 T# w0 y7 W( V: u8 ~
  10.   /* USER CODE BEGIN USART1_IRQn 1 */
    8 D- d) b: k4 \& ^+ j: K5 H3 U
  11.         uint32_t temp;# R, H! W. p+ T' D
  12.         /*        如果是串口1中断        */
      F- \6 S* h3 l5 {  E0 C# F" }
  13.         if(USART1 == huart1.Instance)' @9 Y9 V0 D5 M1 e) S5 j
  14.         {        /* 如果是串口1IDLE中断        */6 a& l: T9 k) X+ w
  15.                 if(RESET != __HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)){
    . L3 r6 w% `- q
  16.                         /*        清除中断标志        */
    $ C1 ^) k  t6 |2 [5 f, @6 q
  17.                         __HAL_UART_CLEAR_IDLEFLAG(&huart1);
    / y& N% b1 F9 j" `( I2 r: O
  18.                         /*        停止DMA接收        */& w: E( b+ A- ^" _: @5 ?- d' c
  19.                         HAL_UART_DMAStop(&huart1);* h1 G5 {" J- P. Z% E% u
  20.                         /*        获取DMA当前还有多少未填充        */# X' M1 c- L' |8 i* Y7 S7 k7 {
  21.                         temp  = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    9 o% A. X2 C+ {! H' ?: n0 s
  22.                         /*        计算串口接收到的数据个数        */
    " l& g7 Z# s+ x# I1 A
  23.                         Rx_len =  BUFFERSIZE - temp;
    ) p8 E8 h0 [  W" T3 h/ }  j
  24.                         recv_end_flag = 1;, j8 h* C3 e) w4 i
  25.                 }
    ! ^* T4 s% \+ K9 X+ h4 M( A& u
  26.         }
    * A- Y; Q! j& o5 c5 E9 u
  27.   /* USER CODE END USART1_IRQn 1 */
    0 W( y' ?5 A* p- ^
  28. }
复制代码
将程序下载到板子后,使用串口调试助手发送数据到MCU,
2 B; b0 x, p# X" q8 B# X4 D9 e 1.png ' D$ X6 d0 D' K8 B
下面是源代码$ I- W  T& y, U7 {# U
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
) p3 b$ S. n- E( z7 S亲 你的这个代码 上电  包头掉一个字节  第二次通信正常  是怎么回事

: O8 V& g3 p. Y. A需要启动串口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);
1 O( @! o: N8 k+ ?! w9 ?! S& 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
很好的资料,以前用标准库做过,现在学习一下cube
; b% `1 _4 ?2 a( N
. x( L5 ~9 y. x; }$ V9 z! T, g# p
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

. e( M$ M- K% c好东西, 正需要, 谢谢了
发个人意见 回答时间:2018-7-9 15:33:32
学习学习
12下一页

所属标签

相似分享

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