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

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

[复制链接]
攻城狮Melo 发布时间:2024-6-15 13:03
串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。
9 B% f) v+ v$ M  u本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。( I& o4 m# Z9 U( J) f2 r

+ f# J, {7 \6 T, c+ z( g% l; b 微信图片_20240615130239.png
1 h$ O0 ^! n# d8 T% L7 p' Z8 U/ D  E' p: ^7 }; G

! ^0 f6 h+ `' Z2 U; I  n( q 微信图片_20240615130232.png + C1 j+ G+ z- j6 u8 {7 B3 A' l
$ Q$ g- @# b) h3 I$ x2 ^1 _; W
首先打开CubeMX,配置时钟树和时钟源。
& F5 O* k3 l. `" y
7 c8 A( h; _: A 微信图片_20240615130228.png 9 m* w5 n1 N' Q

! j8 n$ C+ D1 B. A( X' C& g接着配置我们的串口,设置相对应的波特率。" v0 D- `6 y8 j  g, q# d9 T: A- i

: h* T7 }! ~  ~0 _5 f 微信图片_20240615130224.png
1 r% t/ I) K! R6 ~( L

3 \9 R( h. h5 o' g8 G# a- p打开串口的中断。
7 U) |/ Y! d) u, n3 Q; N
0 t) F8 m; k1 [: R! y
然后创建工程。6 `/ V, v, w  B
, l9 r7 }9 ?2 K+ Q
微信图片_20240615130221.png . V# X( P1 J% j1 ~/ ]! J

4 [9 r) i: O* L* d& X* [1 B5 F在魔术棒中勾选Use MicroLIB% }3 W. ?+ A* |. @/ R* z
  1. unsigned char ReciveBuffer;
复制代码
. R8 R4 j( i4 n- a4 L- [6 g
在全局定义一个缓存用以存储中断接收到的数据。
! _7 z; F; H) G# k$ {
  1. HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码
7 m6 B$ h: K1 @5 Q) `& N
初始化的时候需要启动串口中断。6 e- H8 W5 g: x4 Z) H9 ?  t1 W
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)+ _" Z8 z1 m# D; F( w+ b4 g& Q
  2. {$ f" V. K% d2 V7 j) G
  3.     if (huart->Instance == USART1)  // 判断是哪个UART触发了中断
      g5 H4 i( C; a6 q! ~* \, d
  4.     {  P% U  D; X! b/ B
  5.         // 处理接收到的数据
    & ~/ e% T8 u9 R- R3 f9 v
  6.         HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去
    . ~  E0 `$ [$ p. r) v* {1 L
  7.         // 可以再次启动中断接收9 ?, Q9 b" B- J+ {
  8.         HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));& b: I4 B3 j4 L+ v5 y
  9.     }
    6 t0 C+ o: C. f+ y& f+ E! w& B
  10. }
复制代码

9 l2 F0 J/ N& e+ l$ m接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。
& P2 p! {9 ]$ n$ P% E% h* e. C" h1 t( I# \' m8 a
微信图片_20240615130217.png % o2 Y% x5 T7 ]5 |4 h7 O$ M

6 ^  O5 {" p/ G  k' C! V可以看到,我们发送的数据被原原本本的发送回来了。
9 S5 h  i& L' Q# `6 A
' `& e0 l2 V* q1 l& x
串口的重定向
  H7 j: L5 N4 x  p
重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。
4 K/ X; D3 K0 r( D+ T
  V' }' }1 p3 q% _+ r3 Z# t
串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?
8 c8 d( |3 E" z. l$ T3 }1 a
  1. #include <stdio.h>
复制代码
1 o( s& c: A' }: a$ L9 ~
我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。$ J/ l+ ^8 Q& h8 r7 V

4 ]. }: n4 Y, L, W
通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。& M' L' _0 d& B4 `( q- i* d1 \
  1. int fputc(int ch, FILE *f) {" A# d( V( q: S7 \& x
  2.     // 发送单个字符# s' l) C8 N8 l6 O
  3.     HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
    3 Y$ c: a9 x3 d0 M$ j6 P& u4 b
  4.    
    1 s) ~# {  `3 m& B# w' p
  5.     // 返回发送的字符
    ! i! k! K) ]8 b7 N9 l+ Q
  6.     return ch;
    7 v1 W4 T0 d. Y. P$ v( R- b$ w8 b  V9 a
  7. }
复制代码
  1. while (1)/ H3 ]1 p3 Z# V! q1 }- X: z
  2.   {
    0 E% v5 H* |' _, F
  3.     /* USER CODE END WHILE */
    " z5 Q' w$ t9 e/ D2 Z+ ]# l5 L
  4.     printf("Hello\r\n");
    6 K0 o8 k. ?- r: O5 `% B
  5.     /* USER CODE BEGIN 3 */
    , a8 t$ e3 Q" Z3 _
  6.   }' B4 u0 B" D$ F( o/ J
  7.   /* USER CODE END 3 */
复制代码

/ B: j- c# {) G; ~0 z7 H: G% ^( d 微信图片_20240615130212.png ( }4 w7 m( B0 k/ x. t3 l

; W* U! t. Z( H$ ]. ^2 M
* G  g, }, z7 j. t1 N/ ~
正弦波- P; P1 ?9 z# R
  1. while (1)
    & o) @5 c( n4 w
  2.   {* S5 u$ e, \9 ^9 E- h: B* N0 V
  3.     float t = 0;
    6 B; q/ f% E/ [4 _: w
  4.     /* USER CODE END WHILE */
    % P5 [- p' l/ r: O8 w& f' B
  5.     printf("A:%lf\r\n",sin(t));//正弦波
    5 F, ?7 u" i/ @, D& a' O
  6.     t+=0.01;: E4 T1 u- ^5 d& I3 L. }5 [+ b) m7 q
  7.     /* USER CODE BEGIN 3 *// t& y1 A% _9 V- Q1 A- o) g8 t
  8.   }
复制代码

% ^: E! m  T2 K# R. @ 微信图片_20240615130207.png
3 {, j& i- h6 u/ r; o+ n& K
  v1 X7 {# y0 w( @! S* x
& O0 v! c$ I' o) y1 M正弦波相加
1 V' j2 D+ G7 E
  1. while (1), D: n! I, |" D) V1 j
  2.   {+ ?, U) [( \  q) `9 R2 }7 B0 }1 _
  3.     static float t = 0;
    * g. q+ [% A% Y0 v( E$ u
  4.     /* USER CODE END WHILE */. ?7 S2 m; ]; ~0 U
  5.     printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加
    ! L6 i6 e1 `/ F" s1 g2 h% q
  6.     t+=0.01;
    ; _2 x+ N& |2 Q' |& N
  7.     /* USER CODE BEGIN 3 */
    ! j5 P# g7 d) \  D; }# @' p
  8.   }
复制代码

4 E5 {0 v6 r$ ^' S 微信图片_20240615130159.png
) I8 K0 g( E% |) z" L4 u' D
& O  W. m2 a; K( G5 f/ E7 Q5 ~9 j0 u$ g: L
正弦波相乘
; L/ z0 Z5 W, c9 y# ?  j
  1. while (1)( y" a5 k$ n& G# f0 j, V5 F$ H/ T
  2.   {
    . _: N' A4 b, `
  3.     static float t = 0;0 d5 ?8 W& n2 y- ]* i: X
  4.     /* USER CODE END WHILE */
      K3 ^' ^+ N" z$ [' H
  5.     printf("A:%lf\r\n",sin(t)*sin(100*t));" X' {. w; X8 i1 i2 {
  6.     t+=0.001;
    1 d. |% S' M- F  D5 H$ q2 T3 E0 x
  7.     /* USER CODE BEGIN 3 */" Q6 k; f0 e& z0 R- U
  8.   }
复制代码
0 o! ^+ E2 @: }% T7 d. Q& _
微信图片_20240615130130.png
9 U$ }5 ]; C6 G9 ?# d( M( f% i, h" }2 `0 F3 h) K
转载自: 电路小白
/ u6 Q# H0 H, H
) [' s; N# p: d% v* T+ Q  w* [如有侵权请联系删除
# M# q4 C. g& s$ D. c
. l6 O& ~( j* q% }" z- m5 a2 p& N# M" C1 t% j* I6 s, m. i
/ h  o& p$ L& B/ q: ]9 p
1 G* Y0 u. q6 o" x( _* @) [

3 W. F: w' r, J! T
" {! t# |" x- p4 l+ \4 J: l/ c5 _5 Q- w
赞 收藏 评论0 发布时间:2024-6-15 13:03

举报

0个回答

所属标签

相似技术帖

官网相关资源

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