串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。8 M. L" [ P- v% l' D: g, c
本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。1 ?" b/ }) W; \" u
# K, t! h6 v& ?/ g
4 B$ A {/ c& M( r* M8 Y6 v! c: b- w& a# _# L; A( d# Z! y
! G" A& e3 ]! f. C& N
- v8 ]* H3 n1 i; \' l6 Z- Q( ]- Z/ {, b% d3 H
首先打开CubeMX,配置时钟树和时钟源。
* O$ K; ]; C \" J% k3 f) ^* x0 ~6 P1 e" w" i
* D4 |& Y/ a8 E# e' K2 K, q
( c5 I' ^# w6 b) u, I9 J接着配置我们的串口,设置相对应的波特率。0 {6 b% V7 a; d$ p3 I) e7 s" K6 @% \
) z6 z4 Z6 f8 E3 _" b m
/ q8 t) ~5 V# ]
) q* Q& p; Q3 c1 \打开串口的中断。
+ B9 ~( W8 ~! f1 K2 a8 f1 Z' ?8 |4 J
n2 f) I7 E3 J然后创建工程。
+ Y$ D6 i- |1 |; M+ e0 F9 t( k' W% r! d/ _, E& b; }* u( E' L
( @, F$ y c1 L8 {
2 M9 f# Y3 Q o在魔术棒中勾选Use MicroLIB
, W- x/ ^5 Z0 k7 |- unsigned char ReciveBuffer;
复制代码
! O* h/ P7 P) r4 ]( Z7 U在全局定义一个缓存用以存储中断接收到的数据。
" m8 Y0 b( E6 Q! K- d' n! n) |& ^- HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码
! H7 m1 {; Y! |9 {初始化的时候需要启动串口中断。
# v& T! _. H. @2 _* R- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)# {& k8 [ F: p7 P, h" }
- {
6 Z$ T# w, D7 B# {- ?. q - if (huart->Instance == USART1) // 判断是哪个UART触发了中断
: [. T" t/ s" G, M5 ]- | - {- d: f: A h2 s) ] S U
- // 处理接收到的数据3 k0 r. S, `) U P5 @
- HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去 G7 e8 E* w3 o' s8 k- S/ v
- // 可以再次启动中断接收
& C6 M9 e9 |" ?; h - HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));
6 N% ^1 H, c0 O" U7 W& W - }
/ d% Q' G# j/ \( z: w, n0 i - }
复制代码
5 d2 Z. O8 b- a2 g接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。0 X2 O' _$ X1 P% k0 D$ f
) B" I3 l) q1 I( I: W
+ {0 n* @0 d( L6 }* [ L1 b! P: K' b/ G6 X4 ~ |" ^4 U
可以看到,我们发送的数据被原原本本的发送回来了。
; r8 B) |; f% V# P3 W
7 s) q3 t+ E2 `- B( {串口的重定向" g) p/ F" t" r4 Z+ X$ E
重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。
6 q4 m8 s7 A$ G; C/ {0 `
, ^! K6 A* G6 y* |% ] Z+ K) s! E串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?( [: s/ I7 K* B% f5 E+ O
! k1 R; F9 @9 _4 V. T+ M! Q我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。' F; y6 A/ z: j9 k) L: Z1 c
3 }6 ]+ X0 i2 I' K- a! R/ B; @
通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。
% |' {* Z! Y' ?- _; g' [, I- int fputc(int ch, FILE *f) {, U. K# z. _4 r9 e( y! J
- // 发送单个字符4 r4 U) `& G2 T
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
1 E+ R% U% {( O) s$ g% t: O1 G; Y3 q. w - ( u/ _: m7 w6 X3 ~% x* {
- // 返回发送的字符
) l: c& @' {+ I: @ K9 B7 E/ H6 g - return ch;
: ?1 Z' o3 e' I3 H - }
复制代码- while (1); T0 Y6 \ e5 @0 {: f+ u4 ^3 n
- {
" k: l. ~( M8 L - /* USER CODE END WHILE */
: ?6 p; v' N T1 i/ V2 M" a - printf("Hello\r\n");2 ?* M) V1 C! ^+ W1 S j
- /* USER CODE BEGIN 3 */
, b9 N6 m+ R% i$ H - }& Q, z. F8 ~ u+ p; C' X3 d% f
- /* USER CODE END 3 */
复制代码
X. k& h8 H- ~
* q5 J+ r& y1 S; q" Y! m
$ t% L# X0 G3 F ~3 ~0 @# s8 H1 {5 `7 ]- v8 O; h
正弦波
% q% E( z, y& M" a2 {- u- while (1)* p6 n8 {1 j0 T* L8 k
- {6 W' o, _2 ^9 K! \
- float t = 0;* \' s+ F* W+ j. B1 x. r
- /* USER CODE END WHILE */, K+ U) l- T* u; `0 F( C) q
- printf("A:%lf\r\n",sin(t));//正弦波
" D, z, d3 i7 H+ _ - t+=0.01;$ i0 ] v1 L2 O5 t
- /* USER CODE BEGIN 3 */, `8 K( f* m$ ?1 @
- }
复制代码 " n/ Q5 d4 O) }$ s- F7 `
% Y# {6 e" [* t/ {& ~; h+ _
( P8 O+ A7 v# q6 c2 {+ l) z
6 h$ Q) Y/ ?- B2 K; W4 F$ e3 ?7 j# [& A正弦波相加; S5 t) D8 H0 o8 }7 O5 n
- while (1)
5 P. ^# A1 }7 }' c - {
) _8 [/ P, r0 o. z# r" R; g - static float t = 0;
! \% U) r6 y4 q' n0 s6 | - /* USER CODE END WHILE */. c' O" u5 w3 g; F; |
- printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加+ m Q; N: Y9 O. \9 y
- t+=0.01;- z: b6 n0 T( P5 i' L
- /* USER CODE BEGIN 3 */# n/ l6 @6 {7 W6 R, F
- }
复制代码
Q& [) l9 G, Y' |6 s# I. t
8 N/ C, k- P& J; M/ y
, `1 q% u/ p" F1 e) M+ P3 g5 S- ^
% A! F# o$ l- a: d! H正弦波相乘, o- e; o) I& @/ r9 A6 i) {
- while (1)0 E& b8 s% d7 m) A; x, g4 ?
- {" s/ Y. b; y- a _" M2 @2 P
- static float t = 0;+ D3 y# R2 D! D
- /* USER CODE END WHILE */4 u) I" H/ B4 y9 L) p* b& a( P2 I
- printf("A:%lf\r\n",sin(t)*sin(100*t));) q8 W) k1 @7 [3 t
- t+=0.001;
0 ^/ I8 d; i3 @ G- Y$ ]7 b - /* USER CODE BEGIN 3 */0 r" _" B1 k( k$ q2 H0 K
- }
复制代码
7 j0 ]8 G( d- Z
, f: J7 G/ f0 V4 B$ e( l) R+ @$ Q8 X
& r$ e0 u% k7 U2 [4 G转载自: 电路小白
, Q" B7 Q9 n5 W8 t; b
& o M( f0 S7 U# ^" {& }4 R如有侵权请联系删除# o8 Y5 m! U$ |8 `+ F
6 Y2 {! O4 \/ K- U# W; R- Z g, s, E' y) h+ I
7 V% G, n) ^! f( \& w
$ k; D! ]1 i2 Z; ^9 A" p0 @
h6 H( z: j3 `
% K, V' L/ s" T. j |