串口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
# d1 s9 S3 l/ h' }0 Q q
# @0 L2 C3 X3 B2 ]
, a9 Z) t, _' J9 E6 X) N
( `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 ~
: 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
9 H6 ] `: a% [9 ~ w! ^: l% q4 W9 L4 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
) D3 ^# B ~6 \: A6 m' Z1 ]8 ~2 g! M, }% N9 q6 r
在魔术棒中勾选Use MicroLIB. l9 T& m* i+ R7 d: s/ h% x
- unsigned char ReciveBuffer;
复制代码
. ?0 _) E$ `; }) w* G- X. z在全局定义一个缓存用以存储中断接收到的数据。' L5 m$ C8 q7 Y4 t; ?! {
- HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码 ! s/ B4 h2 l% [
初始化的时候需要启动串口中断。
6 }4 Z1 Z1 {/ d7 C- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
. j4 [; |4 G' } - {
2 f6 d) e6 D6 m" q2 }# | - if (huart->Instance == USART1) // 判断是哪个UART触发了中断4 f9 G3 d/ |2 R5 U; G
- {
6 \2 `% [: p; I - // 处理接收到的数据
' R- b+ J6 g) B( q7 b - HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去; z/ M Y* _' ~" {3 C' U
- // 可以再次启动中断接收
( I2 ?; |( f/ F; c6 c: h& ~ - HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));
- B3 H9 q: }4 r! n - }$ `* G2 ?% o2 L/ S7 [3 K% N
- }
复制代码 " 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
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
$ \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 {
- int fputc(int ch, FILE *f) {
0 S0 I. h# l! \& c {2 N - // 发送单个字符
M1 Y+ U' R7 }! Q3 a, w8 M - HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);% ?1 J# b, S U! y0 G a+ z( V+ w! }
- , Q( ^% k7 K; T' S8 X) N c
- // 返回发送的字符: j/ q: \, x2 v( a! o: I
- return ch;
* F4 A9 O3 t1 n9 v& M5 `) ^# j - }
复制代码- while (1), G; J$ t5 b% k7 C1 v6 R) s
- {
% [: s$ M6 N; [& O% O, ~ - /* USER CODE END WHILE */' _3 |8 R% Q: i1 z3 u: F4 w
- printf("Hello\r\n");( E6 l1 y3 F7 u- {4 [: u; {
- /* USER CODE BEGIN 3 */
+ V, n2 C9 C4 i+ L- d& U - }
; r5 \8 y* W0 d- U - /* USER CODE END 3 */
复制代码 $ B/ L5 m! n7 K2 x, V! @' N* e' R
% 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
- while (1)5 O4 C O8 q. x" ~
- {6 `/ ~) b" g; {! d6 L/ j1 u* U
- float t = 0;4 z: E7 }/ _- P
- /* USER CODE END WHILE */
1 ~( Y8 ^0 O* M' b& h - printf("A:%lf\r\n",sin(t));//正弦波
$ m- s/ h# i8 [6 y' F* g - t+=0.01;2 m1 M* U7 q4 d. w( I$ e# |
- /* USER CODE BEGIN 3 */( G: z8 H1 R# e
- }
复制代码
- H8 K7 p- O. a. A7 c/ a
: 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
- while (1)0 X& W0 [+ P4 f" B( w1 U( ~
- {- m) K$ s n; F1 B! B3 Z/ d4 _7 W% H
- static float t = 0;$ b+ i" z7 q/ M5 @; Q
- /* USER CODE END WHILE */ v* H. a; Y/ X
- printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加
% ^9 h9 m7 ^2 y" d+ d& P: L: x - t+=0.01;9 J; |! n8 i6 e/ ^7 q# P3 |
- /* USER CODE BEGIN 3 */
) z4 n* ~9 M, j5 `- F- C - }
复制代码
0 Y* f N" x) x0 a
, 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
- while (1)
7 M/ S R6 {: l0 {- U# W# d' S - {
% N+ x& O) r1 \3 S1 ~5 s8 g - static float t = 0;( n5 q' D' c; h1 ^- l
- /* USER CODE END WHILE */4 F9 I F- k, j! C
- printf("A:%lf\r\n",sin(t)*sin(100*t));4 @2 h* c# {/ _& p& E
- t+=0.001;( e& @6 z8 B- i0 x/ t
- /* USER CODE BEGIN 3 */
0 c% d' J" [6 C - }
复制代码
8 [7 v" m6 d" g0 ]
) 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
|