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

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

[复制链接]
攻城狮Melo 发布时间:2024-6-15 13:03
串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。8 M. L" [  P- v% l' D: g, c
本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。1 ?" b/ }) W; \" u
# K, t! h6 v& ?/ g
微信图片_20240615130239.png
4 B$ A  {/ c& M( r* M8 Y6 v! c: b- w& a# _# L; A( d# Z! y
! G" A& e3 ]! f. C& N
微信图片_20240615130232.png
- v8 ]* H3 n1 i; \' l6 Z- Q( ]- Z/ {, b% d3 H
首先打开CubeMX,配置时钟树和时钟源。
* O$ K; ]; C  \" J% k3 f) ^* x0 ~6 P1 e" w" i
微信图片_20240615130228.png * D4 |& Y/ a8 E# e' K2 K, q

( c5 I' ^# w6 b) u, I9 J接着配置我们的串口,设置相对应的波特率。0 {6 b% V7 a; d$ p3 I) e7 s" K6 @% \
) z6 z4 Z6 f8 E3 _" b  m
微信图片_20240615130224.png / q8 t) ~5 V# ]

) q* Q& p; Q3 c1 \打开串口的中断。
+ B9 ~( W8 ~! f1 K2 a8 f1 Z' ?8 |4 J
  n2 f) I7 E3 J
然后创建工程。
+ Y$ D6 i- |1 |; M+ e0 F9 t( k' W% r! d/ _, E& b; }* u( E' L
微信图片_20240615130221.png
( @, F$ y  c1 L8 {

2 M9 f# Y3 Q  o在魔术棒中勾选Use MicroLIB
, W- x/ ^5 Z0 k7 |
  1. unsigned char ReciveBuffer;
复制代码

! O* h/ P7 P) r4 ]( Z7 U在全局定义一个缓存用以存储中断接收到的数据。

" m8 Y0 b( E6 Q! K- d' n! n) |& ^
  1. HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码

! H7 m1 {; Y! |9 {初始化的时候需要启动串口中断。
# v& T! _. H. @2 _* R
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)# {& k8 [  F: p7 P, h" }
  2. {
    6 Z$ T# w, D7 B# {- ?. q
  3.     if (huart->Instance == USART1)  // 判断是哪个UART触发了中断
    : [. T" t/ s" G, M5 ]- |
  4.     {- d: f: A  h2 s) ]  S  U
  5.         // 处理接收到的数据3 k0 r. S, `) U  P5 @
  6.         HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去  G7 e8 E* w3 o' s8 k- S/ v
  7.         // 可以再次启动中断接收
    & C6 M9 e9 |" ?; h
  8.         HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));
    6 N% ^1 H, c0 O" U7 W& W
  9.     }
    / d% Q' G# j/ \( z: w, n0 i
  10. }
复制代码

5 d2 Z. O8 b- a2 g接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。0 X2 O' _$ X1 P% k0 D$ f

) B" I3 l) q1 I( I: W 微信图片_20240615130217.png
+ {0 n* @0 d( L6 }* [  L1 b! P: K' b
/ G6 X4 ~  |" ^4 U
可以看到,我们发送的数据被原原本本的发送回来了。
; r8 B) |; f% V# P3 W
7 s) q3 t+ E2 `- B( {
串口的重定向
" g) p/ F" t" r4 Z+ X$ E
重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。
6 q4 m8 s7 A$ G; C/ {0 `
, ^! K6 A* G6 y* |% ]  Z+ K) s! E
串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?( [: s/ I7 K* B% f5 E+ O
  1. #include <stdio.h>
复制代码

! k1 R; F9 @9 _4 V. T+ M! Q我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。' F; y6 A/ z: j9 k) L: Z1 c
3 }6 ]+ X0 i2 I' K- a! R/ B; @
通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。
% |' {* Z! Y' ?- _; g' [, I
  1. int fputc(int ch, FILE *f) {, U. K# z. _4 r9 e( y! J
  2.     // 发送单个字符4 r4 U) `& G2 T
  3.     HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
    1 E+ R% U% {( O) s$ g% t: O1 G; Y3 q. w
  4.    ( u/ _: m7 w6 X3 ~% x* {
  5.     // 返回发送的字符
    ) l: c& @' {+ I: @  K9 B7 E/ H6 g
  6.     return ch;
    : ?1 Z' o3 e' I3 H
  7. }
复制代码
  1. while (1); T0 Y6 \  e5 @0 {: f+ u4 ^3 n
  2.   {
    " k: l. ~( M8 L
  3.     /* USER CODE END WHILE */
    : ?6 p; v' N  T1 i/ V2 M" a
  4.     printf("Hello\r\n");2 ?* M) V1 C! ^+ W1 S  j
  5.     /* USER CODE BEGIN 3 */
    , b9 N6 m+ R% i$ H
  6.   }& Q, z. F8 ~  u+ p; C' X3 d% f
  7.   /* USER CODE END 3 */
复制代码

  X. k& h8 H- ~ 微信图片_20240615130212.png
* q5 J+ r& y1 S; q" Y! m
$ t% L# X0 G3 F  ~3 ~0 @# s8 H1 {
5 `7 ]- v8 O; h
正弦波
% q% E( z, y& M" a2 {- u
  1. while (1)* p6 n8 {1 j0 T* L8 k
  2.   {6 W' o, _2 ^9 K! \
  3.     float t = 0;* \' s+ F* W+ j. B1 x. r
  4.     /* USER CODE END WHILE */, K+ U) l- T* u; `0 F( C) q
  5.     printf("A:%lf\r\n",sin(t));//正弦波
    " D, z, d3 i7 H+ _
  6.     t+=0.01;$ i0 ]  v1 L2 O5 t
  7.     /* USER CODE BEGIN 3 */, `8 K( f* m$ ?1 @
  8.   }
复制代码
" n/ Q5 d4 O) }$ s- F7 `
微信图片_20240615130207.png % Y# {6 e" [* t/ {& ~; h+ _
( P8 O+ A7 v# q6 c2 {+ l) z

6 h$ Q) Y/ ?- B2 K; W4 F$ e3 ?7 j# [& A正弦波相加; S5 t) D8 H0 o8 }7 O5 n
  1. while (1)
    5 P. ^# A1 }7 }' c
  2.   {
    ) _8 [/ P, r0 o. z# r" R; g
  3.     static float t = 0;
    ! \% U) r6 y4 q' n0 s6 |
  4.     /* USER CODE END WHILE */. c' O" u5 w3 g; F; |
  5.     printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加+ m  Q; N: Y9 O. \9 y
  6.     t+=0.01;- z: b6 n0 T( P5 i' L
  7.     /* USER CODE BEGIN 3 */# n/ l6 @6 {7 W6 R, F
  8.   }
复制代码

  Q& [) l9 G, Y' |6 s# I. t 微信图片_20240615130159.png
8 N/ C, k- P& J; M/ y
, `1 q% u/ p" F1 e) M+ P3 g5 S- ^
% A! F# o$ l- a: d! H正弦波相乘, o- e; o) I& @/ r9 A6 i) {
  1. while (1)0 E& b8 s% d7 m) A; x, g4 ?
  2.   {" s/ Y. b; y- a  _" M2 @2 P
  3.     static float t = 0;+ D3 y# R2 D! D
  4.     /* USER CODE END WHILE */4 u) I" H/ B4 y9 L) p* b& a( P2 I
  5.     printf("A:%lf\r\n",sin(t)*sin(100*t));) q8 W) k1 @7 [3 t
  6.     t+=0.001;
    0 ^/ I8 d; i3 @  G- Y$ ]7 b
  7.     /* USER CODE BEGIN 3 */0 r" _" B1 k( k$ q2 H0 K
  8.   }
复制代码

7 j0 ]8 G( d- Z 微信图片_20240615130130.png , f: J7 G/ f0 V4 B$ e( l) R+ @$ Q8 X

& r$ e0 u% k7 U2 [4 G转载自: 电路小白
, Q" B7 Q9 n5 W8 t; b
& o  M( f0 S7 U# ^" {& }4 R如有侵权请联系删除# o8 Y5 m! U$ |8 `+ F

6 Y2 {! O4 \/ K- U# W; R- Z  g, s, E' y) h+ I
7 V% G, n) ^! f( \& w
$ k; D! ]1 i2 Z; ^9 A" p0 @

  h6 H( z: j3 `
% K, V' L/ s" T. j
收藏 评论0 发布时间:2024-6-15 13:03

举报

0个回答

所属标签

相似技术帖

官网相关资源

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