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

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

[复制链接]
yygkqzh 发布时间:2017-5-3 23:25
本帖最后由 yygkqzh 于 2017-5-4 14:14 编辑 % X' y! Q& N: \" |

+ O3 Z3 a% }6 @2 K最近买了一块STM32F407的板子,玩了较长时间,开发使用的是STM32CUBE,发现这个软件确实很实用,只要在软件界面进行选择,就可以帮你配置好各项参数。今天根据Paderboy的帖子【NUCLEO-L476RG开发】DMA-ADC1-串口不定长接收,也在自己的板子上搞了一把串口通过DMA方式接收数据,并通过显示接收到数据长度和接收到的数据。; E( b, Q0 Z- p
下面上图:
  C- p* i; Z6 H% h4 _- F9 n+ J配置时钟为外部高速时钟 1.png + H6 ]0 G. |  c
配置串口1为异步收发模式
2 Y4 I! S7 G5 d! I6 S- } 2.png
3 r& Q" ]8 {% G6 Z3 g; ?+ s% `( G配置时钟为外部8MHz晶振,配置系统时钟168MHz
& r" Q$ ]% q% l3 {* [, R: t1 ` 3.png : T, v. [* h, i8 D$ z' w3 l
配置串口波特率115200,使能发送和接收1 V; D8 P1 f! W0 v9 J
4.png 5 U+ \# I1 }- e* k6 x
开启串口接收中断
* |" y3 a7 B4 L" o* ]0 t; g 5.png 2 V" u4 k: Q! T4 ]
使能DMA串口接收
3 V7 c/ M+ \( h$ b 6.png
" v  j3 e$ x- r+ H# O+ {5 g配置NVIC
) @, z* @4 g* r; ^% F 7.png   e8 _, u& Z  U& i
NVIC生成代码+ W# ~' Q: M  D8 x+ u. X1 [
8.png
' z/ X# u: A& i! x6 P然后输出代码 ,下面是在生成的代码中添加的。! p7 {/ W6 N" f0 Y
变量定义6 |" n# c( |. O. ]" S. {' Z
  1. /* USER CODE BEGIN PV */
    8 @/ `9 R* N- B) h
  2. /* Private variables ---------------------------------------------------------*/# Q4 T+ Z' ]% A6 m& m# c
  3. /*        可以接收的最大字符个数        */) A% U9 u* d3 @# M
  4. #define BUFFERSIZE 255                                . `5 B+ b6 K9 E1 D9 B
  5. uint8_t ReceiveBuff[BUFFERSIZE];                                                //接收缓冲区
    1 w1 n; d, S1 ?7 r( D+ r6 p: c( b0 Q6 O* j
  6. uint8_t recv_end_flag = 0,Rx_len;        //接收完成中断,接收到字符长度  \; A; x# j! [  P
  7. /* USER CODE END PV */
复制代码
函数声明7 z1 E4 Y+ ~0 S
  1. /* USER CODE BEGIN PFP */
    0 W& D9 _5 c* I5 \; b% \* J8 j
  2. /* Private function prototypes -----------------------------------------------*/* C: B$ r' Z5 T! n4 X8 p4 |
  3. void uartdamget(void);' q9 y7 c4 f2 m* m6 {
  4. #ifdef __GNUC__
    & e* ]) i" \" Q' T" a7 x$ G
  5. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    1 ?4 L( m( K2 h- z! O7 b  L
  6. #else3 i& I, S$ J+ v) D
  7. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f), M4 o( h  ^# U1 K* {7 x
  8. #endif 6 h' C% [/ N) R) W0 X
  9. PUTCHAR_PROTOTYPE
    2 z/ {+ s& |: V" ~4 _# c; o
  10. {
    * l( b6 @4 `1 H+ ?" U
  11.         HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);1 q& c4 v, ?- \8 p8 c" ]
  12. return ch;
    6 I) t9 j4 J7 B( A5 m' I
  13. }+ v6 `. k% B' V3 |! h* u
  14. /* USER CODE END PFP */
复制代码
开启串口IDLE中断/ B. \! E5 z8 i3 [4 H- F$ X
  1.   /* USER CODE BEGIN 2 */8 W- H/ A1 R" I  v' w
  2.         printf("This is a USART DMA Receive Test!!!\r\n");9 X' h# p. M5 L- N8 ]
  3.         /*        使能串口1 IDLE中断        */- R. U/ Z6 i& U( Q6 T  H1 ~% f
  4.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
    : S4 n% b9 ]0 F! b, ]4 q
  5.         
    / l6 U' F. g$ B; q; |; t; l2 d
  6.   /* USER CODE END 2 */
复制代码
while(1)循环
3 Y2 A, o7 Y% g' h1 I4 e- Q
  1.   /* Infinite loop */- B* q. e) Y+ x) i3 e
  2.   /* USER CODE BEGIN WHILE */
    , n! G9 M0 `! A7 ~( f
  3.   while (1)$ R- j* v, O( Y! D. W
  4.   {8 f  v) K9 b' I( o
  5.                 uartdamget();* [) }4 f' q/ l% A
  6.                 ) J4 b8 Y2 K7 `6 V2 f* v
  7.   /* USER CODE END WHILE */
复制代码
串口DMA获取
2 V8 K9 @* k3 F) f7 r/ |& m
  1. /* USER CODE BEGIN 4 */* A" n9 e9 x) I: ?' c
  2. void uartdamget(void)' e( u% Z) p3 [, @$ D
  3. {
    ( l+ |" u- T$ Q8 l, F) Q3 n. B; }& e
  4.         if(recv_end_flag ==1)3 s4 j4 }  U  b
  5.         {
    & {/ P- {/ e8 ^) o$ H( i9 ]
  6.                 /*        打印接收到的数据长度 */9 `) W5 R8 u& P# c5 k8 P# k
  7.                 printf("\nrx_len=%d\r\n",Rx_len);, c8 t/ I6 L3 g4 R* H0 _

  8. 1 [. A* z0 Y. D3 U8 n0 x8 x  C( |
  9.                 for(int i=0;i<Rx_len;i++)
    - w# P& X% x: R( F" {7 N
  10.                 {
      H- M8 x0 t5 V, e$ L: j
  11.                         /*        打印接收到的数据 */
      U& G/ h- u% c% o5 b- V
  12.                                 printf("%c",ReceiveBuff[i]);
    # U' |/ e- E) q& @& |( X# J
  13.                 }, q$ n2 p& D9 z, A# a
  14.                 printf("\r\n");          % P8 W& K' `( Q$ o1 s5 b
  15.                 /*        清空接收缓存区        */
    , l' x4 @& f, N+ n2 a
  16.                 for(int i = 0; i < Rx_len ; i++)
    ' z' B! b5 [8 P/ G8 i1 y$ s) ~
  17.                         ReceiveBuff[i]=0;  g: d, t, c; i
  18.                 /*        接收数据长度清零        */: q, E+ H% A9 F  o
  19.                 Rx_len=0;
    / W0 X  o" C% n
  20.                 recv_end_flag=0;
    5 G( W7 [; y4 E: `4 v6 ]
  21.         }
    9 u" S* r5 Y: y' ~, f
  22.         /*        开启下一次接收        */
    % U$ o) e! d6 {* d/ c9 E8 Q. l. u
  23.         HAL_UART_Receive_DMA(&huart1,(uint8_t*)ReceiveBuff,BUFFERSIZE);) x# g; a* b. @' I3 ^( u( z  v
  24. }
    + D: ]' b2 R& H2 h$ U1 o
  25. /* USER CODE END 4 */
复制代码
#include "stm32f4xx_it.c"文件中断外部变量引用3 ]# X2 X0 Q# o2 t
  1. /* USER CODE BEGIN 0 */" L' Q$ ~9 w( l; E# \$ l& f! A# w/ }* p
  2. #define BUFFERSIZE 255
    " z0 ?" c* w# y  n( m5 c
  3. extern uint8_t recv_end_flag,Rx_len,bootfirst;
    1 x+ M" e& ]1 F
  4. /* USER CODE END 0 */
复制代码
串口1中断函数9 l( m  Y6 O5 o0 j2 @; U. z
  1. /**
    * m) y" V3 j& N; o$ u# [
  2. * @brief This function handles USART1 global interrupt.
    ! y/ g2 w/ U& a' }3 |- i7 ~
  3. */
    # K9 h; J( B0 z4 L
  4. void USART1_IRQHandler(void)
    5 q! B7 I0 q) l' G9 h
  5. {; _, D% _+ M4 m1 l, W1 n" F
  6.   /* USER CODE BEGIN USART1_IRQn 0 */
    4 m8 t: d) ~9 u" P( `9 p
  7. ; l0 C( @) B' a$ w% U! D. n
  8.   /* USER CODE END USART1_IRQn 0 */
    # Z' \0 Q6 M1 F* a$ J! e3 s. @7 r
  9.   HAL_UART_IRQHandler(&huart1);9 \$ g( c8 E" Q
  10.   /* USER CODE BEGIN USART1_IRQn 1 */
    . _" w8 C; [: s& Z7 k$ S
  11.         uint32_t temp;& O* m8 g0 H: ~* o) b
  12.         /*        如果是串口1中断        */& ~/ R1 K/ N$ a0 t' p6 F
  13.         if(USART1 == huart1.Instance)
    ! @: J1 ~. P8 p; h/ C: N! M
  14.         {        /* 如果是串口1IDLE中断        */6 u) L. j' a4 O0 V" I/ D4 y
  15.                 if(RESET != __HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)){, t& C1 O4 J( N( `
  16.                         /*        清除中断标志        */9 q$ c! ~- _% l  I& B
  17.                         __HAL_UART_CLEAR_IDLEFLAG(&huart1);
    3 a* F0 C/ ^. o8 c
  18.                         /*        停止DMA接收        */  Z: V+ W7 A! v4 R
  19.                         HAL_UART_DMAStop(&huart1);* P0 y5 D7 z. ?
  20.                         /*        获取DMA当前还有多少未填充        */
    2 u7 D  x- d, A0 Z& Z
  21.                         temp  = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    - k. c. q; _, U
  22.                         /*        计算串口接收到的数据个数        */
    ! a0 {0 _- |0 Z1 b5 q( `4 }& F* ?+ s
  23.                         Rx_len =  BUFFERSIZE - temp;
    6 c& r3 Z7 {% D$ N- f/ Q8 J
  24.                         recv_end_flag = 1;# K8 D" M5 ~2 e. m+ w  I% h% g
  25.                 }
    ; j( L: p" A$ u% j3 V) J% v1 Q
  26.         }
    1 ?3 v7 e! @/ D3 h' l9 B
  27.   /* USER CODE END USART1_IRQn 1 */7 Z9 E* h( v# d. b( H1 s5 o
  28. }
复制代码
将程序下载到板子后,使用串口调试助手发送数据到MCU," b1 J* @( B4 V4 o' c7 j
1.png 1 O) y+ [9 f: Y' c; Q  Y3 w
下面是源代码
2 K; r7 P" p# c, G* T9 m' q 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$ d3 j) G2 L  W, Q7 Z
亲 你的这个代码 上电  包头掉一个字节  第二次通信正常  是怎么回事
3 p3 d2 P% e/ ^* _$ ^
需要启动串口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);8 B' I+ f& [4 H( ]
不然第一帧会错,实测!!!
假装微风 回答时间: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) k3 W  F+ y" W( V2 @
6 I9 [# j' r8 v% P) P' c2 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

; b: l& x. E1 ^7 Y好东西, 正需要, 谢谢了
发个人意见 回答时间:2018-7-9 15:33:32
学习学习
12下一页

所属标签

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