|
本节详细说明如何在本项目中新增串口通信,将超声波距离 dist_cm 通过 USART1 发送到电脑串口。 ' B2 t/ p, ]" G7 Y# V) @3 \6 }. y& i 1. 目标与环境 MCU: STM32F103C8T6 串口: USART1 (PA9 TX, PA10 RX) 波特率: 115200 8N1(无校验,无流控)8 m& D# W7 {# T( ?+ e 工具链: Keil MDK / ARMCC 5.06! S6 S2 x- X" H; u1 |' K7 B 2. 新增文件 头文件与实现放在 Hardware/ 目录: #ifndef __USART_H #define __USART_H #include "stm32f10x.h" #include <stdint.h> void USART1_Init(uint32_t baudrate);% j8 o+ D! ]1 R: N D; K+ V9 K void USART1_SendChar(char c); void USART1_SendString(const char *s); void USART1_SendNumber(uint32_t num); 0 N. n$ \5 J0 o2 g" ^ #endif 0 j( \# M" g! M; N4 g/ E. _/ d5 | #include "USART.h"( ?: G1 k$ O2 z; m' o# o+ _/ e void USART1_Init(uint32_t baudrate) {: O3 q+ B K( O GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure;+ x2 ]* N; g, G7 y' R! q " L) g H+ h P* S. f5 ? RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);7 i/ U6 |; E% I& d c$ m1 B , ]3 }, }, e% y- E; m p6 ?" ^ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // PA9 TX GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;& z- z# F. \) a+ D GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;9 b1 ^# s3 @6 T GPIO_Init(GPIOA, &GPIO_InitStructure);: G+ k* \3 p& @" V9 A GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // PA10 RX2 Q% ~) l8 _. T GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;5 ?' p$ s# i6 _7 o GPIO_Init(GPIOA, &GPIO_InitStructure);3 j [0 i+ s% T3 ?! }& A, q6 S 2 t9 A: Z6 m2 \ USART_InitStructure.USART_BaudRate = baudrate; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1;+ Y4 e% g. h6 D8 b; R* T USART_InitStructure.USART_Parity = USART_Parity_No;& H+ j5 o) C- A% r( p- T7 m USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;6 K. W7 c- L T USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(USART1, &USART_InitStructure);6 {& e5 {6 h# \0 w2 T; X" P USART_Cmd(USART1, ENABLE); } . f! `% S" f0 _& {* a ?# [ void USART1_SendChar(char c) {6 E7 `, g6 m2 |! S& ~ while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);9 _/ X9 j/ G2 ?0 u1 g USART_SendData(USART1, (uint16_t)c); } 1 ^ ]/ c3 C }; N void USART1_SendString(const char *s) {6 ^8 X- \, j7 `1 v6 M$ n: E+ I% @8 l while (*s) R0 t7 V/ o r9 M. B- j) ?" J { USART1_SendChar(*s++); } O, D1 J" t5 u3 g- w }5 Q) n9 R2 R5 t9 ^" M, C void USART1_SendNumber(uint32_t num) ]; s! Y- t6 _% k q- p% V9 C/ I { char buf[12];) L5 x0 Z# h8 T0 t8 o6 V$ c int i = 0, j = 0; char tmp;& p2 c( E' B$ u4 j G! T) r if (num == 0)* B- H0 M7 k& I# e* E& R { USART1_SendChar('0'); return;* C; { F% ^* J } while (num > 0 && i < (int)(sizeof(buf))): d7 X/ _* p- v {* ^" W {, |' }" h/ y7 V8 }& K buf[i++] = (char)('0' + (num % 10));4 Z( |0 J; V2 q8 N num /= 10; } for (j = 0; j < i / 2; j++); m. I% ]) I3 s: R; ~3 D. D {4 o W# G5 A# `+ M! f tmp = buf[j]; buf[j] = buf[i - 1 - j]; buf[i - 1 - j] = tmp;$ e0 c+ f% q' e( Q+ Q# k8 }/ N9 ?8 { } for (j = 0; j < i; j++) { USART1_SendChar(buf[j]);7 u# X3 O8 z5 |; Z# D R; g } } 将上述两个文件添加进 Keil 工程:Project.uvprojx → Hardware 组已加入 USART.c/.h(如未加入,请在工程里右键组名 → Add Existing Files…)。 ' `1 _+ b0 f" L 3. 硬件连接9 Y2 }- G }3 R! O- T8 d PA9 → USB 转串口模块 RX(注意是对接到对方的 RX)- n/ C' I; ~% s& e PA10 ← USB 转串口模块 TX(如仅发送可不接)0 x, g/ d( O f) r9 V5 \' @6 D: ?& H& L1 W GND ↔ GND 共地 串口工具设置:波特率 115200,8-N-1,无流控。9 U; q8 O5 G' V' m4 j 4. 在 main 中初始化与发送* X8 K1 I3 E& T8 E9 i. R4 i y 在 User/main.c 中包含头文件并初始化串口,同时将距离通过串口发送到 PC。& A8 E- Y+ u$ V- \% y #include "stm32f10x.h" // Device header #include "Delay.h" #include "OLED.h" #include "ultrasonic.h" #include "USART.h" int main(void)% L: T+ g+ J. g0 a- V1 X8 O { /*模块初始化*/ OLED_Init(); //OLED初始化5 ^! u& {& l9 q1 _4 W1 f) _6 X! Z& N Ultrasonic_Init(); //超声波初始化 USART1_Init(115200); //串口初始化(115200 8N1)* a% V6 M3 g, H' u8 X h O/ R /*OLED显示*/ OLED_Clear(); OLED_ShowString(1, 1, "Ultrasonic:");2 q2 n# s! j" m M9 q' l0 K) H: [3 I while (1)+ I1 b- U9 F) Y {/ W6 k: q8 u3 t9 d float dist_cm = UltrasonicGetLength(); OLED_ShowString(2, 1, "Dist(cm): ");5 i7 W% f" Z0 u; t# ~ { uint32_t d10 = (uint32_t)(dist_cm * 10.0f + 0.5f); // 四舍五入到一位小数; N% O5 |9 S2 U4 z1 X! U1 G( b6 v( E3 q uint32_t intPart = d10 / 10;; ?! D+ e6 c) s* A uint32_t fracPart = d10 % 10; OLED_ShowNum(2, 11, intPart, 4);* r' c! o3 P: s0 O OLED_ShowChar(2, 15, '.');7 L9 k; x4 Z2 P& C, R OLED_ShowNum(2, 16, fracPart, 1); // 串口输出:如 123.4cm\r\n USART1_SendString("dist="); USART1_SendNumber(intPart);- t; l2 w N% q; d' P, Y: W' B USART1_SendChar('.');: n6 _- Z7 W8 W) ~ USART1_SendNumber(fracPart); A1 a& P9 | h. w USART1_SendString("cm\r\n");: B0 i: I: U% r( j3 m% \ }. y# W% y3 K H1 f Delay_ms(200);# T$ w) x; w! |6 P2 o } }0 S& i A$ s$ S% ? 7 l# Y9 k3 i% m) @- [2 k 1 r6 y; ^/ l: P+ H M" M+ @) C 5. 常见问题与排错 无法编译,提示 stm32f10x.h 找不到:- \! M( S) Q) |( Q 确认 Keil 工程 C/C++ Include Path 包含 ./Start; ./Library; ./User; ./System; ./Hardware。4 u& \- h6 g4 c5 l USART1_Init 等函数隐式声明:) F* ~! C9 a4 h/ a/ w0 L! ~! C 确认 User/main.c 已包含 #include "USART.h"。 电脑无数据:9 o6 b1 s' [" n6 _: k% W 检查波特率设置一致;检查 TX 线连接是否正确,GND 是否共地。4 a3 \' C# k3 h" {2 P% \# b 若只接 TX/GND,PC 只能接收;如需从 PC 发回 MCU,再接 RX。0 q7 d% Z6 k2 ^# K, L H 波特率更改: 将 USART1_Init(115200) 替换为所需值(如 9600),PC 工具一并修改。 6. 可选增强 增加 printf 重定向到 USART,便于调试。6 N' {) X k" |$ u" R% W* ^ 加环形缓冲区与中断接收,支持命令解析与上位机交互。 采用 DMA 发送以降低占用。 |
STM32L562DK探索板——串口通讯测试成功
STM32L562DK探索板——再试串口通讯仍不成
实战经验 | 基于STM32G0B1的全桥移相+同步整流PWM解决方案
STM32L562DK探索板——串口通讯的再测试
STM32L562DK探索板——串口通讯的测试
STM32L562DK探索板——运动传感器测试
STM32L562DK探索板——继续深入了解Audio Play的工作流程
STM32L562DK探索板——触摸菜单实验之触摸测试
STM32L562DK探索板——触摸菜单实验之LED闪烁
STM32L562DK探索板——Audio Play的再了解
微信公众号
手机版