串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。. Z4 k! R4 d, v3 |/ `4 m' S+ e8 V
本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。
6 n. g) w3 [9 u+ ?+ I$ ~+ a; Y
' N3 ^! K" N' c1 z0 |' B/ t: t
! F! b% w' y) x9 C: y7 y0 h0 b
. X' R" f2 d% V5 o
1 u% s" E& M" F1 g: ~
: c- z: K+ J d, g6 `5 S* Q, {9 ^
9 T# d2 r4 y+ w+ h, p) X首先打开CubeMX,配置时钟树和时钟源。. R/ f+ N8 h2 B5 {, C) _2 ~
) s/ |+ q7 U2 c- p) N1 t
1 N- p. q9 x$ C% N5 m2 T5 I
~8 U0 g: t3 _9 y& u0 @8 u接着配置我们的串口,设置相对应的波特率。) Q" s' b, ^. Z! a& q2 Q% X
5 |6 r- j- L. c) k8 U) {% k
( t. P* Z1 g1 K
8 W$ p( V8 E- E$ G; _
打开串口的中断。
5 r% n( E' M& P: u& ^. X; t, H4 w5 m: [5 N8 u
然后创建工程。1 `9 q7 @5 p3 g
6 {4 w7 b$ R! V, b+ q- z+ z" n
2 X2 F( a0 o" Q4 Q9 C
2 ^3 k, Y! k+ [! i) R
在魔术棒中勾选Use MicroLIB
7 y0 v+ N: B) I$ @4 Z, A- unsigned char ReciveBuffer;
复制代码
' }: h$ D( x/ d2 x8 C6 K1 P9 Y0 G" ~+ z在全局定义一个缓存用以存储中断接收到的数据。9 }& A4 |* e3 Q9 L- S
- HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码
$ E, l6 E, H" [* j初始化的时候需要启动串口中断。
. S; a1 g# c2 K: V- W- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
1 f, z; P1 {) A/ D3 |3 v* { - {
: a- |6 Q9 B0 r! g2 d - if (huart->Instance == USART1) // 判断是哪个UART触发了中断
9 ]; P, b& w" { - {
2 g* g/ G8 v2 C, d - // 处理接收到的数据
8 `! H0 I1 U& f - HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去
* o0 @4 I1 I M4 s5 ~ - // 可以再次启动中断接收( M6 C. \+ E# l0 D5 I
- HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));
9 f1 q$ e3 N) z( r' M+ e - }+ ^/ w+ \3 y6 }/ \
- }
复制代码
7 Q0 o! d/ E' H3 [7 n接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。
/ z1 @- l( I: H' K+ U
& k: r6 k( Z+ Q
% w, {6 B$ f3 k
& C; c' h+ p" _3 Y* u7 L
可以看到,我们发送的数据被原原本本的发送回来了。( n9 k* B4 m5 \7 j
/ ]# N, V! A4 r9 |; V! g串口的重定向- f3 T/ X, `+ V, H
重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。) T# ^6 o( x4 h" f) R
6 G- p) l' H9 Q9 S% O% J+ I
串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?7 l( z/ c! N5 Q3 G, l5 H% R
' m3 b5 \ c+ Q: }* Q: r, F我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。
- Q0 \% u t- y1 T* Q: @/ _
- U9 a. Y* B+ z0 L0 ~" Y5 r通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。* e3 W8 f4 V/ a3 w; A
- int fputc(int ch, FILE *f) {3 i N9 l- J1 x( k( |/ x4 ^
- // 发送单个字符% u' [$ E* I9 x- ~' S4 q8 A
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);( P6 d3 k8 h0 \& i7 s8 v& ]
- , K/ f9 T9 D' l! w
- // 返回发送的字符
4 T( {3 G, T$ n) o) W: T- D - return ch;" C$ d7 o! i) M# [2 ?1 ]+ Q
- }
复制代码- while (1)2 e5 X: }$ z6 a0 k
- {; D- E9 \6 F0 D7 R2 N' G8 O
- /* USER CODE END WHILE */
2 }; e5 u% P! V. M) s - printf("Hello\r\n");. T1 w+ L0 e/ M3 `" f
- /* USER CODE BEGIN 3 */
" M2 P8 r0 @! \# f% c - }4 Q* C$ j& r1 G4 c( p
- /* USER CODE END 3 */
复制代码
5 Y+ L$ k5 |9 K' ~7 D& D4 h9 c
7 t" D. P. D& f- Z) W8 c* w9 G
( Y6 t, i- v+ \5 ~2 X- o3 v2 o
正弦波5 A% F, \' T1 T/ w2 }5 M2 B# k
- while (1)/ ?2 G0 v, n6 j
- {
" B7 \9 F" m {2 y - float t = 0;
7 }% M) f$ C) v! Y0 p$ v/ \ - /* USER CODE END WHILE */
( X% _/ g& E. a; w - printf("A:%lf\r\n",sin(t));//正弦波0 e# r- b& A5 e* F- W( ]0 u
- t+=0.01;- l, m, i) A1 L1 w: U
- /* USER CODE BEGIN 3 */3 }% i1 { v; R+ [5 m0 \! t
- }
复制代码
7 z0 g8 d6 _# T5 x: L7 M
1 U- ]1 V% w/ f6 c: m' X: J3 M" E5 E7 ^! R2 {! |& ~
# L3 U) L6 P! T, {4 c8 ?正弦波相加
, s+ I, W0 u# X9 B- while (1)
6 p6 O5 R' Z/ |: i+ S5 v- I3 T( Y - {
/ u. S# x9 y$ X7 `* _/ u( z - static float t = 0;0 S6 V% C3 a; i) s; r$ I* n: z* B
- /* USER CODE END WHILE */
, k1 i' r' F% k, X/ @8 s& v! o( }' ~ - printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加
j4 {' A. F! Q - t+=0.01;) t, y4 r- @9 d9 ?
- /* USER CODE BEGIN 3 */( u: Q. b7 B8 L7 q: K
- }
复制代码 c+ g. {) b) a, W+ i, \
, m# D2 J( W3 [& U# B/ I+ t9 @, W- L% |/ N
: L' ^ B2 U5 C r
正弦波相乘: i+ G$ O; A1 @2 W; w8 X5 f$ L
- while (1)
* c6 ^5 r( S9 e3 a0 |$ S+ i } W" H - {
$ g- \, I4 x- M1 C4 r - static float t = 0;; P$ T# P/ W! w. E
- /* USER CODE END WHILE */. `0 L3 y, h9 }( d
- printf("A:%lf\r\n",sin(t)*sin(100*t));- y- a; ~% i- @; Q( k q0 @
- t+=0.001;/ Y+ l# K m, k( g2 k( F) _
- /* USER CODE BEGIN 3 */! B* X1 ]- y' x; }/ e* S) T# x0 _
- }
复制代码
' e- R' N" m6 u3 E* [2 O
5 m3 ]) e5 d4 b
( j5 g: B K' J! v& |转载自: 电路小白
: u$ B/ F, \% w) F; o5 T2 i `" X! H" @7 D
如有侵权请联系删除
4 ^7 H- A5 f4 K( u; q! c1 {4 S7 s; T" b2 V6 E1 e/ W
$ ~( b* Z# L: ~( K
0 f# Z0 o W+ Y& D; b# B) b- R
* K1 P! G R: A1 ]- }' W2 q; H \/ C1 s6 t/ p
2 k+ i- m9 l, J% e& Z |