串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。! U c% I% g5 a0 L7 W
本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。
5 l/ K, L! P* y$ X
+ w- \3 v1 e& X, g
- [8 q) S! f& {& j9 Q( `5 z* Z
* n; F5 G% _: d" m u, N. _) F9 O" x
5 d7 a6 {8 R8 I" r+ D
& J5 s5 O+ B% l& W& b& l* C3 e首先打开CubeMX,配置时钟树和时钟源。( ]' B/ @0 O- k
3 j4 B! T; n* @6 O- n
4 E) a8 G+ T, L1 {0 P: O9 N+ s8 a$ i' @& ]* h, e' \' ~
接着配置我们的串口,设置相对应的波特率。
9 S, [5 a0 a$ m; H: S: |/ k; Y* T; U l
7 E* E8 S# c8 n: S- z1 e* l' i
0 \3 p" P2 b* l' z打开串口的中断。
: r9 m' ]: }6 M w/ _' w. d6 b; C' P5 [7 l& F3 ^! f: @
然后创建工程。- k& V3 C, `; o R7 {
+ v, Q' s2 ?) Q D# O
# O q" m* |' W1 b8 Z3 b6 w$ k r' }# h |$ f
在魔术棒中勾选Use MicroLIB& ]) Y2 m4 Y, v
- unsigned char ReciveBuffer;
复制代码
9 l. `* m# k! u4 T T在全局定义一个缓存用以存储中断接收到的数据。+ w% k& ?' E' G5 ~% j# V
- HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码
2 ^0 u! @5 ]. w初始化的时候需要启动串口中断。8 a2 n$ }- W- E1 X& s o1 c% D
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
8 n6 ^/ V8 S% x2 d - {+ G% M# I9 U) j. ^# j
- if (huart->Instance == USART1) // 判断是哪个UART触发了中断
& b8 \" k; T7 L - {7 o# k/ E$ h% U+ A& }
- // 处理接收到的数据
( B2 [1 C0 c& t* |( |- b% K, N: b - HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去
6 i0 D+ n$ z1 R: j# O - // 可以再次启动中断接收+ Z! l4 s! p2 S" K8 e. P4 i
- HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));7 }6 }" _8 p3 M0 H1 ]8 f# d6 D) D
- }9 O8 i7 [* u1 H2 V* M* Y
- }
复制代码
+ P8 B. _* D2 L( u! I: R接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。
: z5 q9 Z/ S# }) i* l: }
, y5 x* V/ p) M7 @5 m+ P' t
2 n1 Y% S5 N& Q8 d
$ m: N) q4 v/ j) c3 b可以看到,我们发送的数据被原原本本的发送回来了。! n9 m& `& Y' e- y
% a, w0 j- s- l/ `3 L* s2 b& n串口的重定向, _1 }/ U) C( @! m" c, r
重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。! D" X" [4 g- ]+ R7 Q' N5 e4 I
) F! I5 ?( `# r4 Q* I串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?
# Z0 W- C4 V$ c+ t
8 r5 y2 ?% S" i/ ]我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。
3 o. o8 _) y7 V6 m+ j( q) J. ~4 k1 l4 |3 u7 A3 f
通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。
# E: \+ w3 E# |7 d: O7 r8 R' H- int fputc(int ch, FILE *f) {- L7 c6 a/ @+ I
- // 发送单个字符
8 _5 j+ B1 ?8 H* Q" d* b - HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
- l0 G2 j; r. t/ F( J" l9 w$ G - 4 n" F1 X3 F/ S q
- // 返回发送的字符
$ I: l3 g, u3 |4 V: ]9 C2 l - return ch;0 p, s% L: v7 g# M% `5 ~' _
- }
复制代码- while (1)
* W) W0 j* ?( g% `2 L! p* ` - {
4 j! ^- Y& i5 p$ a6 {$ V2 u - /* USER CODE END WHILE */: @7 l# {- o+ K$ F/ h
- printf("Hello\r\n");# m: Q9 i; p/ j0 v
- /* USER CODE BEGIN 3 *// m% A( f, n' m2 V
- }' O f g$ g) O' W
- /* USER CODE END 3 */
复制代码
1 [" H1 { X5 N
$ O7 `3 B5 R! i5 m# z& n; M, S5 [
, R+ G* W3 }7 I0 @% j- _! _
正弦波6 u) {2 y1 T/ a: w8 J8 a1 J- n
- while (1)
: R# N; n; U( l5 r- Y - {0 K9 [+ f9 N1 Z( \& c. p/ e
- float t = 0;
5 I% L9 J9 u7 f+ b U, @+ v! ~( | - /* USER CODE END WHILE */
+ ]- k6 U% L9 v U - printf("A:%lf\r\n",sin(t));//正弦波" _' }* P3 B& d8 e9 k
- t+=0.01;+ T- @5 N0 ^! Y/ ?* J
- /* USER CODE BEGIN 3 */
" q4 m$ u5 I2 B" s' B - }
复制代码
- ^, \5 S; g: ~/ w- I
. `/ a2 n( d; J# S# W5 x% Y, I$ c+ w: F0 g2 x8 ^
" i; v7 z8 M$ j }6 O正弦波相加
/ z ~1 q8 C+ v2 S/ \- while (1)) a2 c5 G& ?# q$ f9 q1 I3 v, U' u8 D
- {
6 U" u4 u% l. f# y8 W X2 |; \5 e - static float t = 0;
9 ^% H7 f# p$ v1 @- j - /* USER CODE END WHILE */; D1 D) E6 D; w! b' Z
- printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加3 t/ e% [, J. J3 S8 J0 ?
- t+=0.01;0 ]! X7 N% t) x- _
- /* USER CODE BEGIN 3 */
n, l: x% K# m3 K- N - }
复制代码 - j1 K' C3 F2 u
! g6 [; W9 h7 k5 A0 v! Y, w2 M6 t) X& j* I0 a) D; ?+ g
7 N) J' w7 z4 H2 U
正弦波相乘
; h Z. i' C5 k( q- V; n- while (1)8 O8 O) X: U# J4 @
- {/ C s+ h& \1 T
- static float t = 0;
/ n' X* o$ {2 f6 h - /* USER CODE END WHILE */. J5 b' k! h6 L. ^
- printf("A:%lf\r\n",sin(t)*sin(100*t));9 q; x$ B7 V, S9 \
- t+=0.001;) ~) L# V3 c& X# G5 O9 Q- f
- /* USER CODE BEGIN 3 */
& E: C- K6 r, |0 D - }
复制代码 ) N- M: h W7 w! n# C5 z
! c: d' B( T; g$ a2 _
8 W% C4 D) {" f0 M转载自: 电路小白
6 v: f" |) K* e0 {9 _5 G a7 [# I4 b3 x$ L: [% k9 }
如有侵权请联系删除0 ~7 g+ P: P6 ^6 i2 K* X0 ~( I
% b& G# q0 P$ F- B e0 [9 C9 e# Q$ B* E( B+ }) j8 i: E. m: Q' `
m- ]. [" `' C8 t" _7 M; m* \0 s# }+ ?, g( B& s9 o# g M
1 d5 K H1 j8 w; T: h% {/ a. a* Q2 V/ Q. W# k* _
|