串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。
0 I7 U8 `" _) c2 b! Y/ m* }/ u" p本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。8 G! G/ S+ p( [/ G9 j
7 t. @3 Q$ S! Q7 X
3 d2 {3 Y% Y' i& [7 m( w" N
' r7 T- z7 ]* m5 M* `6 l' B% d+ [; k. z
2 ^0 o8 m) C5 a) Y0 g
8 H* j1 u n9 d. F# b4 p$ l. M
首先打开CubeMX,配置时钟树和时钟源。2 Y2 ~" \- X* ~9 S" C/ ]7 I7 P
! V2 E& E1 b# n. P9 y
; b* C4 D" O y" G" _; i9 v" c
: s7 |6 L5 {3 O/ t% G& ^+ }, V K接着配置我们的串口,设置相对应的波特率。
+ w1 E. L; w$ j) X
0 M8 \3 Y/ w7 x }
" N$ E3 n O9 J: Q% N S
4 \6 [8 E) |- l0 u- z. L6 N1 B( l
打开串口的中断。
) f9 K- }$ V. P9 Z; G9 m3 \7 x
* q4 v3 K" d) z2 @然后创建工程。2 P" S. W: d) A8 Y: g2 S' i& ?- c% P9 m
) R5 {8 B& L9 j, f) H$ Z- E3 M
$ D B% Z+ Y! v% s' O' m$ G4 D
& P9 d7 [6 }; r P' F5 n在魔术棒中勾选Use MicroLIB; M- L! r4 n; {6 u) z/ O
- unsigned char ReciveBuffer;
复制代码 . P$ D! K0 y: X
在全局定义一个缓存用以存储中断接收到的数据。
9 u6 P) S' g9 Q9 { C3 j- HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码
) U8 Y! [0 v" ~, }' `; Q K+ t初始化的时候需要启动串口中断。
6 x0 R) m$ X. I. f1 \) y% A0 O- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
6 V# V& u1 ]+ A3 b; @% S, `" [: m - {
! l( H$ {( J9 I: G/ d2 ~ - if (huart->Instance == USART1) // 判断是哪个UART触发了中断4 ~; I( F% |% E& p* k8 n
- {5 \( l8 n f2 R& J7 w
- // 处理接收到的数据& C6 N |0 c% ~% O
- HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去
) N" D9 V9 }" r& q4 q - // 可以再次启动中断接收
9 Y7 r7 L8 H( p1 |1 W - HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));9 ~* }! e( F. {( j& I5 I
- }
! e4 }# P' Q5 k. J' B - }
复制代码 * q; z, i8 q) d Q& \
接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。
0 b: a9 L- u# O2 {' q
4 Z4 K" k/ }! J2 T
; D$ ~( Y0 \0 d& l1 a8 k: [2 y- {" q
可以看到,我们发送的数据被原原本本的发送回来了。4 ~9 Y0 t/ c% X9 R
& U6 I, H3 H/ R7 z8 j- |
串口的重定向. a: _. t' s3 i& T: @2 A2 q2 P/ d$ G5 t
重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。' l; [) c8 ^& _8 w
9 D# q+ |# E% r# R4 N6 A8 C
串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?
0 ]; O: b0 {2 S* O! ~$ N( R! `% o: U. P9 J0 ?2 q) j/ j6 v
我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。
; I( z. N( h; V$ c d
( k5 Q9 _! [0 t5 `9 }9 q; J通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。
2 E6 c1 y0 K' T3 K" l) _4 ?- int fputc(int ch, FILE *f) {7 ~7 q$ L, o% K, X4 K
- // 发送单个字符- V; ~/ O% y: y e9 S# `$ S7 [
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);- O- Z+ B3 v+ m
- ( V( p: p# h6 w) z& x
- // 返回发送的字符& J- ?: M( S7 W% K' u8 h
- return ch;" x. I0 U: i/ _/ Z" A
- }
复制代码- while (1)
9 D4 M" H- n# a: y' q6 Q - {
: o% l+ |6 @4 N: @- s. h) ]2 U - /* USER CODE END WHILE */
7 a; }# D$ W _ - printf("Hello\r\n");1 n1 S7 @8 O1 k3 E+ l* R! X( g
- /* USER CODE BEGIN 3 */
- e% ~+ m+ X: L/ j - }6 p, L; L! m+ r- e* m% U8 d
- /* USER CODE END 3 */
复制代码 9 Y& C. T9 q! l
" Z& t, t9 H$ e7 v! O/ l
5 D* C6 H2 K A1 \$ _: O9 D- m: B# a& M; s% Q6 ?* u, a
正弦波
" |; e; c5 t) J+ D; x- while (1)
" w9 Y3 n- j# Y% K0 i1 { - {0 O3 q, k I/ W% }/ J3 r
- float t = 0;# a! m3 Y" H0 [% i) q, x
- /* USER CODE END WHILE */
2 p1 C' d) l' ` - printf("A:%lf\r\n",sin(t));//正弦波$ A+ y8 t; r1 r. q0 K
- t+=0.01;. W; R# p* T0 U% f7 r% T! |2 W9 T
- /* USER CODE BEGIN 3 */
& o9 ^" U7 F8 U! D' W6 b [2 K - }
复制代码
; r( F1 p J% u+ K
N G+ {, \+ m$ \8 n. P- m" \5 F
1 U. @9 x/ R9 A1 y. \5 e
( m/ r0 j. S$ N正弦波相加 m2 x9 d* L) l! p% W$ _
- while (1), U: l5 a) _' ~; Z$ E
- {8 M! `; j ~- { J! M* r$ a& L
- static float t = 0;
* K. v4 `4 o9 f( Y. s% A - /* USER CODE END WHILE */2 R& @6 i/ K) M
- printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加+ L. m* h" x! o5 U7 w+ H$ ?
- t+=0.01;) ?# O, f4 M( y
- /* USER CODE BEGIN 3 */
+ [$ ~. a: B1 u - }
复制代码
- z6 l& ^: u& ?6 W3 k
3 J4 ]- m$ `6 N
G. ^# L% F$ Q4 F" l0 L4 D# z' w7 ?: Y
正弦波相乘* U) \1 |6 V) n6 I$ {& `% G
- while (1)
- d/ y" q ]0 p- b - {
. a: {! J2 }4 R) H4 l2 i8 w; C - static float t = 0;
3 h, I; ]& z# x3 ~6 @5 I3 }% ? - /* USER CODE END WHILE */2 r- {0 u+ v% F) ]- g6 m6 h
- printf("A:%lf\r\n",sin(t)*sin(100*t));* r- _ h% ^. R+ u0 i
- t+=0.001;
1 v1 N$ }$ A0 l9 e - /* USER CODE BEGIN 3 */
/ k# w1 Z- ~0 x- e* {3 f - }
复制代码 ; c2 j" D( ]" U6 G8 x
2 T6 n# x4 x$ q$ M+ y! S' J4 F" r4 f7 F3 b" f
转载自: 电路小白
* |/ T8 a$ i4 Z7 z) o$ I/ {' U
/ M$ l! {& j9 W0 k; \/ }4 h) |如有侵权请联系删除
9 R: Y9 r, P: c2 t+ e5 l8 D0 Y7 R" L: W, d4 L' I+ b8 J
. J% { C& v- X( ?& L4 R3 D1 W" x, b2 C$ q% i" c
% C' p6 S6 `, I! j
& @2 ^, ]8 K$ J; B0 B1 d. y" x
/ {" [# w/ ^- Y: [, P1 a/ Z |