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

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

[复制链接]
yygkqzh 发布时间:2017-5-3 23:25
本帖最后由 yygkqzh 于 2017-5-4 14:14 编辑
$ _+ A- M4 k' t# _  F: Q$ ]3 I, w" `+ `1 E0 M; R4 C0 C! l1 n
最近买了一块STM32F407的板子,玩了较长时间,开发使用的是STM32CUBE,发现这个软件确实很实用,只要在软件界面进行选择,就可以帮你配置好各项参数。今天根据Paderboy的帖子【NUCLEO-L476RG开发】DMA-ADC1-串口不定长接收,也在自己的板子上搞了一把串口通过DMA方式接收数据,并通过显示接收到数据长度和接收到的数据! F- U; t% O, A3 [
下面上图:/ H: T3 h6 C/ E( ]6 ?5 D
配置时钟为外部高速时钟 1.png ( W- ~. L& }, t3 A) D3 L, C/ c5 ]
配置串口1为异步收发模式
8 s1 u3 C& [+ b 2.png - n# ~6 t$ f. z, y
配置时钟为外部8MHz晶振,配置系统时钟168MHz
2 E. P# e- W) G4 o) K% z 3.png
0 V$ U! Q6 P8 f  z$ _1 f! S配置串口波特率115200,使能发送和接收
, ^, X8 v1 T) W+ ]. W 4.png
4 p8 \) F( b* v6 \& p9 C! z开启串口接收中断) U" V, \; `+ E6 g, z
5.png
# o: l+ a: T8 }/ Q* [使能DMA串口接收9 e8 p+ n- k' X& j4 L. {6 R
6.png   f+ V  N0 k  D9 D* B) @
配置NVIC
6 V( |: p7 T  K. ^ 7.png # H" |) }! f2 H/ |7 L$ ]  U
NVIC生成代码% E& o2 K. R9 Y, v. U
8.png
2 e7 m2 @3 M' v2 F8 {7 J% ]# k& C然后输出代码 ,下面是在生成的代码中添加的。
, e) ^; Y$ h' M9 R* J/ \8 v变量定义
/ [% D- p) m- \5 ?
  1. /* USER CODE BEGIN PV */; N; o& M, N7 [7 W; G
  2. /* Private variables ---------------------------------------------------------*/7 h& Y7 S- U+ b1 @: D
  3. /*        可以接收的最大字符个数        */
    # ?! Y" i! |) G: }0 c+ p
  4. #define BUFFERSIZE 255                                
    ( [: u; v# y) N3 ~9 t+ H' F# {. S
  5. uint8_t ReceiveBuff[BUFFERSIZE];                                                //接收缓冲区
    $ ?* F  [; }* U: k3 U
  6. uint8_t recv_end_flag = 0,Rx_len;        //接收完成中断,接收到字符长度5 ~6 ?2 n% f& b9 h
  7. /* USER CODE END PV */
复制代码
函数声明
& Z5 ]3 z* t  M/ d
  1. /* USER CODE BEGIN PFP */  r$ o9 C) y9 b+ p) ^6 p) X
  2. /* Private function prototypes -----------------------------------------------*/
    0 \) O) O* O' I9 `
  3. void uartdamget(void);3 w. Y2 Z& I% K
  4. #ifdef __GNUC__
    / W, a) t: h3 i
  5. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
    ! C* P/ z: a2 ~6 c" [& y
  6. #else
    % K5 F; h* R4 Z
  7. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)% [" b: s. s( g, y/ G; R  b
  8. #endif
    1 \- d, w6 Y% P2 |/ C
  9. PUTCHAR_PROTOTYPE( r* d& A% n- t" {
  10. {
    3 {1 j/ I) c- j" x# g0 T
  11.         HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);5 G5 R8 a# k2 R/ u5 P
  12. return ch;' W0 A" a) Z% @% j( ^
  13. }5 P3 h( W" }- {! X3 I% e
  14. /* USER CODE END PFP */
复制代码
开启串口IDLE中断7 l, G- v( X. E) F5 a( ^
  1.   /* USER CODE BEGIN 2 */
    8 F+ T% X! \# ]
  2.         printf("This is a USART DMA Receive Test!!!\r\n");
    2 C* B8 u* m8 S2 c
  3.         /*        使能串口1 IDLE中断        */: d* M& J0 d8 a
  4.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
    2 {% K+ V% W0 f: C3 B
  5.         * A' \1 M" l8 M4 V
  6.   /* USER CODE END 2 */
复制代码
while(1)循环
1 _  y+ `5 s; e# B
  1.   /* Infinite loop */8 p4 L9 m1 }3 O  {
  2.   /* USER CODE BEGIN WHILE */' D$ [: H, m0 @( E# @' n* S7 A
  3.   while (1)* B. l% _, A2 r0 f
  4.   {
    ; [& z7 r3 W' r( `, r! o4 X7 M
  5.                 uartdamget();
    2 n! w# i: Y6 n8 v9 i0 U
  6.                 ) q$ N8 r; X  t: [* y
  7.   /* USER CODE END WHILE */
复制代码
串口DMA获取
1 l# K" q$ I6 S) }( g
  1. /* USER CODE BEGIN 4 */; {& e; Z; L( l9 T# ]/ s* x* Q
  2. void uartdamget(void)
    - q( t6 t( L" \4 @
  3. {
    4 t6 a! ^8 F' [$ k; p
  4.         if(recv_end_flag ==1)
    / U  x" i4 M( K
  5.         {- k3 d8 N6 S+ o
  6.                 /*        打印接收到的数据长度 */
    2 e' L& |2 a  j8 R* O' m
  7.                 printf("\nrx_len=%d\r\n",Rx_len);' c8 f$ U2 Z- z! z1 ~8 e/ ?0 c" h% o
  8. % J$ p1 S. C$ p5 n( J
  9.                 for(int i=0;i<Rx_len;i++)+ D! m- p" w( Z3 [2 _7 {' p
  10.                 {
    $ x) h8 G4 l4 b
  11.                         /*        打印接收到的数据 */
    , U* q+ X  H  h5 a
  12.                                 printf("%c",ReceiveBuff[i]);
    2 C% F8 F4 D6 n/ C& D& b: s
  13.                 }
    ( }. A3 ^' j  e/ _
  14.                 printf("\r\n");         
    & i: N( ]3 a9 m" R; q! K9 f
  15.                 /*        清空接收缓存区        */+ S! U* e: @0 |9 t2 |( y3 c
  16.                 for(int i = 0; i < Rx_len ; i++) - s! y, u  i2 |4 m
  17.                         ReceiveBuff[i]=0;  j$ M* G6 L* {$ C7 F
  18.                 /*        接收数据长度清零        */
    4 @9 z# j3 P$ b  o: l+ c+ h1 G
  19.                 Rx_len=0;( F  d* h: `% S  X) O
  20.                 recv_end_flag=0;
    * n. r0 ]. W* Z- _
  21.         }
    3 P  t: j, p7 g
  22.         /*        开启下一次接收        */
    ' N# b- h3 o1 \3 n  S
  23.         HAL_UART_Receive_DMA(&huart1,(uint8_t*)ReceiveBuff,BUFFERSIZE);
    4 I$ W* q9 O+ p
  24. }
    : I2 z0 v1 a: O9 G/ L2 `$ L! I
  25. /* USER CODE END 4 */
复制代码
#include "stm32f4xx_it.c"文件中断外部变量引用
! {$ I  v, F  G; r1 t  b6 a5 q$ M: c
  1. /* USER CODE BEGIN 0 */) I) o; L2 z7 y, w! C# e' T9 S/ i4 o( r
  2. #define BUFFERSIZE 255
    : f. I  i$ ~& U! a* p3 C8 n8 m$ Z
  3. extern uint8_t recv_end_flag,Rx_len,bootfirst;
    + S. r; F$ x3 J# G  J7 I
  4. /* USER CODE END 0 */
复制代码
串口1中断函数" d. J( u- S) v. C: |
  1. /**- U( m3 O' Q* N/ ~7 e
  2. * @brief This function handles USART1 global interrupt.
    + v3 ^8 Y2 J1 n1 h3 y
  3. */9 }! L4 f$ q8 F
  4. void USART1_IRQHandler(void)( l+ Z' M6 e8 R2 K: L
  5. {& }' \6 [8 o4 t  G3 J" p
  6.   /* USER CODE BEGIN USART1_IRQn 0 */! {+ V1 V6 b% K- i# S/ _

  7. ; Q& S$ F3 x1 G9 S9 I+ e. ]- m
  8.   /* USER CODE END USART1_IRQn 0 */
    ! q6 {% I/ I! n/ D
  9.   HAL_UART_IRQHandler(&huart1);
    + _/ e; j& {& m  r* a
  10.   /* USER CODE BEGIN USART1_IRQn 1 */
    0 t9 @9 q! Y$ e% n2 C( U
  11.         uint32_t temp;6 B" T  G! n( W5 g$ U8 P* i7 x; p
  12.         /*        如果是串口1中断        */
    ( Q5 |! s1 j+ m% w$ u* Q7 X
  13.         if(USART1 == huart1.Instance)
    / s  T% r& A  g
  14.         {        /* 如果是串口1IDLE中断        */
    1 e2 e4 @) R' B
  15.                 if(RESET != __HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)){
    ) o2 |+ t9 b9 H6 q% |3 R
  16.                         /*        清除中断标志        */& P( E8 J" u' j
  17.                         __HAL_UART_CLEAR_IDLEFLAG(&huart1);/ G( z' S: Y9 f& ^; I8 `, S% d5 u  K
  18.                         /*        停止DMA接收        */
    , t4 Q" T$ T* m7 _0 l
  19.                         HAL_UART_DMAStop(&huart1);
    7 d* G/ I% `" _; c
  20.                         /*        获取DMA当前还有多少未填充        */( l: J+ s% E" N. C0 U( D' ]/ _* T7 p
  21.                         temp  = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);2 |( K/ y+ N8 q; m0 i& k" H
  22.                         /*        计算串口接收到的数据个数        */" e: `) }% I0 k! |
  23.                         Rx_len =  BUFFERSIZE - temp; 5 A3 p. n4 {+ E7 U2 V
  24.                         recv_end_flag = 1;
    3 F6 q! q- f0 E- d
  25.                 }
    + q' m1 _+ G) U: Q/ V' r8 _1 I
  26.         }
    8 d, V" D' K+ W; T/ ?% P+ ?, }  f
  27.   /* USER CODE END USART1_IRQn 1 */* I8 f- z8 ~* p, p3 z  ?7 M( d& O
  28. }
复制代码
将程序下载到板子后,使用串口调试助手发送数据到MCU,# c6 z8 z7 O! I4 X
1.png % o# H. Y( m! x/ [8 H
下面是源代码7 p, [/ y! d( P& [# U. ^: S8 y
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 G: n. s  N1 i  [+ a6 X
亲 你的这个代码 上电  包头掉一个字节  第二次通信正常  是怎么回事

3 P9 T6 C# p+ A0 S& F7 Q需要启动串口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);
& J6 [- e* X" `" u1 z! c9 J6 n不然第一帧会错,实测!!!
假装微风 回答时间: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
1 l/ E$ q9 Q/ v9 t( q0 S9 Z  d5 G, ?( ?5 ~
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

$ L: T+ s7 U( m% L, ~- l8 l1 C/ n好东西, 正需要, 谢谢了
发个人意见 回答时间:2018-7-9 15:33:32
学习学习
12下一页

所属标签

相似分享

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