串口UART,作为基础的一种通信协议应该是我们接触的最早的通信协议,有许多芯片和模块可以利用串口来进行通信。
) p+ C& _/ Y, @3 w0 N8 L' u本期我们介绍如何使用CubeMX实现STM32的串口通信以及对printf等函数的重定向。
5 Y" f5 u: B3 J. g* }) r# S( k5 n: ^% X" S6 b6 H, z' o6 E9 I( G
2 X3 I+ \% ?; c+ W" z
8 P7 s% b7 X, p+ _& n, o/ i
+ g* t; b0 u4 w( @5 {! O
. e4 t$ J4 a- t& N% ^
$ b) M2 q1 i. W: \5 K; |1 q首先打开CubeMX,配置时钟树和时钟源。
( p$ I. k+ a2 P7 J
$ w7 p% B7 S( ?( r
& S8 e+ T. q% x5 v1 d) \
0 r4 Z; E5 m+ I" }接着配置我们的串口,设置相对应的波特率。
, h) i# z! H, v% B2 O
# y4 O- _. `7 o7 c
& E3 \) c1 \1 a7 \
8 \; u0 t) @( k5 O! ?+ J2 _* g打开串口的中断。
# k! u, f5 q: C0 U7 E
" c& J+ C- k$ o3 _8 k6 X/ E然后创建工程。
' d+ ?2 \5 y$ n
& c" h/ ~ X, t9 U; F
: V. c% `8 b/ Y- Y8 G( f2 K* t) P% i! P6 E2 V+ b3 Q
在魔术棒中勾选Use MicroLIB( \; f8 P& i9 ^; p' l$ p& Q/ [
- unsigned char ReciveBuffer;
复制代码
/ W! ^5 D H }9 B在全局定义一个缓存用以存储中断接收到的数据。) |. y L8 g+ i
- HAL_UART_Receive_IT(&huart1,&ReciveBuffer,sizeof(ReciveBuffer));
复制代码
. b8 }3 u9 r' |/ N( A初始化的时候需要启动串口中断。* [0 o# K& h% G1 P+ C
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
/ l$ D9 U( D7 _3 j) z5 A9 E u - {8 i8 q/ j: p- q1 ` C8 A7 M
- if (huart->Instance == USART1) // 判断是哪个UART触发了中断! V; a! J0 e/ r! v! h' D5 I- i- @
- {
" Y' X' _ |9 z+ I( p4 r0 n1 @9 j - // 处理接收到的数据- m2 N, V8 A3 u; t" q& s4 o
- HAL_UART_Transmit(&huart1,&ReciveBuffer,sizeof(ReciveBuffer),0);//将接收到的数据发送出去7 x# M% t9 |: u7 M
- // 可以再次启动中断接收
. I* x, w, \' Y1 y, |1 c - HAL_UART_Receive_IT(huart, &ReciveBuffer, sizeof(ReciveBuffer));
- a u9 M( i6 M - }
( n1 J7 \. R" L - }
复制代码 # [3 g; y' ?* t
接着编写串口的中断回调函数,我们将接收到的数据发送回PC机。" Q2 s1 b; `8 z( i" K; p
) i5 M9 D a7 a- j, s
1 Y2 h2 i, O7 F% C
: X. W, M9 ]0 _: p
可以看到,我们发送的数据被原原本本的发送回来了。
S ]# P. i( a# X) ]/ S# |7 O3 e& c, g& w2 B) ~
串口的重定向
! w; @% ?9 h- g4 L' _7 m# x6 @" H重定向在计算机科学中是一个常见概念,特别是在操作系统和编程语言中。在C语言中,标准输入输出库(stdio.h)提供了标准的输入输出流,如 stdin, stdout, 和 stderr。这些流默认连接到键盘和显示屏(或者命令行控制台),但是C语言也提供了机制来重定向这些流到其他的输入输出源,比如文件、管道或者其他设备。7 ]" }! y: p' h0 N" M# [. M
$ f1 X- [% P1 t6 |! F2 t( x串口的重定向可以非常方便的让我们解决发送的格式问题,可以看到,其实使用HAL_UART_Transmit发送文本是比较麻烦的,C语言的标准库中有printf函数可以方便的让我们实现指定格式的发送,那么如何将printf函数和串口结合到一起呢?
3 H! b* {8 ~8 y* U, W$ V A5 g* I
0 K& J" @+ M$ K! z* h; j& k; g我们首先需要导入C语言标准输入输出库,这样子我们就可以使用printf函数了。7 e4 J8 H. O1 ?9 A6 M: A7 D
; g! c5 A r2 S" k通过重写 fputc 函数,可以控制 printf 函数的输出,因为 printf 最终会调用 fputc 来逐个字符地写入输出。通过将这些字符发送到串口,实现了将标准输出重定向到串口的目的。
6 V( L1 K/ l* c/ }7 |( y! M' B- int fputc(int ch, FILE *f) {+ E o+ C5 j5 s, [2 c6 q9 g
- // 发送单个字符
7 f4 r+ S3 |" z# y) K - HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY); |0 F$ d" m- m, i7 Z( F( ?& Z
- / T+ C. A, J7 ~$ j
- // 返回发送的字符
( T9 O/ N0 Q% M8 m# B V# i - return ch;
1 k$ [% Z- L2 `# W: B4 G# {6 K- l - }
复制代码- while (1)* E: ]: ^% a- } J, b
- {
$ Y" N6 s0 p- @! u# m* V - /* USER CODE END WHILE */" V2 {! @6 T+ D- `$ t; ^
- printf("Hello\r\n");
1 i3 |5 {9 v9 G) o - /* USER CODE BEGIN 3 */
- W j' ?- k- _4 n% T, j - }- U( ^0 U( @ u' A
- /* USER CODE END 3 */
复制代码 . R+ c/ K8 C n8 Y( N8 H9 q
% h2 N6 M" I) l2 e; @; n3 R; O0 l0 g" }2 F' U2 `4 A z
9 V& |! k Z1 f$ d
正弦波
- z+ V1 c4 C1 R8 W' k; X- while (1)8 j0 E, {! D; y# F( @
- {+ c2 r6 ~, G2 a! O$ G7 S
- float t = 0;+ r# S! I5 w! L, ]% T4 J- S' C$ J
- /* USER CODE END WHILE */0 d: [9 d: H6 t9 p1 L
- printf("A:%lf\r\n",sin(t));//正弦波# f- w6 j& h T
- t+=0.01;
: ?/ `) _6 y) S4 H+ ~ - /* USER CODE BEGIN 3 */
% q% p+ |2 e" S) [. W- H- c3 V - }
复制代码 & s l7 m! t. D: n5 I1 U" u" _
. ^* z: t; e' N' t
) W8 \/ c; m% {+ m- `4 l/ T* \% N' z8 X6 p- z3 s7 F* v) B/ U
正弦波相加
, c) u+ U4 j. L# O( e& F- while (1)6 n( C- J5 R; Y' [
- {# p+ L$ Z b# f& e1 p- Q
- static float t = 0;
9 |, U+ w- D) l2 p" V% W$ q- i; O - /* USER CODE END WHILE */
' x1 m# s' z' s3 W - printf("A:%lf\r\n",sin(t)+sin(10*t));//正弦波相加
! w2 Q F4 U! x/ [, B% W; n - t+=0.01;$ v; \- \: X5 |7 Y
- /* USER CODE BEGIN 3 */( V6 z5 J0 ^% u: L
- }
复制代码
9 t- _6 }9 E7 S$ l7 [% W
2 K8 d0 `; o8 H5 F
8 }4 a8 {$ q, o5 Y( m( F" V% N0 i8 c+ _: I
正弦波相乘
4 ?' s! {6 Q% Z4 k. T- while (1)
1 v- c! B2 ]7 D! v9 Z4 j - {
$ w5 ]& ~, Z- ^( M - static float t = 0;
/ B$ u% ~% I( T, D4 I% x5 e - /* USER CODE END WHILE */' r( ?( w5 P# r& S# o8 f( R$ c4 l
- printf("A:%lf\r\n",sin(t)*sin(100*t));
0 D* j' o" E' b s% b+ I9 ]" U - t+=0.001;
, R6 `* q2 G, k; [; ` - /* USER CODE BEGIN 3 */
3 {$ p2 \% f& ~( G2 A - }
复制代码 9 t. ]% A% p, g* q
7 q9 @! d6 B! r0 u7 T4 ` p5 k
' X7 B' a$ J( m/ o! }3 d! A h转载自: 电路小白
4 p/ Q ^* _# s. Q4 n
8 g# Q' V Q4 l/ h9 D4 \如有侵权请联系删除
o, i4 `, r0 H; `( n& q$ n, W6 h" T: B& p
$ ?' o: X8 B" q8 b9 H0 ]5 n
) ~# O1 u. b+ \9 K4 v
, d0 y& }7 O- N1 c) T0 x2 @. y/ w* S: T# w# I5 G
6 b" V: ]+ A$ u |