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

如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向

[复制链接]
攻城狮Melo 发布时间:2024-6-15 13:03
串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。
( U7 [# i: Z% T6 ?本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。+ E+ p8 k, c0 g4 b- E
  @" U9 E0 v9 ^# k( U
微信图片_20240615130239.png
$ _2 M8 W/ G8 c& |1 f: _+ r
  g* v/ f, P" D
7 F4 r4 c. T$ N1 e0 T2 x 微信图片_20240615130232.png
. i. O: k" ^! C9 ^( f
1 g* `' U) ?' g  `首先打开CubeMX,配置时钟树和时钟源。
( e9 k# `0 N; j, |
1 e0 d+ _/ ]6 L# i3 |5 |7 t 微信图片_20240615130228.png
6 M6 s% g9 I1 }5 D- L# w( P

4 S* K/ l* g' d接着配置我们的串口,设置相对应的波特率。
. ~. Y! j" i5 z  O" ~7 f7 {" U% q: Z+ h
微信图片_20240615130224.png
2 L9 k: ^, \. ^& L6 [

8 {( R' s2 q/ i4 |, x, [$ Q打开串口的中断。
. G( _% v( l  K9 H* J4 j% f" n8 v2 y8 q  A5 L$ C
然后创建工程。
7 J& z( E9 e+ n; a* s# K  k
) `9 ~0 g$ Q2 P4 Y3 A 微信图片_20240615130221.png
3 n0 i% |- T$ e$ v* p: m

: e4 g8 b) z; v3 x在魔术棒中勾选Use MicroLIB# ]: ~8 A3 e$ E1 O
  1. unsigned char ReciveBuffer;
复制代码
" C4 H9 H) U3 I: x6 }
在全局定义一个缓存用以存储中断接收到的数据。
8 o4 a$ A& w' n+ L6 \
  1. HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码

, U( t1 G4 w" F0 [* p* t: G初始化的时候需要启动串口中断。
% D* T. L8 B0 |5 `3 j9 A$ a
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    ; R$ k, \. I4 b- w
  2. {
    3 o3 a0 Q4 a" g
  3.     if (huart->Instance == USART1)  // 判断是哪个UART触发了中断$ u) E0 s, J8 |6 I5 T; D3 ?' n
  4.     {6 A1 \4 s! F( t7 o! |, A0 K8 |
  5.         // 处理接收到的数据
    ' \8 f8 [) B3 f0 x) U
  6.         HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去
    4 \& Q- a4 @  n6 i% ~$ v* y! ?
  7.         // 可以再次启动中断接收
    : B6 j1 f2 y7 z# m0 l7 r
  8.         HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));' q1 P0 K" a8 S) P  ^
  9.     }
    : W! B, r8 U+ J7 g; T
  10. }
复制代码

7 a+ f; K: I0 i# G7 W* {6 a接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。% O" p. z9 k' \4 V2 `
1 g' v+ @. i. s5 s$ z) K* w
微信图片_20240615130217.png
, I  H) |2 D% w0 ?; F* g; }( r/ ~2 B

) u/ z$ {" X6 o- Z6 s% G6 R可以看到,我们发送的数据被原原本本的发送回来了。# o  R: N! u8 @* h6 x
+ N9 M/ ]8 e" m. w9 `
串口的重定向

, v% Z5 S. o* U% i- ~) S0 o) V重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。
1 N/ _2 L7 ^9 }% e1 ?& |
' t' m) C9 j+ e! _. v2 v$ c. v5 K
串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?2 u! E, F9 I+ }
  1. #include <stdio.h>
复制代码
& \6 H/ w5 U9 j) ]
我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。' X8 @+ ?: R2 u+ C; J

( g" m# o9 ~9 n4 i
通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。+ p8 S$ C4 }$ `2 C/ M' T
  1. int fputc(int ch, FILE *f) {
    & H- P' H9 ^: w# q9 p- [
  2.     // 发送单个字符
    3 ~8 z( L: j2 T5 {. f2 _2 u' `' N& }
  3.     HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);& D  ?+ q2 V# N0 K  b7 Z( ^
  4.    
    , {" s/ U# \) F! ?2 k
  5.     // 返回发送的字符
    ) ?: L, q3 i" C
  6.     return ch;
    / ^0 ^: @9 J0 J0 T" t6 T! W
  7. }
复制代码
  1. while (1)+ M/ h9 O( G2 _+ ]/ r3 y1 w
  2.   {
    * R, s% w: E* [) m: i
  3.     /* USER CODE END WHILE */0 ^3 a; B  n1 ^4 H$ n! ^! B
  4.     printf("Hello\r\n");/ Y3 j0 O' h* @
  5.     /* USER CODE BEGIN 3 */
    : \1 u4 H- f/ T' `5 j! R3 B8 G
  6.   }' ^8 r+ A9 I3 x+ a- i4 |
  7.   /* USER CODE END 3 */
复制代码

  b& W/ X: w4 v 微信图片_20240615130212.png 8 A+ R( t( h  L4 g
$ K2 ]  H4 i, p. I

4 n6 N1 r+ ^3 i. V. @8 l1 {正弦波
% y+ M4 N; E  i
  1. while (1)3 K5 ?1 X0 V* W! C
  2.   {/ Q( _, R$ \% t% J- u" E
  3.     float t = 0;) [7 {0 z! _7 d! w3 x, F& T' w9 F" s
  4.     /* USER CODE END WHILE */
    ( o6 Q# l4 C5 i. j/ D
  5.     printf("A:%lf\r\n",sin(t));//正弦波
    + W$ F& O* Z+ i% |( Q
  6.     t+=0.01;2 _  j. Y  H  s  h
  7.     /* USER CODE BEGIN 3 */8 a& ]) g4 f6 P
  8.   }
复制代码
9 b1 J- h$ Q- X* s9 z% d" z& x, Z
微信图片_20240615130207.png ; g. h1 m( c+ n3 |3 l; ?
: t  m% |& H9 {# N( f4 U( p1 v) Q

0 S* ^9 c& @3 a' N' |" S正弦波相加2 d( U' X% `/ S
  1. while (1)  }0 W  u9 K' W; O
  2.   {
    + Q$ ]) ]7 R) g6 m  \6 f
  3.     static float t = 0;1 O" E. X# b2 J7 Y- t
  4.     /* USER CODE END WHILE */& `$ r6 {: x+ k- p7 O5 J+ ^6 m* J% T
  5.     printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加
    2 T7 E1 W9 T- c
  6.     t+=0.01;% [; i( F! X- I) q
  7.     /* USER CODE BEGIN 3 */
    " F. S! s# T1 @1 N: V8 s
  8.   }
复制代码

) w" x, n( u4 w* y 微信图片_20240615130159.png 0 c5 j( R! [9 Q( _% V0 U' ]

0 D" N- \" z5 C8 b( Y6 Z' Q. Y9 h- Z. T8 W9 `. W
正弦波相乘5 }' Y5 U7 Q4 F8 f3 C% t* F
  1. while (1); C( i( {/ f( f' Y3 h3 M( t! |
  2.   {& J2 Z6 ]8 H4 \( L4 A
  3.     static float t = 0;
    4 L+ O& a5 }8 w$ w9 C
  4.     /* USER CODE END WHILE *// k1 T7 {0 d, j- [7 D( \1 q- U
  5.     printf("A:%lf\r\n",sin(t)*sin(100*t));* G; d# h" A' l+ T$ K: C; u
  6.     t+=0.001;
    6 |6 K. k$ U' o5 R
  7.     /* USER CODE BEGIN 3 *// l8 {$ Y& j% x" H5 \: b9 U
  8.   }
复制代码

, \2 e! E- O/ ?' @! T 微信图片_20240615130130.png $ }5 J9 F  c" J  k# }$ H, ]
: |" X. s9 c+ `/ q
转载自: 电路小白
8 Z. p! `1 p( h$ \6 n
$ r! y6 N6 `; X# S如有侵权请联系删除
  p7 P* F8 l$ C. c
* E' T( n2 `# ?; g" l( ^6 A% H! b' Z+ o2 G
8 p1 d( v' G1 S' r8 a5 c% E: m) K4 D

+ |, A$ t6 g; O4 o) [+ m# B$ i6 s9 r- T# U
# n7 V3 A* [3 z4 s% `
收藏 评论0 发布时间:2024-6-15 13:03

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版