串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。
: {( V6 D) d; k, u& c, E本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。% K* c9 Q5 P9 G: ^3 E
% n+ l* A6 u, u3 C) U* P1 L
/ E9 c, n1 g# [
- k O( @2 _: D- A$ C2 V$ n: t, }$ F* n* h" ?
" }) g9 \! E8 b* R+ x
+ y" H' _; K! S) n, U首先打开CubeMX,配置时钟树和时钟源。
% ~' @( p5 V6 N8 _, }. }+ \: X
5 \7 ?1 W8 t8 v/ r' s" e, u
3 w* n& e. B. S) M/ t- A( g; o" m
- a+ d5 x& r9 Y1 i" ^" H接着配置我们的串口,设置相对应的波特率。2 l6 _ H9 g5 F, B0 W8 ^7 `4 C
4 W- m. \5 g" S, M: ~
$ I9 \5 X C9 u* t
7 l+ O4 E8 v( N3 N
打开串口的中断。- L) Z5 W3 ?, q& ~* B* b
5 n" u& H; m2 ^3 o( ]然后创建工程。
2 C# a( F d/ P4 q& _# u7 H7 O# ?& d9 W- r
, H! K* d+ a1 [
+ @* e4 U! F$ ~在魔术棒中勾选Use MicroLIB4 M. F' W' z# p; z% ]
- unsigned char ReciveBuffer;
复制代码 $ X' J2 t: l4 a6 D" Q; Q
在全局定义一个缓存用以存储中断接收到的数据。6 `+ ~! H7 u v% c. Q: i2 V' q
- HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码 " Z2 p: I4 z( ~2 g0 Y a2 P2 |3 Y
初始化的时候需要启动串口中断。- \% B5 v' G; }; @3 a6 O
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
- K6 N: d' L. B - {
* |" M+ }( K1 M - if (huart->Instance == USART1) // 判断是哪个UART触发了中断
% g# i: r2 E. s3 t& f3 U4 C - {8 d6 ?+ V% }5 ?2 I1 p6 E* y
- // 处理接收到的数据
; H7 x; i+ M8 o7 j! I9 g! U - HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去: z: Y3 ?/ i( E& D# P0 b6 S3 l
- // 可以再次启动中断接收. {/ N5 F$ X. H3 i$ W3 V
- HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));
% J$ ]( W2 x' a* p0 b$ _ - }% [/ A! u8 C6 p" I; |6 Z9 c* f- u E
- }
复制代码 ) S" f4 m! [8 I' W% p
接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。% \0 W9 B! M p
& {& a' J, K0 I' C* r
6 L1 X# }/ g% r# i( t
' w* F& o+ j0 Y+ r
可以看到,我们发送的数据被原原本本的发送回来了。0 p: e; o$ Y8 O
4 h, G: X; D F4 Z串口的重定向
E" @9 n, {- `9 c重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。, R6 a% k+ `( _' G0 f8 G5 T0 U
+ V; L) d9 B! V: r0 }$ E) I
串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?. [( F' [5 r) s5 T' x( G* f' d
1 p- l' t8 P' ]. Q* [+ S我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。
% k. a. F& Z/ E# ~, B y1 p; q
1 U# g) x; O- y" p2 U! U通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。
) S* p* ]! N$ a- int fputc(int ch, FILE *f) {) E2 s6 f" `6 r4 u4 u; C5 t
- // 发送单个字符3 K5 u2 b3 w7 d
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
' M4 m5 |; o1 e \ e -
$ j+ i3 f' I# |, f3 x7 O - // 返回发送的字符
3 z' S6 T# u; z - return ch;
: s ^2 S9 _2 P2 m, P0 e - }
复制代码- while (1)# c* d0 b6 @. g) }. { v
- {
6 w+ |* [: U7 w3 ^) @9 J. Y% ? - /* USER CODE END WHILE */
- l5 M6 G+ M# p6 R - printf("Hello\r\n");* P; C3 f+ A8 h. y, F! r
- /* USER CODE BEGIN 3 */1 R5 t' k1 Z: q
- } g4 I) v; u% w0 a" C8 G
- /* USER CODE END 3 */
复制代码
) o6 R, g5 z, |: w2 Q
4 l; e% U, T+ B8 b
3 U3 \8 l4 D+ I7 K' z
+ K' |/ ]& O" q9 B正弦波; F" F9 e; C: W. A( m. m1 a$ M
- while (1)
( ~: e: ]4 f. `! W - {& n: D7 R7 N. v* U7 P( ^
- float t = 0;0 N$ O/ |: F; U( C3 F
- /* USER CODE END WHILE */
4 _" Z x1 `/ o4 r' v3 I - printf("A:%lf\r\n",sin(t));//正弦波4 C6 @+ h3 U/ z7 {" E
- t+=0.01;
* V* j* ^" z6 e. `- @ - /* USER CODE BEGIN 3 */
2 k* g% Y* d+ H. H - }
复制代码
7 s+ I; N" A* C
1 \1 K3 p& l6 E7 }2 u: b& i& j4 X1 P# S) V
0 k* Y a/ C" N! y/ d' m: ^& Y正弦波相加
# B; L) H3 B8 K7 i' T# p% b9 E- while (1)
9 C, ^& T. o# j6 z' {' N8 u$ z - {
1 F, r$ R+ N7 b2 `5 M, V' d - static float t = 0;
# E9 A* Q+ s3 G- x* p8 b - /* USER CODE END WHILE */
2 J6 R1 V( p+ }2 Q. Y/ N - printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加
; R) p' Z4 L) ^4 G9 N - t+=0.01;8 q' w4 ?- B& W
- /* USER CODE BEGIN 3 */
& g: `8 y9 T- f# z2 A - }
复制代码 - ~- I9 a( H% q4 w( s, b
( S' R+ _+ U& P" x
8 n& ?# A6 }$ {1 ?/ w& ?3 Z8 N- B: r+ E7 q+ i
正弦波相乘) W- |0 ]: R8 M% c& b/ |
- while (1)
' Z" X$ ~2 W$ G0 m* ?/ `, d - {. F5 N, y/ U+ z
- static float t = 0;& B5 M6 o# N7 M/ I! k
- /* USER CODE END WHILE */
+ U/ V6 \6 q6 `! f7 K - printf("A:%lf\r\n",sin(t)*sin(100*t));; e0 _0 N* _( Q0 Z4 _, u/ U
- t+=0.001;
9 z A. X! {9 }: |' w: `4 B - /* USER CODE BEGIN 3 */
, @ k2 [% O* S( p" P - }
复制代码 1 g& _8 ~6 A( c( t& t# b' M4 T8 [+ k
9 P2 F! F" S! s% J4 u: {1 V( t( u/ R9 b
转载自: 电路小白3 t/ a" @% b) D {0 h
. L/ p m2 G; O- {: J如有侵权请联系删除4 S5 b! i" P$ f
+ E) {1 X' ]2 |+ B0 A( J# J
4 @4 }+ E$ T# W
5 v" N! L& k$ h& z
# j1 n8 m3 G# D9 M( ^7 ?7 S2 l0 E6 m/ J6 _: g2 G
6 p* M% c6 c; P2 _/ n7 ~ |