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

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

[复制链接]
攻城狮Melo 发布时间:2024-6-15 13:03
串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。
) p+ C& _/ Y, @3 w0 N8 L' u本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。
5 Y" f5 u: B3 J. g* }) r# S( k5 n: ^% X" S6 b6 H, z' o6 E9 I( G
微信图片_20240615130239.png 2 X3 I+ \% ?; c+ W" z
8 P7 s% b7 X, p+ _& n, o/ i

+ g* t; b0 u4 w( @5 {! O 微信图片_20240615130232.png . e4 t$ J4 a- t& N% ^

$ b) M2 q1 i. W: \5 K; |1 q首先打开CubeMX,配置时钟树和时钟源。
( p$ I. k+ a2 P7 J
$ w7 p% B7 S( ?( r 微信图片_20240615130228.png
& S8 e+ T. q% x5 v1 d) \

0 r4 Z; E5 m+ I" }接着配置我们的串口,设置相对应的波特率。
, h) i# z! H, v% B2 O
# y4 O- _. `7 o7 c 微信图片_20240615130224.png
& E3 \) c1 \1 a7 \

8 \; u0 t) @( k5 O! ?+ J2 _* g打开串口的中断。
# k! u, f5 q: C0 U7 E
" c& J+ C- k$ o3 _8 k6 X/ E
然后创建工程。
' d+ ?2 \5 y$ n
& c" h/ ~  X, t9 U; F 微信图片_20240615130221.png
: V. c% `8 b/ Y- Y8 G( f2 K
* t) P% i! P6 E2 V+ b3 Q
在魔术棒中勾选Use MicroLIB( \; f8 P& i9 ^; p' l$ p& Q/ [
  1. unsigned char ReciveBuffer;
复制代码

/ W! ^5 D  H  }9 B在全局定义一个缓存用以存储中断接收到的数据。
) |. y  L8 g+ i
  1. HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码

. b8 }3 u9 r' |/ N( A初始化的时候需要启动串口中断。* [0 o# K& h% G1 P+ C
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
    / l$ D9 U( D7 _3 j) z5 A9 E  u
  2. {8 i8 q/ j: p- q1 `  C8 A7 M
  3.     if (huart->Instance == USART1)  // 判断是哪个UART触发了中断! V; a! J0 e/ r! v! h' D5 I- i- @
  4.     {
    " Y' X' _  |9 z+ I( p4 r0 n1 @9 j
  5.         // 处理接收到的数据- m2 N, V8 A3 u; t" q& s4 o
  6.         HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去7 x# M% t9 |: u7 M
  7.         // 可以再次启动中断接收
    . I* x, w, \' Y1 y, |1 c
  8.         HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));
    - a  u9 M( i6 M
  9.     }
    ( n1 J7 \. R" L
  10. }
复制代码
# [3 g; y' ?* t
接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。" Q2 s1 b; `8 z( i" K; p
) i5 M9 D  a7 a- j, s
微信图片_20240615130217.png 1 Y2 h2 i, O7 F% C
: X. W, M9 ]0 _: p
可以看到,我们发送的数据被原原本本的发送回来了。
  S  ]# P. i( a# X) ]/ S# |7 O3 e& c, g& w2 B) ~
串口的重定向

! w; @% ?9 h- g4 L' _7 m# x6 @" H重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。7 ]" }! y: p' h0 N" M# [. M

$ f1 X- [% P1 t6 |! F2 t( x
串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?
3 H! b* {8 ~8 y* U, W$ V  A5 g* I
  1. #include <stdio.h>
复制代码

0 K& J" @+ M$ K! z* h; j& k; g我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。7 e4 J8 H. O1 ?9 A6 M: A7 D

; g! c5 A  r2 S" k
通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。
6 V( L1 K/ l* c/ }7 |( y! M' B
  1. int fputc(int ch, FILE *f) {+ E  o+ C5 j5 s, [2 c6 q9 g
  2.     // 发送单个字符
    7 f4 r+ S3 |" z# y) K
  3.     HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);  |0 F$ d" m- m, i7 Z( F( ?& Z
  4.    / T+ C. A, J7 ~$ j
  5.     // 返回发送的字符
    ( T9 O/ N0 Q% M8 m# B  V# i
  6.     return ch;
    1 k$ [% Z- L2 `# W: B4 G# {6 K- l
  7. }
复制代码
  1. while (1)* E: ]: ^% a- }  J, b
  2.   {
    $ Y" N6 s0 p- @! u# m* V
  3.     /* USER CODE END WHILE */" V2 {! @6 T+ D- `$ t; ^
  4.     printf("Hello\r\n");
    1 i3 |5 {9 v9 G) o
  5.     /* USER CODE BEGIN 3 */
    - W  j' ?- k- _4 n% T, j
  6.   }- U( ^0 U( @  u' A
  7.   /* USER CODE END 3 */
复制代码
. R+ c/ K8 C  n8 Y( N8 H9 q
微信图片_20240615130212.png
% h2 N6 M" I) l2 e; @; n3 R; O0 l0 g" }2 F' U2 `4 A  z
9 V& |! k  Z1 f$ d
正弦波
- z+ V1 c4 C1 R8 W' k; X
  1. while (1)8 j0 E, {! D; y# F( @
  2.   {+ c2 r6 ~, G2 a! O$ G7 S
  3.     float t = 0;+ r# S! I5 w! L, ]% T4 J- S' C$ J
  4.     /* USER CODE END WHILE */0 d: [9 d: H6 t9 p1 L
  5.     printf("A:%lf\r\n",sin(t));//正弦波# f- w6 j& h  T
  6.     t+=0.01;
    : ?/ `) _6 y) S4 H+ ~
  7.     /* USER CODE BEGIN 3 */
    % q% p+ |2 e" S) [. W- H- c3 V
  8.   }
复制代码
& s  l7 m! t. D: n5 I1 U" u" _
微信图片_20240615130207.png
. ^* z: t; e' N' t
) W8 \/ c; m% {+ m- `4 l/ T* \% N' z8 X6 p- z3 s7 F* v) B/ U
正弦波相加
, c) u+ U4 j. L# O( e& F
  1. while (1)6 n( C- J5 R; Y' [
  2.   {# p+ L$ Z  b# f& e1 p- Q
  3.     static float t = 0;
    9 |, U+ w- D) l2 p" V% W$ q- i; O
  4.     /* USER CODE END WHILE */
    ' x1 m# s' z' s3 W
  5.     printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加
    ! w2 Q  F4 U! x/ [, B% W; n
  6.     t+=0.01;$ v; \- \: X5 |7 Y
  7.     /* USER CODE BEGIN 3 */( V6 z5 J0 ^% u: L
  8.   }
复制代码

9 t- _6 }9 E7 S$ l7 [% W 微信图片_20240615130159.png
2 K8 d0 `; o8 H5 F
8 }4 a8 {$ q, o5 Y( m( F" V% N0 i8 c+ _: I
正弦波相乘
4 ?' s! {6 Q% Z4 k. T
  1. while (1)
    1 v- c! B2 ]7 D! v9 Z4 j
  2.   {
    $ w5 ]& ~, Z- ^( M
  3.     static float t = 0;
    / B$ u% ~% I( T, D4 I% x5 e
  4.     /* USER CODE END WHILE */' r( ?( w5 P# r& S# o8 f( R$ c4 l
  5.     printf("A:%lf\r\n",sin(t)*sin(100*t));
    0 D* j' o" E' b  s% b+ I9 ]" U
  6.     t+=0.001;
    , R6 `* q2 G, k; [; `
  7.     /* USER CODE BEGIN 3 */
    3 {$ p2 \% f& ~( G2 A
  8.   }
复制代码
9 t. ]% A% p, g* q
微信图片_20240615130130.png
7 q9 @! d6 B! r0 u7 T4 `  p5 k
' X7 B' a$ J( m/ o! }3 d! A  h转载自: 电路小白
4 p/ Q  ^* _# s. Q4 n
8 g# Q' V  Q4 l/ h9 D4 \如有侵权请联系删除
  o, i4 `, r0 H; `( n& q$ n, W6 h" T: B& p
$ ?' o: X8 B" q8 b9 H0 ]5 n

) ~# O1 u. b+ \9 K4 v
, d0 y& }7 O- N1 c) T0 x2 @. y/ w* S: T# w# I5 G

6 b" V: ]+ A$ u
赞 收藏 评论0 发布时间:2024-6-15 13:03

举报

0个回答

所属标签

相似技术帖

官网相关资源

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