串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。& Z" N0 c6 t* w1 ^7 S
本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。
, M5 F# o* v7 H6 X/ Z; T/ P' K* X3 y: P) T" c7 M1 |
* f4 y# U0 c. W( z5 i
" W/ f1 A r; N0 Y
0 Z h, D( L J+ ?% p' O
6 w0 ^5 W% d8 l. k8 B: ^6 B% b. r. @! K3 m
首先打开CubeMX,配置时钟树和时钟源。/ N' P; O3 x' n& U* N" w# a
! z. ~& a, Z& j! R. Q Z
" c, B" q. h6 ?5 n8 ?5 t: g
7 ~8 b& c. e+ ~0 J: v接着配置我们的串口,设置相对应的波特率。4 a* M& f7 u* z* N" A
8 [) o5 m, X4 _$ D G4 m% {0 L
2 B5 m( L! d3 c. q) ^ k% g6 F
o, E. l8 T0 b/ z3 \打开串口的中断。
6 A& x( _* C4 D- K' m
7 Y4 Q% J. s4 O' W9 v& E然后创建工程。* m, g0 x a, {/ ^! k5 b
- c, |% t3 t5 Y4 T
1 y# N T* L1 _% N6 d8 e2 l/ q: X8 W
' j1 I. F/ A! m }8 m" T在魔术棒中勾选Use MicroLIB: l; ]6 O: x% [( D0 u6 Y4 l
- unsigned char ReciveBuffer;
复制代码
5 N9 h5 Q$ R3 P) T在全局定义一个缓存用以存储中断接收到的数据。 Q; L3 T2 ?5 \
- HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码
: \8 q9 I8 T: B9 n初始化的时候需要启动串口中断。2 `, J9 G* |$ D
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
2 {4 }+ u. N$ d - {8 m' E8 f+ p4 _7 L
- if (huart->Instance == USART1) // 判断是哪个UART触发了中断+ R$ w; |; V5 g) [
- {- T4 A: q; ~ n! G* Y6 G
- // 处理接收到的数据
) s( k$ f( d$ }; X( E L/ d! |0 y - HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去
3 n" V+ B+ ?3 P/ @; g3 m - // 可以再次启动中断接收5 d1 i/ b* @$ K
- HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));
* N, r) r' v$ H) } - }( m0 B8 ~/ v9 H
- }
复制代码
5 ^$ l) {/ z. x8 @接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。6 {# M2 G6 |( ~- ?* a5 H
! O3 `: V9 h' @/ s
3 ~0 q( U: H, Y
9 d8 _0 t# O& [1 r可以看到,我们发送的数据被原原本本的发送回来了。6 S1 }$ C; Y" o
, g8 ?1 p) q3 I" Q串口的重定向
: R9 R$ q7 x5 ^5 s2 X1 u. }- ~重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。
+ a% M5 w" `! [# `. O2 Q" L( z& p
0 A: X+ ^1 q$ G- u串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?
9 O( j! `% M$ G4 R, F( O: q' Y/ M6 u% m: ^. q/ K2 ?* E$ E& n* P7 C/ S
我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。
3 H: v+ g& C9 ?8 V1 N9 l5 W- W' `& ]* f2 ]9 J
通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。* y( n; H3 n6 i2 v) e1 X
- int fputc(int ch, FILE *f) {$ P7 c* h& Z' h! m5 E% Z
- // 发送单个字符
1 o) \- |# X* l4 e( ^! d& X - HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); F4 k6 o R+ C1 N
- ; P8 }, |& y4 |0 }8 m/ ~
- // 返回发送的字符
$ ]" T4 Z2 A/ H3 |" l - return ch;
, `) N3 R+ Q: y3 j) s" z, E - }
复制代码- while (1)9 r9 _1 h7 @4 {& Z8 Y
- {& [( Q" b# a3 s7 T; u `
- /* USER CODE END WHILE */
8 H7 W" r* d; K% s - printf("Hello\r\n");1 ?( B1 [7 k! R% O* x- V
- /* USER CODE BEGIN 3 */7 M; j6 Z! I6 P) u" J
- }; _6 c" L- W/ E6 z3 F
- /* USER CODE END 3 */
复制代码 , n+ B% Y, y. L
5 Y& U, E s+ K! Y8 S1 @% G0 c: }
1 e( P! F- V; l% E" g) R7 X+ g- O* F1 b9 L7 ~
正弦波
; N0 f& z. d$ c& A+ K- while (1), i k4 p5 P+ @; {
- {
8 W+ D2 a& W/ f4 | - float t = 0;
6 X- S+ }/ E( \) B7 u7 t - /* USER CODE END WHILE */" w0 ]8 H8 T* w* a) l. P7 p
- printf("A:%lf\r\n",sin(t));//正弦波
( b& S2 T: S% Y" ~9 E4 P: S% g - t+=0.01;
) y/ Z: L( F. l* X% ] - /* USER CODE BEGIN 3 */
( u4 C( l( f1 n0 A) J - }
复制代码 5 t& a7 d# _: z
; A! K; `" c. B! h2 b( r
* m3 s6 v* ~: Y4 f3 r; i {
8 H9 }. c& @: D正弦波相加 u- i0 J9 G: G2 n5 R" A, W: w$ q! f( L
- while (1); \1 P, ]. |% O' z, ?/ {' u0 h d8 J
- {4 S8 T1 W9 b K* v$ D1 V
- static float t = 0;
# a. h3 R) v' k! t; M - /* USER CODE END WHILE */
$ L' l: }: b1 o" w# p4 u* G, A- P- P - printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加
0 ]. A& h: x5 m# n - t+=0.01;: W7 n5 w# K$ H9 B1 `- s! b
- /* USER CODE BEGIN 3 *// f( S# ^! X, C! H; {5 W9 A( q
- }
复制代码
1 h- h5 X' l# f1 u4 v
, `* a6 E. @3 f/ ^8 l9 t! M
# |, h& E$ y' T- m
5 O) h i: G7 P/ k) i正弦波相乘! m# A' i/ c2 C' r5 Q* H) J" k5 e" E
- while (1)4 Z" D" c" H7 G* q( K
- {
( d. J, K9 s* t) k$ R - static float t = 0;0 E5 }! b0 `/ ? R
- /* USER CODE END WHILE */+ s. [4 V- H8 V9 c: L$ C* m W
- printf("A:%lf\r\n",sin(t)*sin(100*t));. K* E4 a4 o# t# R* _3 u8 v
- t+=0.001;, ~3 \7 f K: X# f1 W
- /* USER CODE BEGIN 3 */
0 U& c# U) P. {& c- i- ? - }
复制代码
& c: p4 s8 q' I# g1 M
5 e f7 N- I7 |- C& O/ H$ O7 T C$ i0 b7 ]) _' T* v( f2 r
转载自: 电路小白5 l5 @3 d7 G5 x( w
2 r$ L. ]+ R( @; B4 L
如有侵权请联系删除
) \( W9 r7 V9 T
k0 ^2 s6 d8 W& e5 y
2 G! ]7 ^& K4 `7 c r* k$ h% D9 Q& l
) K1 d) Z X; x# u# q- X; p' @
1 |* [7 [' [ X) _2 }( S4 G
: p C+ G6 O% Z' k& x w q |