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

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

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

( e- A% d* f3 m9 F
硬件准备
    首先需要准备一个开发板,这里我准备的是NUCLEO-F030R8的开发板:   
! q# o4 O3 d& T  K
# N# A7 _1 Q, c
微信图片_20230415164627.jpg
3 E2 @2 o. W$ z: l3 U* T/ q
选择芯片型号
       使用STM32CUBEMX选择芯片stm32f030r8,如下所示:
  z- q4 n4 [7 N6 v5 Y0 S9 v8 m
微信图片_20230415164623.png

& F& Q3 l; s5 e# n( y7 w配置时钟源
    HSE与LSE分别为外部高速时钟和低速时钟,在本文中使用内置的时钟源,故都选择Disable选项,如下所示:0 `6 X2 y% k/ o, E6 f

' d& Z. W$ \) ?: r- T% c
微信图片_20230415164620.png

3 N' ^( k* z7 U/ B3 i, _  J$ j
配置时钟树
    STM32F0的最高主频到48M,所以配置48即可:) ~6 Q2 n7 L6 e' W" `2 e
) A* ]+ Q2 h! |8 H7 t0 H1 F! n0 D
微信图片_20230415164614.png

. v" c! \) D6 Q/ a' t8 r- O串口配置
    本次实验使用的串口1进行串口通信,波特率配置为115200。
2 m  `- z8 q, D; V5 G, J9 k) ^
1 K2 W8 q& b! L6 {# P
微信图片_20230415164611.png

( O, [9 y. }# F9 r& b8 K
    中断+ g. z; V" p+ X$ ^4 L. r
, W% X- {9 |* H! r2 O3 [
微信图片_20230415164607.png
" U3 `% H' z: f2 B
GPIO配置
    板子上led为PA5端口,故设置PA5闪烁来验证是否正确。( P. Y$ S2 i( d( E8 f
* C9 L, W8 k1 x# S/ e; O
微信图片_20230415164604.png
* n3 l$ W; o$ L
定时器配置
    本次实验使用的是TIM3来进行计数。
+ e7 G0 ~4 z$ q5 F
, D# Y: t! y8 M: e' j6 T* b
微信图片_20230415164601.png

0 b9 G# s  V( ?2 j  N
    PWM频率计算如下所示。
2 e  M, h& u' V
微信图片_20230415164558.png

( x) Y/ ]$ F# g' W    在上面配置TIM3参数,预分频系数设置为480-1, 自动重载值设置为10000-1,那么PWM频率为48,000,000/((480-1+1)*(10000-1+1))=10Hz,即 100ms一个周期。
" y. Z% ?" w) P6 b& f$ J

7 q1 j" R+ n2 {$ B4 O% M生成工程设置
    注意在生产工程设置中不能出现中文,不然会报错。
- N  G* g- b& W4 U8 m

; N8 p% h1 D& h( m/ V: Q' S1 y: f
微信图片_20230415164553.png
) o3 v- U% z. `, ]# v
代码生成设置
    最后设置生成独立的初始化文件:" D# R3 e1 f5 V( A3 q
9 K4 `6 j5 d6 \0 X0 a
微信图片_20230415164550.png

7 E7 X6 g) ?+ }5 z( ?& q( I生成代码. J- Q( }8 D: R" S8 d2 z

. d* i+ d& b) L# b
微信图片_20230415164541.png

$ r! n8 r  i  H1 J1 o
配置keil
微信图片_20230415164538.png

5 H* q& K4 k4 a  |
微信图片_20230415164511.png
3 Q7 \' N; j. K- _2 F3 o

0 [; i% E' a! H代码
    在main.c中,先加入头文件。
  1. /* USER CODE BEGIN Includes */
    & N3 s* }) }% \2 u8 j
  2. #include "stdio.h"//printf头文件/ s% n3 w6 y# Q. G
  3. #include "string.h"//memset头文件' X0 ?7 [& H3 M6 d9 B
  4. /* USER CODE END Includes */
复制代码

1 n! G9 X, J) l& `) {  F9 ]
    定义变量存储。
  1. /* USER CODE BEGIN PV */
      n9 u# S' R7 n
  2. uint8_t RxBuff[1];      //进入中断接收数据的数组6 a6 t6 O7 I5 d8 {2 V1 B1 ?" B
  3. uint8_t DataBuff[5000]; //保存接收到的数据的数组/ {/ Y6 p) ~9 ?" k
  4. int RxLine=0;           //接收到的数据长度
    2 W1 `" I" Q) @1 G2 l
  5. int Rx_flag=0;          //接受到数据标志& a( p) }) ~1 Z6 j& m, h- i
  6. /* USER CODE END PV */
复制代码

, ]* q0 B0 x4 B" ^9 h
    定义printf的重定向函数fputc。
  1. /* USER CODE BEGIN 0 */
    1 J; k4 H. A+ |& H
  2. void printf_usart(void);//输出内容
    ' s5 x% p' J+ w
  3. int fputc(int ch, FILE* file)//定义printf的重定向函数fputc,满足串口调试打印
    - @. G6 }1 S6 X+ Z/ T8 J  O
  4. {
    8 o4 T' ^( y9 X/ @( p" C: B
  5.     return HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 100);
    ! l; ~8 l! n4 g' u
  6. }
    ! C. B+ O* d  v4 M! V3 N3 ~3 S
  7. /* USER CODE END 0 */
复制代码
   
打开串口和定时器。
  1.   /* USER CODE BEGIN 2 */
      y1 S; f9 d: y; q) S$ R
  2.   HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuff, 1); //打开串口中断接收
    6 O: z+ X/ x: ]& F& j, k8 z
  3.   HAL_TIM_Base_Start_IT(&htim3);//开启定时器; u, V9 C( `% i  H9 z0 \
  4.   /* USER CODE END 2 */
复制代码

9 _+ y  l7 A, w5 W% B$ V' K
    串口接受代码,当接受到最后数据为FF时候,直接打印,否则等待100ms打印。
  1. /* USER CODE BEGIN 4 */
    / R; ?1 J( N3 s3 @
  2. void printf_usart(void)
    : E( c6 n# }3 f; G% i
  3. {
    1 O0 f$ T/ q" ~3 _
  4.   printf("数据长度=%d\r\n",RxLine);
      q- s' [1 q( H$ C8 q; P, J" C
  5.   for(int i=0;i<RxLine;i++)" V8 ?! v# I: t5 ^6 |; ^
  6.     printf("数据:[%d] = 0x%x\r\n",i,DataBuff[i]);                            ' G3 Z% t* y: E6 x
  7.   memset(DataBuff,0,sizeof(DataBuff));  //清空缓存数组* g2 a# p3 y  j7 w
  8.   //memset()作用:可以方便的清空一个结构类型的变量或数组。/ L3 i$ C+ v* e) e& g
  9.   //例句:memset(aTxbuffer,0,sizeof(aTxbuffer))  用memset清空aTxbuffer。
    - T0 T1 s, w+ K3 W) p& ^9 R' k3 p
  10.   RxLine=0;  //清空接收长度
    ( j7 U, \; @# c
  11. }2 c$ K( u7 ]- G/ z+ W- i
  12. void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
    ! ]' ^0 o4 u, `+ V
  13. {; V: q& Z0 @! p/ v3 k5 e
  14.     if (htim->Instance == htim3.Instance)
    9 w* [6 v/ ]3 l
  15.     {
      H/ H% L: |2 [! t; U9 K4 E
  16.       HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
    + [8 W: e& ], h4 Y  W" Z
  17.         /* Toggle LED */
      R; F; }4 G/ o
  18.       if(Rx_flag==1)5 n; s! J/ g1 }1 M0 u' [/ W! L2 {
  19.       {
    3 {! K. u4 Z# N! p8 a
  20.         printf_usart();* G: d! d, E* Z! a, X0 N4 h. v
  21.         Rx_flag=0;: [5 M% M" ]0 E; f: s
  22.       }1 \* L9 P1 D4 ?1 \) s  @$ Q8 n* W
  23.     }  , ]* A+ O4 U* d/ S
  24. }! I  P) e5 Q7 f: K; h; \" {4 i9 w
  25. // 捕获中断回调函数,每次捕获到信号就会进入这个回调函数, [" s  E3 L0 S0 P4 z
  26. void HAL_UART_RxCpltCallback(UART_HandleTypeDef*UartHandle)
    ; r+ [5 l4 K. f! P* M
  27. {9 I' [" t9 O: }: ]6 W
  28.     RxLine++;                      //每接收到一个数据,进入回调数据长度加1
    7 M) {3 _5 r3 h0 D, C( s
  29.     DataBuff[RxLine-1]=RxBuff[0];  //把每次接收到的数据保存到缓存数组/ W# d3 Y8 w- J1 X: s8 ~5 w0 K1 U
  30.     Rx_flag=1;
    ' g8 g' y+ X4 `& t
  31.     if(RxBuff[0]==0xff)            //接收结束标志位,这个数据可以自定义,根据实际需求,这里只做示例使用,不一定是0xff
    ! c( O/ C8 f. T: T  u( t
  32.     {# D( }! o- M/ t( |. H, `
  33.       printf_usart();
    % |2 u' f" S5 w
  34.     }   
    # D# q! p. N" ?0 F9 D/ d
  35.     RxBuff[0]=0;/ y" u. X+ A6 o- O5 Q
  36.     HAL_UART_Receive_IT(&huart1, (uint8_t *)RxBuff, 1); //每接收一个数据,就打开一次串口中断接收,否则只会接收一个数据就停止接收% u! y2 m$ B% G; g  u7 _# [8 t
  37.     __HAL_TIM_SET_COUNTER(&htim3, 1); // 计数清零,从头开始计& ~# P4 h* L# f' Q# a% g
  38. }
    + ?6 j) a! p+ _. |
  39. /* USER CODE END 4 */
复制代码

  z8 L. F; I1 h9 f; o
) l' G% v, R8 Z' ~$ R, C6 O9 }
演示效果
    可以看到  发送11 12 13需要等待100ms左右才能发送,如果最后加上ff直接发送。
4 d- L3 ~; m& b: s  D) L+ J
微信图片_20230415164508.png
# L' X2 R+ i4 L0 v  T9 y
转载自:记帖
如有侵权请联系删除

+ u: L: T, Y- F4 Z; D  l0 O
. k: n: a3 j. Y5 B

+ l, C5 _' l1 E# ?5 M$ s
收藏 评论0 发布时间:2023-4-15 16:48

举报

0个回答

所属标签

相似技术帖

官网相关资源

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