串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。5 B8 K1 r3 I) Y( |2 Z1 i1 M" f
本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。
$ m' B% K( F) U Z
' q: M/ E4 v8 j4 G
4 N! U9 g9 z- y. j+ q! g( E+ r) ?. b8 w% f" R8 B
( |$ B& y1 i: W t" X3 f
3 d4 D5 b+ I6 T5 V
8 S. V: B6 c* p0 k% H
首先打开CubeMX,配置时钟树和时钟源。8 O3 {: y& H6 V- \/ `5 p. k
% j1 t6 g' t+ [, W, {4 @
5 P+ |3 s( E& r. D! ]/ A( C$ i' l5 P0 V% h. h2 a& }5 H0 R5 f7 z! q
接着配置我们的串口,设置相对应的波特率。1 O( H5 [- C, G2 a6 D; f; [
( `$ |% G6 k7 b# j, e9 Y
4 L1 i- [+ A$ b* F$ w
: e5 G! l* H. E1 X' R
打开串口的中断。
6 o# {) h7 [8 \- J( y+ ~& ~+ D- u
然后创建工程。- \( \' b" @* |
) c3 p) L9 X; i3 @# n
$ [: x8 J; T& z1 f
2 r4 D! \* T) O! F2 s. \
在魔术棒中勾选Use MicroLIB1 [* ^2 n, r, X
- unsigned char ReciveBuffer;
复制代码 $ B0 D4 Y7 c' c9 O* } n; x5 L( y
在全局定义一个缓存用以存储中断接收到的数据。1 l' O: j. J$ z+ x
- HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码 4 J0 K9 D* L: `: O* O& @$ q# v0 t H
初始化的时候需要启动串口中断。
: e- q$ h5 C- e4 o1 d+ d- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
+ j) L3 s! I# w6 G+ H - {
, S( ?8 C0 n$ x, u" ` - if (huart->Instance == USART1) // 判断是哪个UART触发了中断
( n" a: U/ F! l$ R; \ - {
3 r, x0 @8 v8 r9 C/ c- z - // 处理接收到的数据/ l7 S9 R% f C9 |
- HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去$ } [* h2 B/ `0 ^8 {; Y4 O# }
- // 可以再次启动中断接收+ Q2 F- s* h7 R4 j3 M. Z7 @0 F( _
- HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));! w2 {9 t: Y7 m, D
- }9 d( Z; j2 b0 l
- }
复制代码 " i3 N2 S. ], \: Z6 L5 {& ^7 m
接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。
( `+ E9 `& @" n& ]7 v3 H8 h( C" \" K* x5 a7 o: Y. b$ ^6 J6 s" N
; \" g/ ]- k& d% X7 C
- }6 P2 W8 @' t/ y, e可以看到,我们发送的数据被原原本本的发送回来了。4 g/ Q. k6 b: B: u2 `0 ]
! l+ C: Z- l: ~6 t
串口的重定向
' T; i/ E' B$ ?; t# ]" h重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。
+ I; l* X9 E4 \9 X2 R: C' A2 \
' ~ `4 L# J2 w) f5 H& r0 b4 [串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?" D( y' P2 U5 u: G$ ?" t
* O# \$ K2 _/ _" O/ }( U: [9 ?/ H- F; z我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。$ F" P( m+ c0 o- {) ?5 F
1 l" V V) z4 Q9 g3 a通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。
, i7 q' Y9 `2 y/ O0 Q4 K0 Z# e- int fputc(int ch, FILE *f) {
$ o8 G6 R# y# U6 v" D8 W$ n* \ - // 发送单个字符/ H' F, G# N8 A6 B& p9 i
- HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);$ V3 q, W. P$ E4 f2 s
-
$ u5 t. z* R! U/ I - // 返回发送的字符! I, H1 B+ q7 p7 p
- return ch;3 H( K: `4 r9 f$ Y9 F/ V
- }
复制代码- while (1)
1 C0 A) k7 M# s7 ~, s - {
& Y4 N J: e8 W2 v& H! i - /* USER CODE END WHILE */
/ s( t0 T7 X) B; L: ^6 C - printf("Hello\r\n");
7 T) P6 i$ ~8 ~! I- Q - /* USER CODE BEGIN 3 */
% A6 {: H: T0 \' r6 U9 W2 _ - }4 [" t% K& j1 J- I
- /* USER CODE END 3 */
复制代码 . \& E$ @" j- z! ~5 C$ ^2 t
) S- ^ s {$ ?# z+ Y+ k0 G2 k' f/ W. _
8 U' W( A0 j3 A4 h正弦波
) i8 N6 R4 _6 o3 b2 |% R, h- while (1)
0 w X1 _" h7 J6 u+ y1 N' v0 n. B - {- ~- |5 a) \& [& |! Y
- float t = 0;
" Q3 v9 D4 j( u @1 U# u" h - /* USER CODE END WHILE */2 S: E$ g% K$ E' m$ g" n5 [
- printf("A:%lf\r\n",sin(t));//正弦波( i0 ~/ c8 Y- k. a% y% d$ ~
- t+=0.01;$ {4 `5 L' q+ I; N
- /* USER CODE BEGIN 3 */9 u" C" n5 c! }% ?! o
- }
复制代码 7 e- }2 ~' V5 ]- V! E# ] T
2 U# v% }- T. E4 A
" {. H' l' u# E: v3 ]! J" F
6 N# F6 R( P1 U正弦波相加) u& w' C0 X/ X0 s4 f
- while (1)% a+ ~. c* _7 T' [- @8 ?
- {# @/ Y0 B6 q8 J7 g) t/ r
- static float t = 0;
: d, t0 N+ n, C3 H. I( @ - /* USER CODE END WHILE */
) E! C+ n8 P+ X) o1 p - printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加% e( l! q; D/ q$ L
- t+=0.01;8 |2 V. \! E7 \8 A. n% n1 K6 `
- /* USER CODE BEGIN 3 */6 L7 {# d2 l* Q( v) f3 y
- }
复制代码
+ l' ~+ o" v3 q# s
, v Z6 C! U* P$ D% p0 O5 m2 |( M: a' P% u
' ^$ I' c1 w9 M5 O" D
正弦波相乘
4 U+ d' t6 u. F: l- while (1)
# P" i, k" n2 v! L$ r4 ` - {
% ~6 e2 G3 E- s( ~3 a0 r O - static float t = 0;
5 P; |% X- M8 H: | - /* USER CODE END WHILE */
) g( X3 t* i6 Y( ]- q2 i5 m - printf("A:%lf\r\n",sin(t)*sin(100*t));
% x9 y' b- Z; n7 U - t+=0.001;' M5 c1 p1 F( r& d7 B& J8 v* F
- /* USER CODE BEGIN 3 *// }$ {# \* {/ k( T2 v g$ K
- }
复制代码 : @4 M4 f: E/ z
! a- u' G& h, Q& \& I& O( R8 P+ ?/ j* q: z6 m, ~3 d# K
转载自: 电路小白- m/ o2 b( @" m. m& @, X- ^( A) }
" N% I0 e% D$ i
如有侵权请联系删除, o/ D$ V& F7 M4 x1 T
" O+ }2 o$ m, \# q( e
9 \8 x9 b( y$ y6 ]" ]9 t7 F
1 [/ u" \7 i% I* g
; R5 g. [- d5 U
+ E& A% Z! Q+ b, p. P2 Y5 P( u% B4 `- m) T
) y4 R: n& a# w0 U5 ]! H% ]! x/ y+ j |