串口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
5 S; h3 B; I, E m/ k
. C' |) l3 P( U5 U3 S; h a5 E% [9 c6 E/ P- I
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
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
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
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
- unsigned char ReciveBuffer;
复制代码 7 }% Z7 I0 Y- G4 R y/ M
在全局定义一个缓存用以存储中断接收到的数据。
6 I7 b& }( [7 m2 p0 A( C- HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码
3 h8 k1 b. R4 `初始化的时候需要启动串口中断。
) ^4 I/ j+ ~( `9 d2 {- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)( E1 W9 s3 {. ?% a _
- {- q, T Z6 M7 V, i
- if (huart->Instance == USART1) // 判断是哪个UART触发了中断
7 E/ K& p) a9 Z; A; M+ Z9 S \% m8 n - {
' o( Z2 C0 N/ x4 O/ F' C8 W - // 处理接收到的数据0 M% a/ y# \) c3 b) q. {( ]& X
- HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去
% Y0 o: m9 n# v( \ - // 可以再次启动中断接收! L) |9 i6 T! E0 q7 o0 x7 [
- HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));
; U! ~- @ x3 u% ^. y; X4 E - }
- X, V/ O$ s5 x& q0 i+ _6 L$ R+ l - }
复制代码 + 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
* [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
# 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
- int fputc(int ch, FILE *f) {1 p, M" u5 S4 [* P5 l% W
- // 发送单个字符2 ~5 i) r1 v$ o
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
5 D6 g4 G# f% J; O - ; C) H5 Y3 E; r& V! @
- // 返回发送的字符
- O) q8 @& d8 h- M" g5 n& j0 r1 r - return ch;
( |0 z$ P$ T8 b$ D3 C. C" r9 o+ ` D - }
复制代码- while (1)9 l# i# Z- D- ~7 | W* Q
- {' j, i8 Y9 w! w3 a
- /* USER CODE END WHILE */
5 b$ V, C& m. v- w. I) k7 z) W6 L - printf("Hello\r\n");
: `* e1 m+ |0 `1 ^ - /* USER CODE BEGIN 3 */ W) Y8 W2 d' `. P
- }
' o; i* Q) \1 ?; W0 M2 Y - /* USER CODE END 3 */
复制代码
; m3 y# i$ l$ ~& |- a# _: g; Y7 _
; [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
- while (1)
5 R* _; W7 l, G; q; h/ \# h( t3 i. a - {1 @% x; R# ]: W3 G% S
- float t = 0;
: _& }- V+ q: x+ b6 ~3 G4 Y - /* USER CODE END WHILE */
! ^4 l8 h% H" v3 i - printf("A:%lf\r\n",sin(t));//正弦波$ ]* l/ S1 a$ x
- t+=0.01;
% _& U2 F- F5 y2 L# C - /* USER CODE BEGIN 3 */
1 \8 s# ]% y' v - }
复制代码
" ?7 g- G3 g) f
2 t5 ~7 X& C' X @/ r' L4 f. G. Y5 q4 F! I
. n; ]" Q0 E7 B
正弦波相加
! i! k, h! I1 _/ `1 @# g- while (1)$ y+ L. P: R# |7 q" X! ?8 d. N Q
- { q3 ], q) I2 g( c1 Z% _
- static float t = 0;& |% F f/ A: D( y
- /* USER CODE END WHILE */% N* a8 V! Z% c) @$ Q* k5 H- i
- printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加% t5 g" }9 ]$ S+ {, v
- t+=0.01;
( Z- ~' u$ i" c - /* USER CODE BEGIN 3 */
/ N9 U& `$ R% @ - }
复制代码
& f% j: s* J4 S. c C+ U. x
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- while (1), C. X; {9 j' ?% [0 y/ g# O0 c
- {
* K- G+ H7 `5 _2 y: r0 B - static float t = 0;
3 o) P& u. B) |3 o0 E - /* USER CODE END WHILE */
/ S, n) n: ~' W" K9 ~; q* q) J - printf("A:%lf\r\n",sin(t)*sin(100*t));
2 H7 |; @' n- A# P - t+=0.001;
" s* `' O9 l3 Q+ G2 c - /* USER CODE BEGIN 3 */
4 L8 p* p2 c/ j7 x, P3 w+ B1 X* D - }
复制代码 1 y( n# M5 x# v0 s4 {1 _7 `
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
|