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

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

[复制链接]
yygkqzh 发布时间:2017-5-3 23:25
本帖最后由 yygkqzh 于 2017-5-4 14:14 编辑 0 I4 r% @% U/ ]
" ]% M+ H3 q- B# e( }7 }! l8 M
最近买了一块STM32F407的板子,玩了较长时间,开发使用的是STM32CUBE,发现这个软件确实很实用,只要在软件界面进行选择,就可以帮你配置好各项参数。今天根据Paderboy的帖子【NUCLEO-L476RG开发】DMA-ADC1-串口不定长接收,也在自己的板子上搞了一把串口通过DMA方式接收数据,并通过显示接收到数据长度和接收到的数据" o) ]) p* W9 `* R
下面上图:
0 E9 [) M3 y$ F& h配置时钟为外部高速时钟 1.png
' f. b" y0 i/ @4 O" D配置串口1为异步收发模式% m! ]2 U) X( Q7 }
2.png - y: U. e1 d6 f5 Y
配置时钟为外部8MHz晶振,配置系统时钟168MHz
6 V8 k0 A8 y% K9 a% H 3.png
8 f0 T. t3 m; M# J3 v5 i配置串口波特率115200,使能发送和接收/ M# _7 n& ]9 y' m1 y; a
4.png
( o  _' i, b% n0 d% K开启串口接收中断7 G& q& I0 X! \! ^  h
5.png
# J1 V$ J: Q2 R) O, Y使能DMA串口接收
1 Q  O. v) R: r: i/ Y6 d 6.png
: n0 d7 c; W. Z& [' v配置NVIC
) L" X0 E( s; c8 r 7.png & O2 P* i* l& a7 W! t/ {/ ~
NVIC生成代码
* Z3 c1 t+ t, R) C! I+ w1 \9 Q 8.png
; i) \, S: X% `然后输出代码 ,下面是在生成的代码中添加的。
+ U  z$ N6 J, s$ Z变量定义
" U) D6 D, n# M: ?: j( G: M7 E
  1. /* USER CODE BEGIN PV */. O' s0 s3 X7 Z. l
  2. /* Private variables ---------------------------------------------------------*/
    ( V2 \' n! L; l- H' {
  3. /*        可以接收的最大字符个数        */
    ( r# Z! ]/ }8 c1 o
  4. #define BUFFERSIZE 255                                / n  C  Z5 r& W* _# D1 ~0 Q
  5. uint8_t ReceiveBuff[BUFFERSIZE];                                                //接收缓冲区
    " b; [* [7 a: Z
  6. uint8_t recv_end_flag = 0,Rx_len;        //接收完成中断,接收到字符长度# X& l0 I! b( m9 c3 V/ M
  7. /* USER CODE END PV */
复制代码
函数声明2 x" b1 b3 a" h% x/ b8 B
  1. /* USER CODE BEGIN PFP */) E" h4 n' v6 A
  2. /* Private function prototypes -----------------------------------------------*/
    % z  ~! H5 g# S& `
  3. void uartdamget(void);
    - U! ~2 |' }, h: W9 b- W
  4. #ifdef __GNUC__
    " U& t/ X0 x5 e$ t5 f7 q5 c
  5. #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)  p) M* F; C1 I. K" k5 N' Z
  6. #else1 Z; j+ w6 l* U9 L) ~9 A! Z
  7. #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)- K- V+ \' [: Z5 @( |! N) C( i
  8. #endif - l  ~- S4 L) N. c: m
  9. PUTCHAR_PROTOTYPE* g2 y: F6 S4 Z, R
  10. {- J% N2 s  n1 J
  11.         HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);9 m( O$ x& o8 d/ H4 l
  12. return ch;
    * o" A% A: g4 T, ?
  13. }
    0 h7 j9 Y" e( O9 ?: d0 J; e& J
  14. /* USER CODE END PFP */
复制代码
开启串口IDLE中断
0 O. y: o2 w) H3 m  ], f1 L, d
  1.   /* USER CODE BEGIN 2 */
    5 o, i% N: K  k
  2.         printf("This is a USART DMA Receive Test!!!\r\n");; `7 ~6 r6 R4 n
  3.         /*        使能串口1 IDLE中断        */) J. R, i8 D; Y6 q5 H6 X
  4.         __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE); , K; r/ S7 ?1 N, y1 g) b* k
  5.         ( g; t0 C2 @% S. M( s- @, ^7 ?" \
  6.   /* USER CODE END 2 */
复制代码
while(1)循环
3 ?! e6 x( X: P5 X8 i6 i
  1.   /* Infinite loop */
    ( T: y8 K2 n1 S. E
  2.   /* USER CODE BEGIN WHILE */  a% f" ^/ i- c' D' k! l; k9 J
  3.   while (1)2 c& J( J! v3 ^+ E+ N8 H! M& q
  4.   {
    $ b  i, j! V1 m3 @* e! m
  5.                 uartdamget();0 w1 t" K& i5 A7 ?
  6.                
    * ^5 H( n0 B) L  N: J
  7.   /* USER CODE END WHILE */
复制代码
串口DMA获取  v& `* |3 _9 ]& @! z; T; d1 |7 W. w
  1. /* USER CODE BEGIN 4 */
    * o2 z0 G' H; j* [6 a% `
  2. void uartdamget(void)
    0 |9 T. D; F  p9 ^3 e1 O2 p4 |: h
  3. {  @- F# ^7 S! j5 n: u0 h
  4.         if(recv_end_flag ==1)8 N4 k$ `2 h  w! t8 P( S) _1 T
  5.         {
    5 g- J. e% \, W) b/ M
  6.                 /*        打印接收到的数据长度 */
    ! b+ k' B1 n) F  B
  7.                 printf("\nrx_len=%d\r\n",Rx_len);% ~2 V$ ^: T+ h) R) P

  8. / x4 G1 _9 ^, i, Q  c
  9.                 for(int i=0;i<Rx_len;i++); \) F4 X2 w2 A  Q3 p: F
  10.                 {8 C( l; p& M. I8 I5 V5 G. G6 x
  11.                         /*        打印接收到的数据 */
    ! {3 E. m/ G1 w0 R- I2 }( Y
  12.                                 printf("%c",ReceiveBuff[i]);
    , v+ t$ v% E1 I6 ^! m5 M( A
  13.                 }( {8 T% }" a( K9 G& M' O
  14.                 printf("\r\n");          - e- N# l! @" [( y  A3 H! ?4 O& }
  15.                 /*        清空接收缓存区        */  o# [1 f3 ~# O" m/ r! d. i  o
  16.                 for(int i = 0; i < Rx_len ; i++)
    " Z5 ?5 f  ]6 P5 X
  17.                         ReceiveBuff[i]=0;
    & m4 Y; l- c' F5 F2 s
  18.                 /*        接收数据长度清零        */5 r# l8 c& O8 r( V/ g2 I5 R# a
  19.                 Rx_len=0;4 F2 a9 t% h% w  ?8 }7 P3 p
  20.                 recv_end_flag=0;  o4 n" F4 j5 l
  21.         }' t4 H0 P& Y+ t. @! F! s
  22.         /*        开启下一次接收        */# P# l1 F6 m8 x5 E2 `  h
  23.         HAL_UART_Receive_DMA(&huart1,(uint8_t*)ReceiveBuff,BUFFERSIZE);
    ' d7 x/ D- s1 P9 ?! n# O3 ]
  24. }
    ! J3 `: J6 Q2 @( }  }
  25. /* USER CODE END 4 */
复制代码
#include "stm32f4xx_it.c"文件中断外部变量引用
2 N5 Q# @( Y9 B: f; u
  1. /* USER CODE BEGIN 0 */
    % d1 k5 ]2 E+ ^5 R) M4 Q
  2. #define BUFFERSIZE 2559 f0 |, O1 u2 H- N% |. v- j
  3. extern uint8_t recv_end_flag,Rx_len,bootfirst;" A$ _* N' z6 l" P- r
  4. /* USER CODE END 0 */
复制代码
串口1中断函数
' ?7 w( Y: q1 R7 k8 |
  1. /**& r, l- M8 o( Q8 M/ S
  2. * @brief This function handles USART1 global interrupt.% E4 g  b) b" {
  3. */9 V: d1 Y9 A, {' M7 {, c
  4. void USART1_IRQHandler(void)
    * `- p! Y6 b% m; G. }7 ?  G
  5. {
    6 l( Z" V$ b$ M& o, X9 }- a) Z
  6.   /* USER CODE BEGIN USART1_IRQn 0 */" @; a1 Z4 I2 d
  7. . X0 j/ G! r; {
  8.   /* USER CODE END USART1_IRQn 0 */3 Z  P( ~2 U  Z) p1 }9 O: x# p) E% N
  9.   HAL_UART_IRQHandler(&huart1);2 {- d' m+ E! R, Y3 v) t
  10.   /* USER CODE BEGIN USART1_IRQn 1 */
    + [/ p. x+ ^. C" U( K2 ~1 K
  11.         uint32_t temp;0 Q# p' s* |# i
  12.         /*        如果是串口1中断        *// C+ Y8 ~9 w3 g
  13.         if(USART1 == huart1.Instance): v% c( S& k9 [8 y1 T0 H8 i
  14.         {        /* 如果是串口1IDLE中断        */
    & S) ]1 {, G5 ]2 [
  15.                 if(RESET != __HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE)){5 r* @+ N& w1 T( x4 E9 r
  16.                         /*        清除中断标志        */
    $ k3 I2 `% I5 A! \$ D  f
  17.                         __HAL_UART_CLEAR_IDLEFLAG(&huart1);
    : E' C, n/ i; z* @
  18.                         /*        停止DMA接收        */) K$ ~5 N3 u( I, y; o0 Z
  19.                         HAL_UART_DMAStop(&huart1);
    ' t& ^  o0 r! y) Q0 Q' q; o2 |: \
  20.                         /*        获取DMA当前还有多少未填充        */8 l' E# \) k" F( z. |- ]
  21.                         temp  = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
    0 q4 b7 W1 U6 }' ]
  22.                         /*        计算串口接收到的数据个数        */
    & `* t# K$ z1 R
  23.                         Rx_len =  BUFFERSIZE - temp; $ x0 X- ]& O" Y$ G# l; e9 }5 M
  24.                         recv_end_flag = 1;
    ; h! Y& r; }4 h% e$ N& C3 j
  25.                 }7 i9 I2 h  k! X5 P$ S! _! D
  26.         }
    8 u1 C& R, M  p$ P0 G
  27.   /* USER CODE END USART1_IRQn 1 */% H6 E0 v- \3 ]* B! q" Z' e6 r
  28. }
复制代码
将程序下载到板子后,使用串口调试助手发送数据到MCU,
( B' R( Q: l9 O% a! v1 d+ c) z 1.png ! f' t7 Q/ g0 d% R, G
下面是源代码
+ r: s, B! E6 r/ A( ^7 w/ b3 ]6 m 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:225 k; [* D; c  L6 a% ~) B  v2 r
亲 你的这个代码 上电  包头掉一个字节  第二次通信正常  是怎么回事

6 {9 z) [1 l# W  r' f需要启动串口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);9 n* L2 a  n# {8 x# N9 c
不然第一帧会错,实测!!!
假装微风 回答时间: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
( A8 z( D7 T+ |
. c1 _7 x4 R/ q3 ]5 u
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
# G9 i6 b9 o) e& T$ x( U
好东西, 正需要, 谢谢了
发个人意见 回答时间:2018-7-9 15:33:32
学习学习
12下一页

所属标签

相似分享

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