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

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

[复制链接]
攻城狮Melo 发布时间:2024-6-15 13:03
串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。4 l7 p, O: G! E
本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。
$ b8 [: Y: z3 f; N% n0 t4 n( p
6 O# W! f. g) ^& c0 [, l0 L* t 微信图片_20240615130239.png : V+ u( E$ y4 q$ B8 {  L6 N% M
  |: A* }, H* Q- ^5 }$ G. n) Z" F8 i

1 S4 [+ @  J7 _7 R 微信图片_20240615130232.png 4 V$ ~7 V# A! D* ^% d
7 H$ ?# W2 f3 V" z5 V/ m
首先打开CubeMX,配置时钟树和时钟源。# o% M  U/ @8 }5 b' c% C" b

! l: t* [% y2 R- D& u, O 微信图片_20240615130228.png
4 V: g% H! o7 L/ X9 v

. l. y: f2 s$ w- u" _7 K接着配置我们的串口,设置相对应的波特率。
) E+ ^( C6 ^, m6 V! b; r. ^3 [2 H0 @' Y' V7 v: x
微信图片_20240615130224.png
) g* P9 v; a  Y7 Z9 f$ q% o& {+ A
$ v5 v: x5 D( t% r, ~
打开串口的中断。
) U. ~) E9 i2 c. j+ E
0 h1 l- W. a: ]
然后创建工程。7 H5 E3 v- j2 u, x9 t6 W
1 k. Z8 g& x8 f. |5 i& h$ [. u  R
微信图片_20240615130221.png . ]' G+ K" m+ `- x$ v
2 x6 E8 z. e& O' \% c$ t- V
在魔术棒中勾选Use MicroLIB
# Q" i' w6 D" I0 C$ h$ d4 S
  1. unsigned char ReciveBuffer;
复制代码

% h4 `! x1 D# I7 h在全局定义一个缓存用以存储中断接收到的数据。
9 j( Y# ?; E# U4 o% \
  1. HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码

$ V6 B* t6 b4 v初始化的时候需要启动串口中断。
; M. q) G" h& M
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)1 y# B+ V% {: K/ U) Z0 t
  2. {9 ~4 g! X. J" q8 Z3 S- [
  3.     if (huart->Instance == USART1)  // 判断是哪个UART触发了中断
    - `7 ^  e. K- q& h
  4.     {' u# i+ }7 w: G  Q! W% O
  5.         // 处理接收到的数据) `# v# {7 a7 H; {
  6.         HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去
    1 m6 A2 m0 E+ a( x' a
  7.         // 可以再次启动中断接收& O8 f! O; T" T8 E
  8.         HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));0 g8 C$ c3 r* f$ o) R. R1 F" d
  9.     }
    9 t$ n0 [* I- f- I: e
  10. }
复制代码
/ R' Z6 ]- a  x- r2 _6 l/ s
接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。
3 l+ T# w9 a  I, s/ I+ E
) b' q2 l, z* U 微信图片_20240615130217.png , L+ R" ?; F1 k9 F- y. M; y
" p, z' f8 O$ k+ S* G7 T: b+ o- |6 H1 U
可以看到,我们发送的数据被原原本本的发送回来了。
2 O# e: L0 C/ \6 C" d& {
7 ^8 f  |5 K, L/ k. `6 O, P% D
串口的重定向

3 a7 G  f2 j4 u; _" h重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。) Z1 c* T8 `. T& R8 O
1 V, {9 s' U4 n0 j1 h$ l
串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?
( ^" ?% H5 d4 i, q$ ~8 h
  1. #include <stdio.h>
复制代码
& L* C3 D3 G/ v) K
我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。
" D  f- U( l4 w2 t. ?& o: k8 ?
7 x" C* {8 S6 o: J1 _
通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。
$ d8 q: j5 F* |$ k
  1. int fputc(int ch, FILE *f) {
    ; I/ B; j8 m; i5 P# I6 ?
  2.     // 发送单个字符0 W/ H! T. a; t0 {, }9 X# Y1 u
  3.     HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);( y6 d" c& |6 ^* N, O; y4 s# W
  4.    , w. G0 h- N( u/ ]6 I) X5 U
  5.     // 返回发送的字符
    9 c% f  L, Y6 w  ~1 Q$ ?6 s# ^
  6.     return ch;+ C4 I: }1 y$ {" ]- U1 _: k3 T
  7. }
复制代码
  1. while (1)! |6 x' I+ z( S2 x- Z2 l
  2.   {
    0 {  ?1 a0 L/ |2 \5 r: o1 \
  3.     /* USER CODE END WHILE */
    0 y$ j" r) w) P; y
  4.     printf("Hello\r\n");
    ! @, r# Y& A: Q2 F; D
  5.     /* USER CODE BEGIN 3 */
    0 w- o9 Z: \2 t1 M
  6.   }2 T2 B8 `: K" U4 V. O! I
  7.   /* USER CODE END 3 */
复制代码
* E1 s& Z( p6 F
微信图片_20240615130212.png ) B1 I: P5 h! t  T. {, u+ j: t: w  U

7 m8 [, U' j( M2 Y8 Z+ X+ W1 A0 C
- e9 h8 W+ P0 k5 A' @# r8 v
正弦波9 y4 h1 c- s% E" q/ }1 B2 x! M
  1. while (1)6 e' }4 q- |: @) P9 a/ M0 p
  2.   {
    & D9 [% i( k" x# A- H
  3.     float t = 0;
    . g# V/ M' i9 H2 L( y( a2 r5 x: |5 V: Q
  4.     /* USER CODE END WHILE */
    9 t# y3 X5 T. r: Y
  5.     printf("A:%lf\r\n",sin(t));//正弦波
    1 Y8 G7 Y: Q# J! c
  6.     t+=0.01;
    4 l- s( q# h' l! J* `
  7.     /* USER CODE BEGIN 3 */2 U  Z. y& e( A. g4 w
  8.   }
复制代码
' u: H4 j6 U2 W9 E+ ]
微信图片_20240615130207.png
$ `. t) l; U. ]8 L  U3 I+ F
7 U  X. w+ S% G7 o) {
2 L4 N5 z7 O) p正弦波相加9 N. H! n3 @2 p6 _
  1. while (1)
    ' j0 L, H0 }0 a7 ~( O$ ~+ c
  2.   {' `# k; O+ b4 j% j: z* y6 R, @
  3.     static float t = 0;
    - \( u2 }8 W/ Z
  4.     /* USER CODE END WHILE */% w( l; Q- ]& C( f9 u, }- _. C
  5.     printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加
    8 w& X4 `5 X# H
  6.     t+=0.01;
    ' _4 w4 r/ Z7 Q! S$ q0 T4 I
  7.     /* USER CODE BEGIN 3 */
    3 _3 w/ M' N$ L6 ~% f& A& g5 u: a* u& k
  8.   }
复制代码
+ W" ?) V  e: h/ Y( g, Z
微信图片_20240615130159.png
  V+ `/ l& J( p8 X
4 `1 G6 {& [, ]2 g$ X  |2 O& g6 y0 j6 _- @, d- V
正弦波相乘2 u8 V) }8 p! \6 a& Y
  1. while (1)& B. o5 l6 E+ x: c8 l8 a. w
  2.   {8 }, k/ \) h7 q+ O9 Q% N) G5 Y, J/ ~
  3.     static float t = 0;
    1 L! ^/ {- i; M
  4.     /* USER CODE END WHILE */% d# @: K7 U& ]$ P1 |7 P/ \
  5.     printf("A:%lf\r\n",sin(t)*sin(100*t));3 u+ V4 F5 ?9 |) k
  6.     t+=0.001;
    4 a1 k2 t6 i/ n9 V2 n3 N
  7.     /* USER CODE BEGIN 3 */8 s6 I0 o% e2 i- i+ |
  8.   }
复制代码
2 @+ l. U3 k, x  L2 ]* x, Z6 Z5 ^
微信图片_20240615130130.png . r% ]) e2 u, L' Z9 g3 w2 A
$ W% _$ e  ?8 ]
转载自: 电路小白7 b- c' k8 y2 k* q; D

  f: j- f# L. d/ ]. s; @如有侵权请联系删除: ]2 H! m* L! Z- L: {9 e- c2 n% k4 o

) o+ S" c' W: ^: T' \6 m
) H" T+ u6 K6 h) K. p( ?/ g
+ W1 |, b1 T3 i1 `9 `5 V1 |; a% q: v8 V' R3 w& H( y1 g* K2 d

  B8 n. I6 f9 w+ j% x! m  M4 e7 @1 s
) g1 I0 R8 j% O; r; s) l6 [: Q
收藏 评论0 发布时间:2024-6-15 13:03

举报

0个回答

所属标签

相似分享

官网相关资源

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