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

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

[复制链接]
攻城狮Melo 发布时间:2024-6-15 13:03
串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。! U  c% I% g5 a0 L7 W
本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。
5 l/ K, L! P* y$ X
+ w- \3 v1 e& X, g 微信图片_20240615130239.png
- [8 q) S! f& {& j9 Q( `5 z* Z
* n; F5 G% _: d" m  u, N. _) F9 O" x
微信图片_20240615130232.png
5 d7 a6 {8 R8 I" r+ D
& J5 s5 O+ B% l& W& b& l* C3 e首先打开CubeMX,配置时钟树和时钟源。( ]' B/ @0 O- k
3 j4 B! T; n* @6 O- n
微信图片_20240615130228.png
4 E) a8 G+ T, L1 {0 P: O
9 N+ s8 a$ i' @& ]* h, e' \' ~
接着配置我们的串口,设置相对应的波特率。
9 S, [5 a0 a$ m; H: S: |/ k; Y* T; U  l
微信图片_20240615130224.png
7 E* E8 S# c8 n: S- z1 e* l' i

0 \3 p" P2 b* l' z打开串口的中断。
: r9 m' ]: }6 M  w/ _' w. d6 b; C' P5 [7 l& F3 ^! f: @
然后创建工程。- k& V3 C, `; o  R7 {

+ v, Q' s2 ?) Q  D# O 微信图片_20240615130221.png
# O  q" m* |' W1 b8 Z3 b6 w
$ k  r' }# h  |$ f
在魔术棒中勾选Use MicroLIB& ]) Y2 m4 Y, v
  1. unsigned char ReciveBuffer;
复制代码

9 l. `* m# k! u4 T  T在全局定义一个缓存用以存储中断接收到的数据。
+ w% k& ?' E' G5 ~% j# V
  1. HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码

2 ^0 u! @5 ]. w初始化的时候需要启动串口中断。8 a2 n$ }- W- E1 X& s  o1 c% D
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    8 n6 ^/ V8 S% x2 d
  2. {+ G% M# I9 U) j. ^# j
  3.     if (huart->Instance == USART1)  // 判断是哪个UART触发了中断
    & b8 \" k; T7 L
  4.     {7 o# k/ E$ h% U+ A& }
  5.         // 处理接收到的数据
    ( B2 [1 C0 c& t* |( |- b% K, N: b
  6.         HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去
    6 i0 D+ n$ z1 R: j# O
  7.         // 可以再次启动中断接收+ Z! l4 s! p2 S" K8 e. P4 i
  8.         HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));7 }6 }" _8 p3 M0 H1 ]8 f# d6 D) D
  9.     }9 O8 i7 [* u1 H2 V* M* Y
  10. }
复制代码

+ P8 B. _* D2 L( u! I: R接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。
: z5 q9 Z/ S# }) i* l: }
, y5 x* V/ p) M7 @5 m+ P' t 微信图片_20240615130217.png 2 n1 Y% S5 N& Q8 d

$ m: N) q4 v/ j) c3 b可以看到,我们发送的数据被原原本本的发送回来了。! n9 m& `& Y' e- y

% a, w0 j- s- l/ `3 L* s2 b& n
串口的重定向
, _1 }/ U) C( @! m" c, r
重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。! D" X" [4 g- ]+ R7 Q' N5 e4 I

) F! I5 ?( `# r4 Q* I
串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?
# Z0 W- C4 V$ c+ t
  1. #include <stdio.h>
复制代码

8 r5 y2 ?% S" i/ ]我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。
3 o. o8 _) y7 V6 m+ j( q) J. ~4 k1 l4 |3 u7 A3 f
通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。
# E: \+ w3 E# |7 d: O7 r8 R' H
  1. int fputc(int ch, FILE *f) {- L7 c6 a/ @+ I
  2.     // 发送单个字符
    8 _5 j+ B1 ?8 H* Q" d* b
  3.     HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
    - l0 G2 j; r. t/ F( J" l9 w$ G
  4.    4 n" F1 X3 F/ S  q
  5.     // 返回发送的字符
    $ I: l3 g, u3 |4 V: ]9 C2 l
  6.     return ch;0 p, s% L: v7 g# M% `5 ~' _
  7. }
复制代码
  1. while (1)
    * W) W0 j* ?( g% `2 L! p* `
  2.   {
    4 j! ^- Y& i5 p$ a6 {$ V2 u
  3.     /* USER CODE END WHILE */: @7 l# {- o+ K$ F/ h
  4.     printf("Hello\r\n");# m: Q9 i; p/ j0 v
  5.     /* USER CODE BEGIN 3 *// m% A( f, n' m2 V
  6.   }' O  f  g$ g) O' W
  7.   /* USER CODE END 3 */
复制代码

1 [" H1 {  X5 N 微信图片_20240615130212.png
$ O7 `3 B5 R! i5 m# z& n; M, S5 [
, R+ G* W3 }7 I0 @% j- _! _
正弦波6 u) {2 y1 T/ a: w8 J8 a1 J- n
  1. while (1)
    : R# N; n; U( l5 r- Y
  2.   {0 K9 [+ f9 N1 Z( \& c. p/ e
  3.     float t = 0;
    5 I% L9 J9 u7 f+ b  U, @+ v! ~( |
  4.     /* USER CODE END WHILE */
    + ]- k6 U% L9 v  U
  5.     printf("A:%lf\r\n",sin(t));//正弦波" _' }* P3 B& d8 e9 k
  6.     t+=0.01;+ T- @5 N0 ^! Y/ ?* J
  7.     /* USER CODE BEGIN 3 */
    " q4 m$ u5 I2 B" s' B
  8.   }
复制代码

- ^, \5 S; g: ~/ w- I 微信图片_20240615130207.png
. `/ a2 n( d; J# S# W5 x% Y, I$ c+ w: F0 g2 x8 ^

" i; v7 z8 M$ j  }6 O正弦波相加
/ z  ~1 q8 C+ v2 S/ \
  1. while (1)) a2 c5 G& ?# q$ f9 q1 I3 v, U' u8 D
  2.   {
    6 U" u4 u% l. f# y8 W  X2 |; \5 e
  3.     static float t = 0;
    9 ^% H7 f# p$ v1 @- j
  4.     /* USER CODE END WHILE */; D1 D) E6 D; w! b' Z
  5.     printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加3 t/ e% [, J. J3 S8 J0 ?
  6.     t+=0.01;0 ]! X7 N% t) x- _
  7.     /* USER CODE BEGIN 3 */
      n, l: x% K# m3 K- N
  8.   }
复制代码
- j1 K' C3 F2 u
微信图片_20240615130159.png
! g6 [; W9 h7 k5 A0 v! Y, w2 M6 t) X& j* I0 a) D; ?+ g
7 N) J' w7 z4 H2 U
正弦波相乘
; h  Z. i' C5 k( q- V; n
  1. while (1)8 O8 O) X: U# J4 @
  2.   {/ C  s+ h& \1 T
  3.     static float t = 0;
    / n' X* o$ {2 f6 h
  4.     /* USER CODE END WHILE */. J5 b' k! h6 L. ^
  5.     printf("A:%lf\r\n",sin(t)*sin(100*t));9 q; x$ B7 V, S9 \
  6.     t+=0.001;) ~) L# V3 c& X# G5 O9 Q- f
  7.     /* USER CODE BEGIN 3 */
    & E: C- K6 r, |0 D
  8.   }
复制代码
) N- M: h  W7 w! n# C5 z
微信图片_20240615130130.png
! c: d' B( T; g$ a2 _
8 W% C4 D) {" f0 M转载自: 电路小白
6 v: f" |) K* e0 {9 _5 G  a7 [# I4 b3 x$ L: [% k9 }
如有侵权请联系删除0 ~7 g+ P: P6 ^6 i2 K* X0 ~( I

% b& G# q0 P$ F- B  e0 [9 C9 e# Q$ B* E( B+ }) j8 i: E. m: Q' `

  m- ]. [" `' C8 t" _7 M; m* \0 s# }+ ?, g( B& s9 o# g  M

1 d5 K  H1 j8 w; T: h% {/ a. a* Q2 V/ Q. W# k* _
赞 收藏 评论0 发布时间:2024-6-15 13:03

举报

0个回答

所属标签

相似技术帖

官网相关资源

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