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

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

[复制链接]
攻城狮Melo 发布时间:2024-6-15 13:03
串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。& Z" N0 c6 t* w1 ^7 S
本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。
, M5 F# o* v7 H6 X/ Z; T/ P' K* X3 y: P) T" c7 M1 |
微信图片_20240615130239.png * f4 y# U0 c. W( z5 i

" W/ f1 A  r; N0 Y
0 Z  h, D( L  J+ ?% p' O 微信图片_20240615130232.png
6 w0 ^5 W% d8 l. k8 B: ^6 B% b. r. @! K3 m
首先打开CubeMX,配置时钟树和时钟源。/ N' P; O3 x' n& U* N" w# a
! z. ~& a, Z& j! R. Q  Z
微信图片_20240615130228.png
" c, B" q. h6 ?5 n8 ?5 t: g

7 ~8 b& c. e+ ~0 J: v接着配置我们的串口,设置相对应的波特率。4 a* M& f7 u* z* N" A
8 [) o5 m, X4 _$ D  G4 m% {0 L
微信图片_20240615130224.png 2 B5 m( L! d3 c. q) ^  k% g6 F

  o, E. l8 T0 b/ z3 \打开串口的中断。
6 A& x( _* C4 D- K' m
7 Y4 Q% J. s4 O' W9 v& E
然后创建工程。* m, g0 x  a, {/ ^! k5 b

- c, |% t3 t5 Y4 T 微信图片_20240615130221.png 1 y# N  T* L1 _% N6 d8 e2 l/ q: X8 W

' j1 I. F/ A! m  }8 m" T在魔术棒中勾选Use MicroLIB: l; ]6 O: x% [( D0 u6 Y4 l
  1. unsigned char ReciveBuffer;
复制代码

5 N9 h5 Q$ R3 P) T在全局定义一个缓存用以存储中断接收到的数据。
  Q; L3 T2 ?5 \
  1. HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码

: \8 q9 I8 T: B9 n初始化的时候需要启动串口中断。2 `, J9 G* |$ D
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    2 {4 }+ u. N$ d
  2. {8 m' E8 f+ p4 _7 L
  3.     if (huart->Instance == USART1)  // 判断是哪个UART触发了中断+ R$ w; |; V5 g) [
  4.     {- T4 A: q; ~  n! G* Y6 G
  5.         // 处理接收到的数据
    ) s( k$ f( d$ }; X( E  L/ d! |0 y
  6.         HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去
    3 n" V+ B+ ?3 P/ @; g3 m
  7.         // 可以再次启动中断接收5 d1 i/ b* @$ K
  8.         HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));
    * N, r) r' v$ H) }
  9.     }( m0 B8 ~/ v9 H
  10. }
复制代码

5 ^$ l) {/ z. x8 @接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。6 {# M2 G6 |( ~- ?* a5 H

! O3 `: V9 h' @/ s 微信图片_20240615130217.png
3 ~0 q( U: H, Y

9 d8 _0 t# O& [1 r可以看到,我们发送的数据被原原本本的发送回来了。6 S1 }$ C; Y" o

, g8 ?1 p) q3 I" Q
串口的重定向

: R9 R$ q7 x5 ^5 s2 X1 u. }- ~重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。
+ a% M5 w" `! [# `. O2 Q" L( z& p
0 A: X+ ^1 q$ G- u
串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?
9 O( j! `% M$ G4 R, F( O: q' Y/ M6 u
  1. #include <stdio.h>
复制代码
% m: ^. q/ K2 ?* E$ E& n* P7 C/ S
我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。
3 H: v+ g& C9 ?8 V1 N9 l5 W- W' `& ]* f2 ]9 J
通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。* y( n; H3 n6 i2 v) e1 X
  1. int fputc(int ch, FILE *f) {$ P7 c* h& Z' h! m5 E% Z
  2.     // 发送单个字符
    1 o) \- |# X* l4 e( ^! d& X
  3.     HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);  F4 k6 o  R+ C1 N
  4.    ; P8 }, |& y4 |0 }8 m/ ~
  5.     // 返回发送的字符
    $ ]" T4 Z2 A/ H3 |" l
  6.     return ch;
    , `) N3 R+ Q: y3 j) s" z, E
  7. }
复制代码
  1. while (1)9 r9 _1 h7 @4 {& Z8 Y
  2.   {& [( Q" b# a3 s7 T; u  `
  3.     /* USER CODE END WHILE */
    8 H7 W" r* d; K% s
  4.     printf("Hello\r\n");1 ?( B1 [7 k! R% O* x- V
  5.     /* USER CODE BEGIN 3 */7 M; j6 Z! I6 P) u" J
  6.   }; _6 c" L- W/ E6 z3 F
  7.   /* USER CODE END 3 */
复制代码
, n+ B% Y, y. L
微信图片_20240615130212.png 5 Y& U, E  s+ K! Y8 S1 @% G0 c: }

1 e( P! F- V; l% E" g
) R7 X+ g- O* F1 b9 L7 ~
正弦波
; N0 f& z. d$ c& A+ K
  1. while (1), i  k4 p5 P+ @; {
  2.   {
    8 W+ D2 a& W/ f4 |
  3.     float t = 0;
    6 X- S+ }/ E( \) B7 u7 t
  4.     /* USER CODE END WHILE */" w0 ]8 H8 T* w* a) l. P7 p
  5.     printf("A:%lf\r\n",sin(t));//正弦波
    ( b& S2 T: S% Y" ~9 E4 P: S% g
  6.     t+=0.01;
    ) y/ Z: L( F. l* X% ]
  7.     /* USER CODE BEGIN 3 */
    ( u4 C( l( f1 n0 A) J
  8.   }
复制代码
5 t& a7 d# _: z
微信图片_20240615130207.png ; A! K; `" c. B! h2 b( r

* m3 s6 v* ~: Y4 f3 r; i  {
8 H9 }. c& @: D正弦波相加  u- i0 J9 G: G2 n5 R" A, W: w$ q! f( L
  1. while (1); \1 P, ]. |% O' z, ?/ {' u0 h  d8 J
  2.   {4 S8 T1 W9 b  K* v$ D1 V
  3.     static float t = 0;
    # a. h3 R) v' k! t; M
  4.     /* USER CODE END WHILE */
    $ L' l: }: b1 o" w# p4 u* G, A- P- P
  5.     printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加
    0 ]. A& h: x5 m# n
  6.     t+=0.01;: W7 n5 w# K$ H9 B1 `- s! b
  7.     /* USER CODE BEGIN 3 *// f( S# ^! X, C! H; {5 W9 A( q
  8.   }
复制代码

1 h- h5 X' l# f1 u4 v 微信图片_20240615130159.png , `* a6 E. @3 f/ ^8 l9 t! M
# |, h& E$ y' T- m

5 O) h  i: G7 P/ k) i正弦波相乘! m# A' i/ c2 C' r5 Q* H) J" k5 e" E
  1. while (1)4 Z" D" c" H7 G* q( K
  2.   {
    ( d. J, K9 s* t) k$ R
  3.     static float t = 0;0 E5 }! b0 `/ ?  R
  4.     /* USER CODE END WHILE */+ s. [4 V- H8 V9 c: L$ C* m  W
  5.     printf("A:%lf\r\n",sin(t)*sin(100*t));. K* E4 a4 o# t# R* _3 u8 v
  6.     t+=0.001;, ~3 \7 f  K: X# f1 W
  7.     /* USER CODE BEGIN 3 */
    0 U& c# U) P. {& c- i- ?
  8.   }
复制代码

& c: p4 s8 q' I# g1 M 微信图片_20240615130130.png
5 e  f7 N- I7 |- C& O/ H$ O7 T  C$ i0 b7 ]) _' T* v( f2 r
转载自: 电路小白5 l5 @3 d7 G5 x( w
2 r$ L. ]+ R( @; B4 L
如有侵权请联系删除
) \( W9 r7 V9 T
  k0 ^2 s6 d8 W& e5 y
2 G! ]7 ^& K4 `7 c  r* k$ h% D9 Q& l
) K1 d) Z  X; x# u# q- X; p' @
1 |* [7 [' [  X) _2 }( S4 G

: p  C+ G6 O% Z' k& x  w  q
赞 收藏 评论0 发布时间:2024-6-15 13:03

举报

0个回答

所属标签

相似技术帖

官网相关资源

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