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

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

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

# w  a$ P( N, O
硬件准备
    首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:   
! t8 o3 v3 h& Q' c/ S/ P

/ j  \6 n! A1 u1 _; o
微信图片_20230415164627.jpg

: v$ |0 I5 M: T; T, b& X, q6 J8 p2 V选择芯片型号
       使用STM32CUBEMX选择芯片stm32f030r8,如下所示:

3 R( V8 t# N$ t8 y
微信图片_20230415164623.png
% Q0 I. H; u: R2 \" Q& R
配置时钟源
    HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:0 B8 f& R: D/ l6 Y2 y

7 ~0 H: g/ T* _# d' U3 A; F
微信图片_20230415164620.png

' J/ S* A# E! y& G3 _, M0 c
配置时钟树
    STM32F0的最高主频到48M,所以配置48即可:- B+ b0 H6 X' N3 o& B0 b3 G/ J% V

5 {' }+ X. U, F/ i
微信图片_20230415164614.png
/ s; P' e* j. k
串口配置
    本次实验使用的串口1进行串口通信,波特率配置为115200。
) |- \5 \3 p  \# y  Q
. z1 h4 P! }! H& z- U2 P* v* Q
微信图片_20230415164611.png
  H- @. I- J5 N. W- @% {& H
    中断% @5 i/ N: E" j$ T2 t; P

/ f" D2 b: I6 ~. a! R7 {7 n
微信图片_20230415164607.png
1 x1 N5 Y& o* K3 l4 g
GPIO配置
    板子上led为PA5端口,故设置PA5闪烁来验证是否正确。0 D" ]; Z3 f1 P. ~1 }7 d

) z% ]3 n) K- X
微信图片_20230415164604.png
- H( d' J- _0 W
定时器配置
    本次实验使用的是TIM3来进行计数。
% d, v( I$ ~/ |  G. h

( x: T: v8 Z6 t
微信图片_20230415164601.png

8 \! B/ e  N+ m- U
    PWM频率计算如下所示。

2 @0 D* k4 d8 e& Y
微信图片_20230415164558.png

; @1 k* n* n; ?3 u! u    在上面配置TIM3参数,预分频系数设置为480-1, 自动重载值设置为10000-1,那么PWM频率为48,000,000/((480-1+1)*(10000-1+1))=10Hz,即 100ms一个周期。
, A. n- A! R$ T8 F+ ^

$ Q9 [9 r0 i" u1 \生成工程设置
    注意在生产工程设置中不能出现中文,不然会报错。  E5 X5 _: e. g1 F8 ~4 a! `: ~

- P1 U6 T7 |1 o
微信图片_20230415164553.png

: A+ _+ t3 s* @- J# N6 o: |代码生成设置
    最后设置生成独立的初始化文件:
* }& }0 n5 l9 B4 r- ~$ L

3 F, d+ ~/ R& ]
微信图片_20230415164550.png
! w9 r( g6 O% Q/ C
生成代码
, d: P4 }# g, o) t; ]# G- F, F% B9 V6 u. g3 ~/ t5 e2 v' u8 f
微信图片_20230415164541.png
8 R% O  @1 d/ Q" y+ N# _$ e
配置keil
微信图片_20230415164538.png

" f+ l. b/ ^+ Q( R
微信图片_20230415164511.png
" J. H9 w- d! o# H3 F6 x: |  K  f
  o7 s8 I- x' n. @+ C: y6 c
代码
    在main.c中,先加入头文件。
  1. /* USER CODE BEGIN Includes */* Z) R, r& d: x
  2. #include "stdio.h"//printf头文件, x: g- S& P3 ^& z& L
  3. #include "string.h"//memset头文件* @7 @2 @6 U% Q8 p1 Y& D
  4. /* USER CODE END Includes */
复制代码

3 X  W% ~3 G* a0 t: I% [" z
    定义变量存储。
  1. /* USER CODE BEGIN PV */9 ?  m2 p/ l2 _4 B
  2. uint8_t RxBuff[1];      //进入中断接收数据的数组2 H- [* F/ `4 \. m+ C4 |
  3. uint8_t DataBuff[5000]; //保存接收到的数据的数组
    ' [. R' w* r! a) Y9 a8 A( M
  4. int RxLine=0;           //接收到的数据长度/ l4 O! v: v6 d' A  s8 \
  5. int Rx_flag=0;          //接受到数据标志! z  X" Q  V4 e6 Y% F+ s" x
  6. /* USER CODE END PV */
复制代码
; n/ S3 V" A* |  r6 L/ ]. k
    定义printf的重定向函数fputc。
  1. /* USER CODE BEGIN 0 */
    7 p( O/ }8 v+ }  n
  2. void printf_usart(void);//输出内容
    1 |8 t9 o; U$ F) Z* v- ?5 E
  3. int fputc(int ch, FILE* file)//定义printf的重定向函数fputc,满足串口调试打印
    4 c$ Z3 B+ O  f! f1 ^
  4. {* M- d% _. L9 o  Z8 b
  5.     return HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 100);
      ?; @+ S1 l1 t$ q/ e
  6. }: i, V' |0 E$ X' s2 R9 {
  7. /* USER CODE END 0 */
复制代码
   
打开串口和定时器。
  1.   /* USER CODE BEGIN 2 */# S0 V8 H0 a3 ^+ @# D4 `7 b. N) V
  2.   HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuff, 1); //打开串口中断接收* ]/ X6 E$ H" P4 @
  3.   HAL_TIM_Base_Start_IT(&htim3);//开启定时器
    , j, m3 e* i& f7 G- A6 y
  4.   /* USER CODE END 2 */
复制代码
. T/ |+ p9 }9 d/ ?
    串口接受代码,当接受到最后数据为FF时候,直接打印,否则等待100ms打印。
  1. /* USER CODE BEGIN 4 */5 s4 r. S. ]. h
  2. void printf_usart(void)
    . a% N+ e0 ?0 C  b/ h" z
  3. {
    & b- [8 j# _+ u0 y
  4.   printf("数据长度=%d\r\n",RxLine); * }* s' P9 a; l, ^- H" w$ P
  5.   for(int i=0;i<RxLine;i++)
    $ l0 X; F0 ^6 y: W" s5 q
  6.     printf("数据:[%d] = 0x%x\r\n",i,DataBuff[i]);                            4 q/ q/ [" F3 a
  7.   memset(DataBuff,0,sizeof(DataBuff));  //清空缓存数组
    4 G) s# Z7 k' n4 w' j8 B. G) M
  8.   //memset()作用:可以方便的清空一个结构类型的变量或数组。$ e- S# J% s5 c3 ~$ a* `7 y9 q
  9.   //例句:memset(aTxbuffer,0,sizeof(aTxbuffer))  用memset清空aTxbuffer。
    9 ^  r' u; J) ], ^; U
  10.   RxLine=0;  //清空接收长度1 \9 M4 [! a# `+ r, g
  11. }5 F! |% R6 Y, g0 v, o
  12. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    , d& p$ B: l6 G. c! @2 W6 S1 _  r
  13. {
    9 h$ `7 B% f6 T4 d) t8 s1 X
  14.     if (htim->Instance == htim3.Instance)
    . r! t4 F- C, U: ~7 F
  15.     {
    6 a( o; i8 G, r  b
  16.       HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);$ Q$ U/ I, ]6 O- s) Y
  17.         /* Toggle LED */" T* p) Y5 y$ y4 }' ^
  18.       if(Rx_flag==1)
    * o1 Y  Z, Z+ _2 {8 O/ [
  19.       {
    5 p/ Z' X. g: `  c# n; z
  20.         printf_usart();$ d! ^9 f9 L* O, x: {- g! t% p2 Z
  21.         Rx_flag=0;3 L3 k4 H, Z0 k" R; a9 V
  22.       }
    5 X1 V$ m; r5 ]1 f4 L" K  T+ u
  23.     }  ( u1 h" Y7 M& Z7 [1 T
  24. }/ z2 w" l" D2 i1 v
  25. // 捕获中断回调函数,每次捕获到信号就会进入这个回调函数
    - k+ R/ C- ?* K  g" Y- S) f9 Z* S
  26. void HAL_UART_RxCpltCallback(UART_HandleTypeDef*UartHandle)( i- @8 J0 o/ g  d
  27. {
    / r6 ?& V6 ]2 C8 d
  28.     RxLine++;                      //每接收到一个数据,进入回调数据长度加1$ e5 [% o8 m7 Q/ B( E3 d% E& Q1 k" w
  29.     DataBuff[RxLine-1]=RxBuff[0];  //把每次接收到的数据保存到缓存数组
    ; }/ \& |) O( s# Q
  30.     Rx_flag=1;+ a2 ~- M* {0 z
  31.     if(RxBuff[0]==0xff)            //接收结束标志位,这个数据可以自定义,根据实际需求,这里只做示例使用,不一定是0xff. W" I! m. `+ ?1 J" W
  32.     {: T! z4 b) _2 m
  33.       printf_usart();
    4 j( F: @8 A+ {# |: K
  34.     }   & o3 G) ?" B% d$ {! e2 A5 J
  35.     RxBuff[0]=0;' J* {; K1 d9 q$ D$ _
  36.     HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuff, 1); //每接收一个数据,就打开一次串口中断接收,否则只会接收一个数据就停止接收4 x8 |1 v, Q! U2 q
  37.     __HAL_TIM_SET_COUNTER(&htim3, 1); // 计数清零,从头开始计
    5 j8 Y& z* Z: Q# w8 E
  38. }
    7 n9 l  q( Z! [
  39. /* USER CODE END 4 */
复制代码
+ S/ n" s& L# w6 w$ g5 K
4 |; Q; u0 h; Z/ Z2 H, A' g
演示效果
    可以看到  发送11 12 13需要等待100ms左右才能发送,如果最后加上ff直接发送。

) H& p% h3 F6 U  k% H* I1 y
微信图片_20230415164508.png

; ]7 A1 S+ T) j
转载自:记帖
如有侵权请联系删除

- \& x6 u6 I8 M

6 C5 {" Y/ O9 a) U3 G
3 F- B2 _. [) A# M# O  x& d3 F* ~
收藏 评论0 发布时间:2023-4-15 16:48

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版