串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。
% N7 V- m% e/ Y) a本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。
4 U. k p# Z! v% ?7 f3 z- L! A: I9 e, T. B( W
/ {: _' A9 ?) U( l
5 f. M* D0 A5 q( V# Z/ p; o$ D8 e2 N: E2 j( l
* {- x5 s5 _8 [1 Q5 B& r3 N2 {3 i6 A" }% J; n) l* a# y
首先打开CubeMX,配置时钟树和时钟源。8 h# @9 R& b4 h3 A& W
7 a- o2 Y7 d; M# v# Z" m
3 }* R* [/ [( E3 ?1 P
2 P, I8 q* J' D: R* u* j9 e接着配置我们的串口,设置相对应的波特率。) O: |; T5 H) ?1 L8 `
, m8 d. G! Y5 G" X
( _6 }) u4 q$ Z8 V4 i6 L
3 ]$ O t: k- ^8 A S) ~2 c; X打开串口的中断。
6 E. a! R. |3 p' o, A$ g. Y; G
$ r# G& u2 Q5 T然后创建工程。
- ]4 ^4 X& x1 M" h
5 H5 v. p& \; _1 y* X; I z
) e& A0 |" y. w
4 K% f3 o0 C" i4 M7 D- ^
在魔术棒中勾选Use MicroLIB
2 e& @# N6 W) k1 w) `- _- unsigned char ReciveBuffer;
复制代码 ' Z; H4 S+ I w7 P3 G& M
在全局定义一个缓存用以存储中断接收到的数据。( W' m' Q+ x+ ^" u% x
- HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码 ) P5 X# M' u. r6 m/ d; M. ?- m) d
初始化的时候需要启动串口中断。
+ d1 i: P/ ]- p$ o" H- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)0 w/ n5 O) k& \3 l( `1 R
- {) h% u& b8 ~+ ~/ L d% o8 n! q- |
- if (huart->Instance == USART1) // 判断是哪个UART触发了中断
" R* Y! l/ r3 m$ b- D2 O) \ - {( X9 x" H# a3 W9 {; N& ?
- // 处理接收到的数据
. d( d- z1 m5 w; ?1 n @ - HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去, Z: k$ r# ^% e' W- Q" e7 C
- // 可以再次启动中断接收8 Q2 o5 j1 K, `
- HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));% a4 ~* `9 X! ~% J0 D( }
- }: ?" A0 c1 x/ B
- }
复制代码 7 `% W( [4 r7 h& c9 H
接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。
7 o; p7 L2 o! l* Y. L! T; b1 c
0 n9 W2 V' l+ D; ^
3 y1 _/ Z4 F8 y0 P/ V
% Q; m0 t* H _( i* f( h
可以看到,我们发送的数据被原原本本的发送回来了。- S9 c) a( V: T
' J- {4 W( v, d0 x: Y' |串口的重定向
6 [2 M. n7 J/ d- t' K6 h0 W重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。: b2 {% u W, w2 K
. V) k" ^7 U+ n* A串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?
5 U0 P# R% B v" N: F
; C S- u- p' |5 j) ^我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。1 l0 {' D! ^: P$ u8 E9 h. ]8 ^
E$ f: p0 r" u6 U* ]通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。) z9 |$ U+ v* ~3 r7 {% N q
- int fputc(int ch, FILE *f) {3 [- `7 u% k. f5 b b# J1 J4 u
- // 发送单个字符9 G7 M" P$ }* C
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
W# a3 C3 `% m3 c# s. c - " p7 L: N( Z) z: q- K; M! y
- // 返回发送的字符: T# X+ L1 F- U! S! k( O9 h) ?( @+ D
- return ch;
. ~! {- l8 u- `5 I- h0 o) i3 a - }
复制代码- while (1). w& x u) B4 H: R# W( n ]
- {
( M. j5 K5 k, d( j2 N( b - /* USER CODE END WHILE */2 v8 J* M# V9 O4 e1 ^
- printf("Hello\r\n");0 M. e0 O. }' L( E' A
- /* USER CODE BEGIN 3 */5 P( k. v; |6 F* Y1 e
- }- B% n5 Q5 X* P
- /* USER CODE END 3 */
复制代码
" o0 n9 a. x% \
: e7 t2 \! W W/ x2 M
' s6 V/ z7 _1 U2 `
) j2 p& }7 e7 u0 z, }7 ^4 C正弦波( z! V% K2 \. {$ P
- while (1); H$ f, W' s& s y1 |& c
- {
# G" a5 M- t1 D g) {% }; @, @ - float t = 0;8 \5 S7 Z% Y6 U: U, X! O
- /* USER CODE END WHILE */+ n; e4 ]# f5 a; c# C
- printf("A:%lf\r\n",sin(t));//正弦波
0 A6 T" Q2 c6 `8 k+ L4 Q - t+=0.01;- ^4 a4 }) x0 f5 J# D, w
- /* USER CODE BEGIN 3 */' g6 U9 ? _" m0 \; r
- }
复制代码 % D" ~" }/ G% w! X* {
5 ?* z f* [; H. [/ a$ U O4 u H
7 S: K; a; L% U/ v
1 X8 b, ]6 ^# O% P) `1 |正弦波相加
; m- ^1 G; B8 H; |0 T7 a! }2 |- while (1)
; ]- D, {8 b5 `4 K, M( E - {
( [7 P! a1 P# c* P& B$ l$ U - static float t = 0;6 y- [7 c6 i+ f. A2 \$ x
- /* USER CODE END WHILE */
& _7 ^. U1 Z7 j' |9 O - printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加5 j. |9 p2 ^9 y3 O7 f
- t+=0.01;
, z% t- m( T0 U - /* USER CODE BEGIN 3 */+ j: U" b5 p6 G& Z0 a0 R" g" G- N
- }
复制代码 " h' `. s; d2 @
; K6 k3 P0 n3 I# C" D
7 |6 s4 N: N1 t# n4 I8 ^
( ]+ n9 A9 Z+ z P) D5 P) @正弦波相乘
9 N* ^- h% i/ k g3 y2 }$ w, I- while (1)9 ^0 M, y K2 K! }
- {8 R$ U) }3 h( c" W8 [
- static float t = 0;
2 U/ H: w1 R# `/ Y - /* USER CODE END WHILE */
* o" J/ p3 B8 C - printf("A:%lf\r\n",sin(t)*sin(100*t));' D7 S& C. s. J* M; l1 p, y
- t+=0.001;
+ \5 z( y& _# j$ ^. c4 E$ ^; m" \ - /* USER CODE BEGIN 3 */
3 ~1 E+ l h4 z% k9 h; }* g - }
复制代码 ; [, P/ V$ z3 `/ b
5 x4 f3 Z. { ?
5 z, S; `/ U' b% u9 j
转载自: 电路小白7 V' V& K8 i. I' f
2 @" ?( P- Y7 }, m& b
如有侵权请联系删除
3 K( ]( p! C5 S3 q3 O: h; `8 ]. x; x) k% s1 ~# w7 A7 l
* r- q% t- a0 c# l
8 ~6 F8 D. x9 w) b3 Q
$ h) P, r- Q9 ~* {- z! p. I# D8 \7 Z/ u) `: Y3 w, v
! G8 Q/ K- Z K$ l' G) h' z
|