串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。
( U7 [# i: Z% T6 ?本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。+ E+ p8 k, c0 g4 b- E
@" U9 E0 v9 ^# k( U
$ _2 M8 W/ G8 c& |1 f: _+ r
g* v/ f, P" D
7 F4 r4 c. T$ N1 e0 T2 x
. i. O: k" ^! C9 ^( f
1 g* `' U) ?' g `首先打开CubeMX,配置时钟树和时钟源。
( e9 k# `0 N; j, |
1 e0 d+ _/ ]6 L# i3 |5 |7 t
6 M6 s% g9 I1 }5 D- L# w( P
4 S* K/ l* g' d接着配置我们的串口,设置相对应的波特率。
. ~. Y! j" i5 z O" ~7 f7 {" U% q: Z+ h
2 L9 k: ^, \. ^& L6 [
8 {( R' s2 q/ i4 |, x, [$ Q打开串口的中断。
. G( _% v( l K9 H* J4 j% f" n8 v2 y8 q A5 L$ C
然后创建工程。
7 J& z( E9 e+ n; a* s# K k
) `9 ~0 g$ Q2 P4 Y3 A
3 n0 i% |- T$ e$ v* p: m
: e4 g8 b) z; v3 x在魔术棒中勾选Use MicroLIB# ]: ~8 A3 e$ E1 O
- unsigned char ReciveBuffer;
复制代码 " C4 H9 H) U3 I: x6 }
在全局定义一个缓存用以存储中断接收到的数据。8 o4 a$ A& w' n+ L6 \
- HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码
, U( t1 G4 w" F0 [* p* t: G初始化的时候需要启动串口中断。
% D* T. L8 B0 |5 `3 j9 A$ a- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
; R$ k, \. I4 b- w - {
3 o3 a0 Q4 a" g - if (huart->Instance == USART1) // 判断是哪个UART触发了中断$ u) E0 s, J8 |6 I5 T; D3 ?' n
- {6 A1 \4 s! F( t7 o! |, A0 K8 |
- // 处理接收到的数据
' \8 f8 [) B3 f0 x) U - HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去
4 \& Q- a4 @ n6 i% ~$ v* y! ? - // 可以再次启动中断接收
: B6 j1 f2 y7 z# m0 l7 r - HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));' q1 P0 K" a8 S) P ^
- }
: W! B, r8 U+ J7 g; T - }
复制代码
7 a+ f; K: I0 i# G7 W* {6 a接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。% O" p. z9 k' \4 V2 `
1 g' v+ @. i. s5 s$ z) K* w
, I H) |2 D% w0 ?; F* g; }( r/ ~2 B
) u/ z$ {" X6 o- Z6 s% G6 R可以看到,我们发送的数据被原原本本的发送回来了。# o R: N! u8 @* h6 x
+ N9 M/ ]8 e" m. w9 `
串口的重定向
, v% Z5 S. o* U% i- ~) S0 o) V重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。
1 N/ _2 L7 ^9 }% e1 ?& |
' t' m) C9 j+ e! _. v2 v$ c. v5 K串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?2 u! E, F9 I+ }
& \6 H/ w5 U9 j) ]
我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。' X8 @+ ?: R2 u+ C; J
( g" m# o9 ~9 n4 i通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。+ p8 S$ C4 }$ `2 C/ M' T
- int fputc(int ch, FILE *f) {
& H- P' H9 ^: w# q9 p- [ - // 发送单个字符
3 ~8 z( L: j2 T5 {. f2 _2 u' `' N& } - HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);& D ?+ q2 V# N0 K b7 Z( ^
-
, {" s/ U# \) F! ?2 k - // 返回发送的字符
) ?: L, q3 i" C - return ch;
/ ^0 ^: @9 J0 J0 T" t6 T! W - }
复制代码- while (1)+ M/ h9 O( G2 _+ ]/ r3 y1 w
- {
* R, s% w: E* [) m: i - /* USER CODE END WHILE */0 ^3 a; B n1 ^4 H$ n! ^! B
- printf("Hello\r\n");/ Y3 j0 O' h* @
- /* USER CODE BEGIN 3 */
: \1 u4 H- f/ T' `5 j! R3 B8 G - }' ^8 r+ A9 I3 x+ a- i4 |
- /* USER CODE END 3 */
复制代码
b& W/ X: w4 v
8 A+ R( t( h L4 g
$ K2 ] H4 i, p. I
4 n6 N1 r+ ^3 i. V. @8 l1 {正弦波
% y+ M4 N; E i- while (1)3 K5 ?1 X0 V* W! C
- {/ Q( _, R$ \% t% J- u" E
- float t = 0;) [7 {0 z! _7 d! w3 x, F& T' w9 F" s
- /* USER CODE END WHILE */
( o6 Q# l4 C5 i. j/ D - printf("A:%lf\r\n",sin(t));//正弦波
+ W$ F& O* Z+ i% |( Q - t+=0.01;2 _ j. Y H s h
- /* USER CODE BEGIN 3 */8 a& ]) g4 f6 P
- }
复制代码 9 b1 J- h$ Q- X* s9 z% d" z& x, Z
; g. h1 m( c+ n3 |3 l; ?
: t m% |& H9 {# N( f4 U( p1 v) Q
0 S* ^9 c& @3 a' N' |" S正弦波相加2 d( U' X% `/ S
- while (1) }0 W u9 K' W; O
- {
+ Q$ ]) ]7 R) g6 m \6 f - static float t = 0;1 O" E. X# b2 J7 Y- t
- /* USER CODE END WHILE */& `$ r6 {: x+ k- p7 O5 J+ ^6 m* J% T
- printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加
2 T7 E1 W9 T- c - t+=0.01;% [; i( F! X- I) q
- /* USER CODE BEGIN 3 */
" F. S! s# T1 @1 N: V8 s - }
复制代码
) w" x, n( u4 w* y
0 c5 j( R! [9 Q( _% V0 U' ]
0 D" N- \" z5 C8 b( Y6 Z' Q. Y9 h- Z. T8 W9 `. W
正弦波相乘5 }' Y5 U7 Q4 F8 f3 C% t* F
- while (1); C( i( {/ f( f' Y3 h3 M( t! |
- {& J2 Z6 ]8 H4 \( L4 A
- static float t = 0;
4 L+ O& a5 }8 w$ w9 C - /* USER CODE END WHILE *// k1 T7 {0 d, j- [7 D( \1 q- U
- printf("A:%lf\r\n",sin(t)*sin(100*t));* G; d# h" A' l+ T$ K: C; u
- t+=0.001;
6 |6 K. k$ U' o5 R - /* USER CODE BEGIN 3 *// l8 {$ Y& j% x" H5 \: b9 U
- }
复制代码
, \2 e! E- O/ ?' @! T
$ }5 J9 F c" J k# }$ H, ]
: |" X. s9 c+ `/ q
转载自: 电路小白
8 Z. p! `1 p( h$ \6 n
$ r! y6 N6 `; X# S如有侵权请联系删除
p7 P* F8 l$ C. c
* E' T( n2 `# ?; g" l( ^6 A% H! b' Z+ o2 G
8 p1 d( v' G1 S' r8 a5 c% E: m) K4 D
+ |, A$ t6 g; O4 o) [+ m# B$ i6 s9 r- T# U
# n7 V3 A* [3 z4 s% `
|