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

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

[复制链接]
攻城狮Melo 发布时间:2024-6-15 13:03
串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。( }' w, v& d" u$ o3 i
本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。, O5 r2 i( V5 p) w" Y- E
; O( I1 }$ Z5 z" f& ]) y1 f
微信图片_20240615130239.png 5 S; h3 B; I, E  m/ k

. C' |) l3 P( U5 U3 S; h  a5 E% [9 c6 E/ P- I
微信图片_20240615130232.png 9 j' u" A7 R" p9 r) _3 u
0 n6 ~' d, d, o/ ]
首先打开CubeMX,配置时钟树和时钟源。
, f, l0 E  f% E% w
% }) Q. [9 [4 y+ @; i1 v 微信图片_20240615130228.png 1 ?9 m3 }% l# u: G5 O8 ^! V0 G
. g; \  F( X0 @  f
接着配置我们的串口,设置相对应的波特率。
" u! w! B! m4 Y+ y* D  i
! l) \* s. s9 e5 d 微信图片_20240615130224.png 2 z7 o; R8 Y) j' ?

% s% j2 `( \/ V6 q( Y5 H打开串口的中断。3 K# |" |3 J5 n- ^  L

0 }; T7 i6 G' l6 U4 Z3 n! B
然后创建工程。
9 i; k' a( v) k/ E  _1 u8 b
1 A4 d: m8 Y# B0 n& B/ [2 Y 微信图片_20240615130221.png
8 _/ }1 l: A3 m4 b+ S1 W
& o3 j- |+ N1 A1 q8 K
在魔术棒中勾选Use MicroLIB  o' `5 U: K4 c, K$ r! }( U! b
  1. unsigned char ReciveBuffer;
复制代码
7 }% Z7 I0 Y- G4 R  y/ M
在全局定义一个缓存用以存储中断接收到的数据。

6 I7 b& }( [7 m2 p0 A( C
  1. HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码

3 h8 k1 b. R4 `初始化的时候需要启动串口中断。
) ^4 I/ j+ ~( `9 d2 {
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)( E1 W9 s3 {. ?% a  _
  2. {- q, T  Z6 M7 V, i
  3.     if (huart->Instance == USART1)  // 判断是哪个UART触发了中断
    7 E/ K& p) a9 Z; A; M+ Z9 S  \% m8 n
  4.     {
    ' o( Z2 C0 N/ x4 O/ F' C8 W
  5.         // 处理接收到的数据0 M% a/ y# \) c3 b) q. {( ]& X
  6.         HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去
    % Y0 o: m9 n# v( \
  7.         // 可以再次启动中断接收! L) |9 i6 T! E0 q7 o0 x7 [
  8.         HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));
    ; U! ~- @  x3 u% ^. y; X4 E
  9.     }
    - X, V/ O$ s5 x& q0 i+ _6 L$ R+ l
  10. }
复制代码
+ E$ v2 {3 l: J# o( e0 K5 B
接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。3 \4 a8 S7 ]8 i/ y! h

0 n0 |6 ^; E* u' V, J( Q' m. ?7 w 微信图片_20240615130217.png
* [5 `/ w, G: {

0 M* ]9 c  h; g8 a5 b( Q% [可以看到,我们发送的数据被原原本本的发送回来了。
4 [; L, Y  ]9 _- K% E( X
! r3 {0 L. ?: `/ q0 I
串口的重定向

5 k, C" t# [1 q9 v1 \. {" t5 L, w重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。
+ n5 u+ C8 l2 d6 |+ {& h$ Q6 o" G3 ]3 F* ?6 _9 i& @: x
串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?+ z5 B; Y0 b6 r8 z
  1. #include <stdio.h>
复制代码
# n: w6 z* m& \
我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。
5 q5 W  g. B% c; v$ n4 n" z  z5 w! R; b! x  r6 e
通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。, e8 h: n7 f; U
  1. int fputc(int ch, FILE *f) {1 p, M" u5 S4 [* P5 l% W
  2.     // 发送单个字符2 ~5 i) r1 v$ o
  3.     HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
    5 D6 g4 G# f% J; O
  4.    ; C) H5 Y3 E; r& V! @
  5.     // 返回发送的字符
    - O) q8 @& d8 h- M" g5 n& j0 r1 r
  6.     return ch;
    ( |0 z$ P$ T8 b$ D3 C. C" r9 o+ `  D
  7. }
复制代码
  1. while (1)9 l# i# Z- D- ~7 |  W* Q
  2.   {' j, i8 Y9 w! w3 a
  3.     /* USER CODE END WHILE */
    5 b$ V, C& m. v- w. I) k7 z) W6 L
  4.     printf("Hello\r\n");
    : `* e1 m+ |0 `1 ^
  5.     /* USER CODE BEGIN 3 */  W) Y8 W2 d' `. P
  6.   }
    ' o; i* Q) \1 ?; W0 M2 Y
  7.   /* USER CODE END 3 */
复制代码

; m3 y# i$ l$ ~& |- a# _: g; Y7 _ 微信图片_20240615130212.png
; [2 ?0 D; g2 ~0 L' e; l3 \  j& w
7 I( g% C4 M/ l/ w! i

" W; g2 j& O0 C) R6 T. b5 q5 L9 b正弦波+ q7 L0 z1 I: ^' w4 K; d( c. c+ B
  1. while (1)
    5 R* _; W7 l, G; q; h/ \# h( t3 i. a
  2.   {1 @% x; R# ]: W3 G% S
  3.     float t = 0;
    : _& }- V+ q: x+ b6 ~3 G4 Y
  4.     /* USER CODE END WHILE */
    ! ^4 l8 h% H" v3 i
  5.     printf("A:%lf\r\n",sin(t));//正弦波$ ]* l/ S1 a$ x
  6.     t+=0.01;
    % _& U2 F- F5 y2 L# C
  7.     /* USER CODE BEGIN 3 */
    1 \8 s# ]% y' v
  8.   }
复制代码

" ?7 g- G3 g) f 微信图片_20240615130207.png
2 t5 ~7 X& C' X  @/ r' L4 f. G. Y5 q4 F! I
. n; ]" Q0 E7 B
正弦波相加
! i! k, h! I1 _/ `1 @# g
  1. while (1)$ y+ L. P: R# |7 q" X! ?8 d. N  Q
  2.   {  q3 ], q) I2 g( c1 Z% _
  3.     static float t = 0;& |% F  f/ A: D( y
  4.     /* USER CODE END WHILE */% N* a8 V! Z% c) @$ Q* k5 H- i
  5.     printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加% t5 g" }9 ]$ S+ {, v
  6.     t+=0.01;
    ( Z- ~' u$ i" c
  7.     /* USER CODE BEGIN 3 */
    / N9 U& `$ R% @
  8.   }
复制代码

& f% j: s* J4 S. c  C+ U. x 微信图片_20240615130159.png 2 h# v: X% o1 X

: n/ a. z# r$ G0 z: J: n  h3 x6 b  x3 M1 B0 o3 p
正弦波相乘
; r& `* a0 B6 T& F
  1. while (1), C. X; {9 j' ?% [0 y/ g# O0 c
  2.   {
    * K- G+ H7 `5 _2 y: r0 B
  3.     static float t = 0;
    3 o) P& u. B) |3 o0 E
  4.     /* USER CODE END WHILE */
    / S, n) n: ~' W" K9 ~; q* q) J
  5.     printf("A:%lf\r\n",sin(t)*sin(100*t));
    2 H7 |; @' n- A# P
  6.     t+=0.001;
    " s* `' O9 l3 Q+ G2 c
  7.     /* USER CODE BEGIN 3 */
    4 L8 p* p2 c/ j7 x, P3 w+ B1 X* D
  8.   }
复制代码
1 y( n# M5 x# v0 s4 {1 _7 `
微信图片_20240615130130.png 3 N$ \7 p$ S; s8 P- U
" S" U/ p, m; B: B/ O
转载自: 电路小白
! S) l+ b" O& {* C; \$ Q6 r3 k7 F1 ~- B% m) |" y
如有侵权请联系删除
1 |' m$ y8 X+ i- u$ I- N  h3 D& b+ c4 l; k

+ C5 s& O) W9 u4 }+ L3 ]
; }( v, @- c! b) N8 D! P6 P5 v) Q9 @5 J" s% ^0 A
9 P* t3 U9 h9 N* x+ m
7 S; }2 x9 v3 ~$ Z9 b: A. |% Z
收藏 评论0 发布时间:2024-6-15 13:03

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版