本章节实现UART测试,实现串口的收发功能。
6 L8 N5 O$ `' X. E, f: j+ F 我们通过以上内容的体验,可以说基本上实现了使用STM32CubeMX图形化配置软件,配置STM32H503RB芯片的内部参数,外设参数,引脚分配等功能,这些也是会贯穿在整个开发过程的。接下来我们继续展望一下功能的实现,加入串口后通过串口调试工具进行LED的控制,实现和按键一样的功能,并每次LED状态发生变化后通过printf打印当前串口的状态。% `/ e. m" T. x- |! v; @
我们分析一下需求,串口的发送实际上就是在这里就是实现串口打印功能准备通过调试器的虚拟串口使用printf打印,而收数据通过串口中断实现。
' O# s2 f. f2 C W8 x, A% \/ a# y 我们先看一下调试器对应的串口接口:
0 ]2 r1 A9 F- H
' O9 ]+ X% ^$ i ]
: \; s* [/ d9 }9 ~4 D
串口打印功能,STlink的虚拟串口主要用到的PA2和PA3,如下图:: p' Z, D U+ }! G, Q
" t3 P; J8 s _) W v
0 a8 K$ o7 N/ E3 E/ B
我们在STM32Cube中看一下这两个引脚可以配置的是UART2,如下图:+ l' a7 |% e+ [9 ^7 L7 ]! q& m
8 X4 \0 R& r6 b5 D3 Z
5 y# F- Q) [! @4 g" Y" K0 `/ U 仅仅配置引脚是不够的,我们还要到对应的串口模块进行配置:
& g. t7 C% o( j+ h* a8 S3 M
% c' K _. F' n 开启后目前使用的基本就是初始配置,115200的波特率,注意开启中断。
. ?$ W% P( i6 I3 j7 E% t( v' g. w: i; ]& z
我们先实现一下printf打印功能,通过一下代码实现:
, k1 r: N! s7 x% z- #if defined(__ICCARM__)
, t* G6 V. }+ n8 ]3 L2 l - __ATTRIBUTES size_t __write(int, const unsigned char *, size_t);2 k! E4 s' Y$ s1 |
- #endif /* __ICCARM__ */ Y* @' t" G, Q) V" Z0 X( t
- $ H) x& X# {, b$ ?
- #if defined(__ICCARM__)
: o2 u& l5 P% h0 j- w - /* New definition from EWARM V9, compatible with EWARM8 */1 p% ^. H6 }3 T* ]- b& c
- int iar_fputc(int ch);
8 K; J7 _6 [% @/ b - #define PUTCHAR_PROTOTYPE int iar_fputc(int ch)
' {8 w( U5 e2 s1 y. r - #elif defined ( __CC_ARM ) || defined(__ARMCC_VERSION): I/ l& j2 Q$ S9 _: Z5 L% r0 w
- /* ARM Compiler 5/6*/
: W7 W& K$ H0 K, C) S" ? - #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)# _7 ~( H; c; g* a' e
- #elif defined(__GNUC__)
5 w, j& m) m3 Q% K+ t ~ - #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)" ~% M8 r( Z+ ]7 B, W! k
- #endif /* __ICCARM__ */
" w& w& v1 s5 n+ {0 Q
( |/ j2 R2 w; q i# `- PUTCHAR_PROTOTYPE
: `. l" M; {; J - {8 ]& V% H% `, D) r& D. C
- /* Place your implementation of fputc here */
; s! U& p( z, M# J- E: V( r - /* e.g. write a character to the USART3 and Loop until the end of transmission */
, h+ S$ n$ G# V& k9 Y$ m - HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF);' z! t/ D1 `0 b- |/ t/ b
0 C: p" o" A/ {8 u6 K- return ch;% V; n' A8 Y+ E F' U/ y$ j
- }
复制代码 <article data-content="[{"type":"block","id":"rslu-1712821672106","name":"paragraph","data":{"version":1,"style":{"textIndent":28}},"nodes":[{"type":"text","id":"jUJd-1712821672104","leaves":[{"text":"这里有几个小细节要注意的,首先是打印使用的串口,不同的调试器虚拟串口连接的可能是不一样的,我们要关联对,另一个就是MDK的配置,要是用标准库,需要把下面的地方勾上:","marks":[]}]}],"state":{}}]"> 这里有几个小细节要注意的,首先是打印使用的串口,不同的调试器虚拟串口连接的可能是不一样的,我们要关联对,另一个就是MDK的配置,要是用标准库,需要把下面的地方勾上:
; i( F$ z7 t |; m f; z
7 Z3 T/ B, C9 s) j+ J) I1 b1 M% `
5 {9 I8 p7 t: K# E 可以看到串口可以收到打印的内容,与初始化段的一致:. w+ K2 R5 D6 u+ I. c
2 t' ^6 C2 z" ?3 G2 }* S3 ~ , k& g" s4 x, W( g, {9 Y5 c/ S
接下来实现串口对LED的控制,并打印LED状态,记得初始化后开启一次中断接收HAL_UART_Receive_IT(&huart2, &aRXData, 1);:7 b% s! t' y1 N& q
- uint8_t LED_state = 0;
9 D7 j0 y9 x% L9 z, g7 c - uint8_t LED_ChangeFlag = 0;) [& U, D8 i! Q K" w) |
- uint8_t aRXData = 0;
, K8 t( o- U4 v# d7 O; I
8 G; e$ o, g5 t/ {5 U ~- void HAL_GPIO_EXTI_Falling_Callback(uint16_t GPIO_Pin)1 A6 I4 g+ H+ Q: [/ `" o
- {+ [0 B8 n) Y- w- {# e- |: X
- if(GPIO_Pin == GPIO_PIN_13)! Y* K+ C, N, ]' S$ z/ r
- {
, k3 A- z+ b) [6 Z: ^% X2 O - LED_ChangeFlag = 1;& L7 y9 c1 w3 Q0 x. q0 b: M. b
-
( L1 u7 l. j# ~6 ~1 a3 p0 H. U - }9 ~. X {& w- R$ Z4 B
- }( W. a$ F* d7 i4 n7 W6 I
- * x. R" E- k: L9 n
- void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
! `) G2 r7 v! J4 s8 h4 M1 G - {
% E8 B1 `3 S5 O8 j - + T2 I! @. F8 T1 M' m
- if(huart->Instance==USART2)
2 L3 c+ z9 L/ N6 o* T7 ~ - {3 a* l# R2 _1 t4 X7 n. u
- if(aRXData != 0)
1 Z+ X( ^2 T7 T, r5 Q" Y/ [ - LED_ChangeFlag = 1;* v( M4 ]6 {! \( t4 \/ g
- HAL_UART_Receive_IT(&huart2, &aRXData, 1);
" M `! u! h+ z9 S8 Z+ I" h* A - }
9 \1 r+ S8 U9 Q2 R: n% L+ N$ V' [$ N
& ~) x! a3 }" i* \, N- 8 T: p {9 N1 {" J0 v L
- }
复制代码 在while中统一处理:0 Q6 V6 Y5 Y: y- O, s/ ~
- while (1)7 U% a+ M4 z4 f
- {: s" p8 @! `- i0 M6 ]
- /* USER CODE END WHILE */
9 W: ~2 n) V: u8 [0 G& k
) o# n2 L" M5 J9 ~- o3 O; i- /* USER CODE BEGIN 3 */
+ `4 ?: p& P8 ^/ B9 q8 I - A9 b. o$ v8 E) f" p
- if(LED_ChangeFlag == 1)& m2 l# l( n R( B5 r) g1 g3 |
- {
4 Q3 Y4 L6 P3 ^( Y# _0 j - LED_ChangeFlag = 0;6 e, {4 w& P1 C
- if(LED_state == 0)1 D" [" u. [, c5 q7 C: q5 m
- {, S0 |3 @2 X% k/ [
- LED_state = 1;
8 e+ l; L7 M/ X2 o2 v - printf("** LED Open! ** \n\r");+ m& y; B8 {$ H6 v9 _/ j
- }( D1 V" |4 T5 s6 H
- else2 t1 B: @" L; W# [ m
- {
3 ?; L- m% \- G s: R$ Z - LED_state = 0;
% M% H$ X5 R1 Y - printf("** LED Close! ** \n\r");' U; U0 D/ v( j
- }: d2 D8 X A( ~( B3 _. A% y
- HAL_GPIO_TogglePin(LED1_GPIO_PORT, LED1_PIN);
* L$ j; i$ B" v0 @ `4 Q4 f - HAL_GPIO_TogglePin(LED2_GPIO_PORT, LED2_PIN);
$ o4 L X3 n | - 4 Y- ]& C! z6 B: ^* V A+ ?! @
- }* g1 @+ S# h/ d+ B' R9 |
- HAL_Delay(10);4 r1 \* S0 p5 r( g, ~% E
% U N6 ?2 C0 ]; m5 L9 x; o- }
复制代码 状态效果保持一致:3 w/ ]( Y* i. F$ Z0 _2 h
) L9 h7 D6 N7 A$ h h7 z2 r
: k! r2 A, V# s8 f
( V8 L% C8 B/ f; v5 Z8 f' O. v; o) q' P
1 `& [& H6 G% [4 |$ s) z3 P! k
! z; w) k% S: f3 `9 {9 n
, g3 T) ]6 G7 m# T; Q1 ~8 l' j- @: l7 r. n' j3 s. O8 M5 `2 q5 f
1 f- z [5 j- T4 Z
- C5 S* Q+ O7 m* w$ X; X; v) A7 n: I
|