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

基于STM32CUBEME接收不定长数据之USART定时器经验分享

[复制链接]
攻城狮Melo 发布时间:2023-4-15 16:48
概述
   本文利用中断实现串口不定长接收(非DMA),使用HAL库,将接受的数据打印出去。

4 W, x8 ?9 q9 Z6 s  _, J
硬件准备
    首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:   
2 D2 a* {# c6 G

8 k& J! }# ?5 Z) O
微信图片_20230415164627.jpg
9 s* F; Y+ b; a! j5 s
选择芯片型号
       使用STM32CUBEMX选择芯片stm32f030r8,如下所示:

2 r* {' N0 n6 C" J5 s
微信图片_20230415164623.png

& `3 h2 B' ]4 {配置时钟源
    HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:
7 z- e1 e+ j9 Z& P8 Z) |
/ X/ K8 A8 p8 b* A8 {' {, f  r
微信图片_20230415164620.png
9 Z! @) s+ Y1 _8 v4 i1 E* V9 P
配置时钟树
    STM32F0的最高主频到48M,所以配置48即可:
6 A& l/ r& ]$ F6 W& J
' I/ N  i6 g0 Q5 |+ P9 S" b
微信图片_20230415164614.png
3 N; `  _& k' r6 o, u1 v% ^
串口配置
    本次实验使用的串口1进行串口通信,波特率配置为115200。) x4 Z' |1 [. y4 ]2 Z

3 ?0 D- C0 T$ k
微信图片_20230415164611.png

& u0 X( i7 \/ s. i: l1 m" t8 z
    中断5 E1 ^* k# h7 L

8 B9 g7 y9 g' [1 C4 m4 w
微信图片_20230415164607.png
. B) a! Z' Q0 U
GPIO配置
    板子上led为PA5端口,故设置PA5闪烁来验证是否正确。
+ T$ ?4 w$ `* @: T5 @/ m3 ^

/ O/ `+ Y/ _1 S
微信图片_20230415164604.png

' C+ k3 M8 N4 {4 \) y
定时器配置
    本次实验使用的是TIM3来进行计数。
6 y# {" X# p% L) q

% f3 m$ Z$ ^: M2 v" x4 _
微信图片_20230415164601.png

4 w5 U; @( X0 p+ ^
    PWM频率计算如下所示。

7 q0 l* q9 m  m9 p
微信图片_20230415164558.png
1 Y  ?) G8 z$ N" s6 D# G
    在上面配置TIM3参数,预分频系数设置为480-1, 自动重载值设置为10000-1,那么PWM频率为48,000,000/((480-1+1)*(10000-1+1))=10Hz,即 100ms一个周期。& T1 d7 y- E' m6 U* R, l" ]5 h

/ Y" Y/ [! x4 _/ ^* F生成工程设置
    注意在生产工程设置中不能出现中文,不然会报错。3 p0 p+ L: ^  A( N8 j
9 A4 R1 P1 T, {6 V* ?
微信图片_20230415164553.png
' ^$ s) H) l- F6 \: ?4 J
代码生成设置
    最后设置生成独立的初始化文件:$ s: W7 m/ l" b; C
: ?8 C, V. m0 w" }% b% Y1 Z
微信图片_20230415164550.png
: \) t8 ]" e0 ~+ B
生成代码
, k; I- v# y0 G. ^$ b1 J! @% I+ O
  q. ]# I& M" Y( e$ s4 K  Q
微信图片_20230415164541.png
6 P& R# B" q6 p7 b
配置keil
微信图片_20230415164538.png

0 R. h; X+ S# J8 i
微信图片_20230415164511.png

, P6 E  L, i: N5 P
! |7 X* l$ J$ y代码
    在main.c中,先加入头文件。
  1. /* USER CODE BEGIN Includes */
    : b4 S5 ~, k' s, |6 W  {  x! v- l
  2. #include "stdio.h"//printf头文件
    7 s8 M9 H3 D" T; v' |
  3. #include "string.h"//memset头文件7 Z: }$ {% Q- @* W! ~
  4. /* USER CODE END Includes */
复制代码

+ C& {3 R& k7 P  O
    定义变量存储。
  1. /* USER CODE BEGIN PV */" q3 ~/ f4 X! C' R& O
  2. uint8_t RxBuff[1];      //进入中断接收数据的数组& M9 U, I$ u/ m+ U1 k
  3. uint8_t DataBuff[5000]; //保存接收到的数据的数组
    1 Y: F* w4 r' u% ^
  4. int RxLine=0;           //接收到的数据长度  E) r+ M3 z1 c/ K5 j
  5. int Rx_flag=0;          //接受到数据标志
    $ s9 }+ k) y, b* i6 w
  6. /* USER CODE END PV */
复制代码

5 h9 Q8 v) ?/ ^( T: @% f, N7 Y" K
    定义printf的重定向函数fputc。
  1. /* USER CODE BEGIN 0 */: N9 r9 Y% R- D6 ]
  2. void printf_usart(void);//输出内容" d2 c( C( g2 H4 u  u  C# x+ q
  3. int fputc(int ch, FILE* file)//定义printf的重定向函数fputc,满足串口调试打印9 i8 g0 Q# ?" V& O. Q* P
  4. {  A& Y$ s$ _9 _& p
  5.     return HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 100);) w% X! H8 W3 l5 B
  6. }
    / P9 w2 w  O: \( p& C
  7. /* USER CODE END 0 */
复制代码
   
打开串口和定时器。
  1.   /* USER CODE BEGIN 2 */* k# X. X# h4 x4 `4 A
  2.   HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuff, 1); //打开串口中断接收9 k# A( i$ B+ a" q# u, d
  3.   HAL_TIM_Base_Start_IT(&htim3);//开启定时器
    9 \/ U! V3 N- e6 o% i- C" M* t+ z
  4.   /* USER CODE END 2 */
复制代码

- T) `! |5 S) J6 ~8 Y
    串口接受代码,当接受到最后数据为FF时候,直接打印,否则等待100ms打印。
  1. /* USER CODE BEGIN 4 */
    ; x! @9 d! T4 J0 Q: f
  2. void printf_usart(void)
    4 \3 j& I+ z  g9 f, X1 O
  3. {8 l+ U3 |$ E6 M) a
  4.   printf("数据长度=%d\r\n",RxLine);
    : ~4 D& b5 w; i) V
  5.   for(int i=0;i<RxLine;i++)1 H- r1 \2 Y; P& K
  6.     printf("数据:[%d] = 0x%x\r\n",i,DataBuff[i]);                            - z, q& I! K8 ]# c% t8 s; x0 U
  7.   memset(DataBuff,0,sizeof(DataBuff));  //清空缓存数组
    # i* {5 c8 K( A
  8.   //memset()作用:可以方便的清空一个结构类型的变量或数组。
    : T, L5 Y: |% e0 y1 N: m
  9.   //例句:memset(aTxbuffer,0,sizeof(aTxbuffer))  用memset清空aTxbuffer。9 a7 k9 H# H+ e5 s0 c! y
  10.   RxLine=0;  //清空接收长度+ F' }* M$ l% t) l1 [& Y; A
  11. }
    8 J5 f( ]# ?" f! _
  12. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)6 z: K$ c  _+ K8 N
  13. {
    ) P6 ~6 z$ n3 x& I5 g5 e  y# Y
  14.     if (htim->Instance == htim3.Instance)
    2 ?; @8 c9 I  x/ }1 ?& h2 c
  15.     {
    & Q5 \( S+ P. K% Y# G/ @0 d3 l6 ]- f
  16.       HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);5 v% h/ K8 T/ ]4 g* ~
  17.         /* Toggle LED */
    1 g4 R, z9 P$ v2 g
  18.       if(Rx_flag==1)3 N4 y; a' t7 \) }
  19.       {( a  l% M; n% [9 E# Q
  20.         printf_usart();
    2 [$ P- K6 O, \
  21.         Rx_flag=0;
    / Z/ d: L- e3 n$ X/ M
  22.       }
    . M; o7 @& B4 Z  t7 M
  23.     }  
    : S+ I* c% L9 u) o
  24. }
    4 ^9 ^+ w% r" ~
  25. // 捕获中断回调函数,每次捕获到信号就会进入这个回调函数
    , ]$ h+ C/ }3 Y( V/ I
  26. void HAL_UART_RxCpltCallback(UART_HandleTypeDef*UartHandle)
    3 U- ?! F$ i3 J# H1 X
  27. {' b5 H8 g% A3 P: U: D- t$ D
  28.     RxLine++;                      //每接收到一个数据,进入回调数据长度加1
    $ {2 F' T6 [9 K# C
  29.     DataBuff[RxLine-1]=RxBuff[0];  //把每次接收到的数据保存到缓存数组. U$ q. p4 g- L( H0 j2 v. G
  30.     Rx_flag=1;- ]1 @7 q# g% N$ ~+ o2 L6 m
  31.     if(RxBuff[0]==0xff)            //接收结束标志位,这个数据可以自定义,根据实际需求,这里只做示例使用,不一定是0xff$ [% B, N" R0 j
  32.     {6 ^; V. K1 n1 V. R3 X
  33.       printf_usart();2 s0 ?0 ]9 v8 u8 o
  34.     }   
    ( H5 w' i! s2 A. S( i8 A# d
  35.     RxBuff[0]=0;
    . n- z5 [( @  \- x, u
  36.     HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuff, 1); //每接收一个数据,就打开一次串口中断接收,否则只会接收一个数据就停止接收* O& J4 `% r7 m8 d) H5 Q; M
  37.     __HAL_TIM_SET_COUNTER(&htim3, 1); // 计数清零,从头开始计
    8 `  H& P* `5 {; \; O
  38. }& x0 U9 u4 T) e9 Z2 M0 Z# |8 [: I
  39. /* USER CODE END 4 */
复制代码

. w  U6 A% n5 ^- x: m8 z
* ?2 u9 G# ], p
演示效果
    可以看到  发送11 12 13需要等待100ms左右才能发送,如果最后加上ff直接发送。

1 O3 o( g7 [( N) a
微信图片_20230415164508.png

+ ?4 p/ }; W+ f* Y: p
转载自:记帖
如有侵权请联系删除
/ ]- O9 S( l. H
4 n' m- c+ E( v+ P4 m8 @
/ Z% R' p$ L0 }- K
赞 收藏 评论0 发布时间:2023-4-15 16:48

举报

0个回答

所属标签

相似技术帖

官网相关资源

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