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

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

[复制链接]
攻城狮Melo 发布时间:2024-6-15 13:03
串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。
& m4 S' O, Z! ~: t! n1 T, P, ?0 Q本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。
, T- }3 `& K3 U6 B7 e, z  H7 p' x" \: m, J+ J& a$ Z
微信图片_20240615130239.png # d1 s9 S3 l/ h' }0 Q  q
# @0 L2 C3 X3 B2 ]

, a9 Z) t, _' J9 E6 X) N 微信图片_20240615130232.png ( `5 p5 h: w6 o. o
" s" {8 R, b3 R
首先打开CubeMX,配置时钟树和时钟源。" E) t( v5 Z7 Y# ^& Y3 A

& N2 e& y0 e* w9 E% z0 ~ 微信图片_20240615130228.png : A; X+ m- A3 o* D0 [

2 p" l! x- v5 S6 p1 n0 e' ~接着配置我们的串口,设置相对应的波特率。) K& J( t, L; C7 B$ A2 d& s6 a: D
  G6 G! u" M2 S4 x8 f# L
微信图片_20240615130224.png
9 H6 ]  `: a% [9 ~  w! ^: l% q4 W9 L
4 d  m- {; C0 g- J
打开串口的中断。
' F- i0 I3 H% R: p, y5 p' l
# H& c, |2 a4 ^1 s9 q, R# q
然后创建工程。' e4 M+ z; ?: v- P7 T7 ~$ |8 k

+ D/ B7 q5 Y* G* ], U 微信图片_20240615130221.png
) D3 ^# B  ~6 \: A6 m
' Z1 ]8 ~2 g! M, }% N9 q6 r
在魔术棒中勾选Use MicroLIB. l9 T& m* i+ R7 d: s/ h% x
  1. unsigned char ReciveBuffer;
复制代码

. ?0 _) E$ `; }) w* G- X. z在全局定义一个缓存用以存储中断接收到的数据。
' L5 m$ C8 q7 Y4 t; ?! {
  1. HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码
! s/ B4 h2 l% [
初始化的时候需要启动串口中断。
6 }4 Z1 Z1 {/ d7 C
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    . j4 [; |4 G' }
  2. {
    2 f6 d) e6 D6 m" q2 }# |
  3.     if (huart->Instance == USART1)  // 判断是哪个UART触发了中断4 f9 G3 d/ |2 R5 U; G
  4.     {
    6 \2 `% [: p; I
  5.         // 处理接收到的数据
    ' R- b+ J6 g) B( q7 b
  6.         HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去; z/ M  Y* _' ~" {3 C' U
  7.         // 可以再次启动中断接收
    ( I2 ?; |( f/ F; c6 c: h& ~
  8.         HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));
    - B3 H9 q: }4 r! n
  9.     }$ `* G2 ?% o2 L/ S7 [3 K% N
  10. }
复制代码
" Q6 G3 C7 U+ d, A" Z
接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。
+ J# {7 p8 x' T0 \5 D& O7 D+ b8 G
2 i1 |0 G  n! _5 b3 S8 N 微信图片_20240615130217.png 3 T4 I+ Z% r" Q

4 Y+ y4 R, O8 b+ L可以看到,我们发送的数据被原原本本的发送回来了。
0 \( k( D2 M% o. q& G8 [
% O9 k8 _7 j" o6 j2 ]! o& ]4 U
串口的重定向

# Q3 T( R6 \1 S. Q重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。
: z, C* m2 S7 @4 n4 b
. w8 M9 U" @5 F* O) x( e! Y0 u
串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?  Z/ W- W0 l% m, p
  1. #include <stdio.h>
复制代码
$ \4 u  H( ]1 i: g$ D, f
我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。
; [/ X$ F. }, y2 h
0 G% y1 Q& g1 O4 n: @% {; M, G
通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。- U  d: V/ p1 {
  1. int fputc(int ch, FILE *f) {
    0 S0 I. h# l! \& c  {2 N
  2.     // 发送单个字符
      M1 Y+ U' R7 }! Q3 a, w8 M
  3.     HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);% ?1 J# b, S  U! y0 G  a+ z( V+ w! }
  4.    , Q( ^% k7 K; T' S8 X) N  c
  5.     // 返回发送的字符: j/ q: \, x2 v( a! o: I
  6.     return ch;
    * F4 A9 O3 t1 n9 v& M5 `) ^# j
  7. }
复制代码
  1. while (1), G; J$ t5 b% k7 C1 v6 R) s
  2.   {
    % [: s$ M6 N; [& O% O, ~
  3.     /* USER CODE END WHILE */' _3 |8 R% Q: i1 z3 u: F4 w
  4.     printf("Hello\r\n");( E6 l1 y3 F7 u- {4 [: u; {
  5.     /* USER CODE BEGIN 3 */
    + V, n2 C9 C4 i+ L- d& U
  6.   }
    ; r5 \8 y* W0 d- U
  7.   /* USER CODE END 3 */
复制代码
$ B/ L5 m! n7 K2 x, V! @' N* e' R
微信图片_20240615130212.png % P% C: ~; o2 ~3 u  J% _+ l

1 v  R! P2 k) u

0 i' Q4 `4 o( v# Z9 \* w正弦波% z0 u" @7 ]) _: \/ s. R9 a
  1. while (1)5 O4 C  O8 q. x" ~
  2.   {6 `/ ~) b" g; {! d6 L/ j1 u* U
  3.     float t = 0;4 z: E7 }/ _- P
  4.     /* USER CODE END WHILE */
    1 ~( Y8 ^0 O* M' b& h
  5.     printf("A:%lf\r\n",sin(t));//正弦波
    $ m- s/ h# i8 [6 y' F* g
  6.     t+=0.01;2 m1 M* U7 q4 d. w( I$ e# |
  7.     /* USER CODE BEGIN 3 */( G: z8 H1 R# e
  8.   }
复制代码

- H8 K7 p- O. a. A7 c/ a 微信图片_20240615130207.png
: q) E  b- V1 U' f. L6 }' E: W0 [, C9 H1 h8 [: T, U- C& |

% R1 z% i; u$ {1 ]$ B正弦波相加0 O1 }' y/ [" \* V. G  `" t
  1. while (1)0 X& W0 [+ P4 f" B( w1 U( ~
  2.   {- m) K$ s  n; F1 B! B3 Z/ d4 _7 W% H
  3.     static float t = 0;$ b+ i" z7 q/ M5 @; Q
  4.     /* USER CODE END WHILE */  v* H. a; Y/ X
  5.     printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加
    % ^9 h9 m7 ^2 y" d+ d& P: L: x
  6.     t+=0.01;9 J; |! n8 i6 e/ ^7 q# P3 |
  7.     /* USER CODE BEGIN 3 */
    ) z4 n* ~9 M, j5 `- F- C
  8.   }
复制代码

0 Y* f  N" x) x0 a 微信图片_20240615130159.png , k6 i2 \6 _8 d  n. i1 I8 g- ^

, n( n" H% D& h4 @6 v3 t7 J% V: W% R- U0 e
正弦波相乘! {3 C6 e' G/ q7 n9 A5 w* t4 o
  1. while (1)
    7 M/ S  R6 {: l0 {- U# W# d' S
  2.   {
    % N+ x& O) r1 \3 S1 ~5 s8 g
  3.     static float t = 0;( n5 q' D' c; h1 ^- l
  4.     /* USER CODE END WHILE */4 F9 I  F- k, j! C
  5.     printf("A:%lf\r\n",sin(t)*sin(100*t));4 @2 h* c# {/ _& p& E
  6.     t+=0.001;( e& @6 z8 B- i0 x/ t
  7.     /* USER CODE BEGIN 3 */
    0 c% d' J" [6 C
  8.   }
复制代码

8 [7 v" m6 d" g0 ] 微信图片_20240615130130.png ) Y2 J4 _  p( F: s: m& R8 q3 Y  f
3 W' J- n) B7 @7 }8 {) c- S
转载自: 电路小白
9 ]. }" C0 Z  A% u
  ^- q. {- c$ w' g% B. z: X$ n$ h如有侵权请联系删除" {1 S, I7 C5 i8 \2 S

& M- y+ Q, {9 k
( k4 F* o. K" C1 j( E- p
7 h. K9 e6 _5 F7 K: {( x4 c' m' h( p! x3 A

  d3 ^/ x' r8 V+ R9 F9 _! Y, c( @+ b! z# Y
收藏 评论0 发布时间:2024-6-15 13:03

举报

0个回答

所属标签

相似分享

官网相关资源

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