|
本节详细说明如何在本项目中新增串口通信,将超声波距离 dist_cm 通过 USART1 发送到电脑串口。+ U% B% E& ]% ]+ W. ?: ~# I 1. 目标与环境 MCU: STM32F103C8T6 串口: USART1 (PA9 TX, PA10 RX) 波特率: 115200 8N1(无校验,无流控) 工具链: Keil MDK / ARMCC 5.06$ X/ {6 C0 r, o. r p5 g& t 2. 新增文件 头文件与实现放在 Hardware/ 目录:' Q. j9 _" U( O; i' b7 D* S #ifndef __USART_H- Q+ m8 o0 c- D6 \% e" A #define __USART_H8 G. L5 r9 l6 k a1 @7 ~6 ^( W H. B #include "stm32f10x.h" #include <stdint.h>2 A( Y: t# T6 A3 H# z# _" v 1 W) D: C1 B: r7 Y void USART1_Init(uint32_t baudrate);- X( B& T1 F4 O4 \/ M6 R void USART1_SendChar(char c);! g4 ~! }& e8 M void USART1_SendString(const char *s);: i1 C% P/ ?3 `+ I) t void USART1_SendNumber(uint32_t num);9 Z$ w2 n. ~0 b2 H' d* L" M5 p) C 2 u! E+ R' a2 S$ @/ U& p) l #endif% j# p" S, \: ~0 h #include "USART.h" 4 T, q8 w; M9 F% z% \/ f6 J2 m void USART1_Init(uint32_t baudrate) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure;3 ?' ?" q# U/ h $ t; G1 ^/ V3 v2 c8 P$ n. L RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);5 |/ w- X4 l2 ? % Q. s S- I9 M3 j3 d4 q GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // PA9 TX0 M8 S8 H) b% j! | K GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;2 E" E' K) K- S GPIO_Init(GPIOA, &GPIO_InitStructure);; b9 d5 E$ g4 t2 v; O$ Y. R, w 9 V; ]8 e/ x( ~" o) i; F/ e GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // PA10 RX; g! o" O. c/ W$ _( t, }) m GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;' L0 v% g5 u' B GPIO_Init(GPIOA, &GPIO_InitStructure); $ R, J# M6 t: n4 u) N$ u, k% c* P USART_InitStructure.USART_BaudRate = baudrate;3 M" w6 u2 B( `* v! n/ P0 H USART_InitStructure.USART_WordLength = USART_WordLength_8b;) T, w& c2 M+ b3 H K% X- d. W USART_InitStructure.USART_StopBits = USART_StopBits_1;3 h# C$ {! ^# d+ A/ G- r USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(USART1, &USART_InitStructure); , J: a% g l- ^9 R) h USART_Cmd(USART1, ENABLE); } & e) z& f6 o3 w1 ~# [2 {" ^. g5 _ void USART1_SendChar(char c)% M, H" Z3 L1 I% O! P0 N4 w# H' m { while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);) B9 |/ t4 G" E5 z: E: O# m USART_SendData(USART1, (uint16_t)c); }8 U) n% r2 s- q2 z 2 S" {% e% ^/ s9 @& o6 r* q void USART1_SendString(const char *s) { while (*s) { USART1_SendChar(*s++);6 K5 }! P+ k& u# Q) ?5 @ }" g2 S1 m* H3 x9 V& T" [ } 6 [; @. o/ f- g& ~7 o' e- ? void USART1_SendNumber(uint32_t num) { char buf[12]; int i = 0, j = 0; char tmp;" `5 D3 D( x1 F0 W2 i, a# A if (num == 0) {9 l5 M' a$ F5 p7 f USART1_SendChar('0'); l4 X0 s& \# \4 ^$ w return; }$ g2 Y* N% S* E" `3 q0 k9 Z while (num > 0 && i < (int)(sizeof(buf)))# x2 P! A' y6 ] ? { buf[i++] = (char)('0' + (num % 10)); num /= 10;$ T- n" a* [6 K' {. A4 k } for (j = 0; j < i / 2; j++)% l/ g4 j* k& a- m+ s- u' S { tmp = buf[j]; buf[j] = buf[i - 1 - j]; buf[i - 1 - j] = tmp;) F& A: ^/ m+ N% w } for (j = 0; j < i; j++) { @3 j% R/ @# P( }, f: V- e USART1_SendChar(buf[j]);9 S* G! Z% n7 m% [& X }( q4 [% i d' `* K; j* q }* N* X. e$ h: A" m' n/ V$ N1 W0 F ' j% o5 E0 |- ]. G5 ^ * W+ A7 @# N0 Q 将上述两个文件添加进 Keil 工程:Project.uvprojx → Hardware 组已加入 USART.c/.h(如未加入,请在工程里右键组名 → Add Existing Files…)。& K1 O/ W. ~6 F e+ ? ! P0 t. W2 c0 V; z 3. 硬件连接 PA9 → USB 转串口模块 RX(注意是对接到对方的 RX) PA10 ← USB 转串口模块 TX(如仅发送可不接) GND ↔ GND 共地 串口工具设置:波特率 115200,8-N-1,无流控。 4. 在 main 中初始化与发送 b- n! C' @; h2 E, o6 m 在 User/main.c 中包含头文件并初始化串口,同时将距离通过串口发送到 PC。' x$ f) ~6 V2 z" L9 Z F% T #include "stm32f10x.h" // Device header #include "Delay.h" #include "OLED.h" #include "ultrasonic.h") C P9 X! n! \, r( J: G# d #include "USART.h"4 p) `! I$ |2 j* C int main(void). o( K. I' |2 [1 H6 p {4 I9 H3 j- b) |) Q+ b' B) ` /*模块初始化*/ OLED_Init(); //OLED初始化0 B% b# z; H( V0 _% ^; V' o# o6 y% c Ultrasonic_Init(); //超声波初始化7 Q3 N7 w& m$ H( r! T2 _ USART1_Init(115200); //串口初始化(115200 8N1) /*OLED显示*/( i) k# F* X( L. O0 A& [ OLED_Clear();( O$ _; W9 ~; a& w9 g OLED_ShowString(1, 1, "Ultrasonic:"); 6 r4 I. S+ G2 {4 H while (1)# X2 w) p/ R3 f+ v& X4 G7 h) ]$ ` {0 t$ m" U% }- j4 I H5 a float dist_cm = UltrasonicGetLength();% W8 x/ [5 i$ ~4 x OLED_ShowString(2, 1, "Dist(cm): ");; `8 Z3 _" L, _! x { uint32_t d10 = (uint32_t)(dist_cm * 10.0f + 0.5f); // 四舍五入到一位小数8 t2 i! t( n/ K" ]! P uint32_t intPart = d10 / 10; uint32_t fracPart = d10 % 10; OLED_ShowNum(2, 11, intPart, 4);3 _: y8 E* j/ C. N, ^; n OLED_ShowChar(2, 15, '.'); OLED_ShowNum(2, 16, fracPart, 1); // 串口输出:如 123.4cm\r\n" Q: Q% a1 E$ m1 E USART1_SendString("dist="); USART1_SendNumber(intPart);$ x8 a5 i$ K- t$ |# Z* U% d7 k: t# ? USART1_SendChar('.'); C: N- p' q7 A0 o8 |. E+ g USART1_SendNumber(fracPart); USART1_SendString("cm\r\n"); } Delay_ms(200); }, ?% X! j8 U! N( Y7 F% ?3 G } 5 s3 R* g% S) ^" y$ n6 R0 g 5. 常见问题与排错 无法编译,提示 stm32f10x.h 找不到: 确认 Keil 工程 C/C++ Include Path 包含 ./Start; ./Library; ./User; ./System; ./Hardware。 USART1_Init 等函数隐式声明:( O9 Y) k I% \: h 确认 User/main.c 已包含 #include "USART.h"。# V) N; ]) Q' m7 v# q& e" ?/ d2 h 电脑无数据: 检查波特率设置一致;检查 TX 线连接是否正确,GND 是否共地。 若只接 TX/GND,PC 只能接收;如需从 PC 发回 MCU,再接 RX。 波特率更改: 将 USART1_Init(115200) 替换为所需值(如 9600),PC 工具一并修改。 6. 可选增强 W4 T( S4 V4 l8 v 增加 printf 重定向到 USART,便于调试。) w s# ]: _- _ 加环形缓冲区与中断接收,支持命令解析与上位机交互。 采用 DMA 发送以降低占用。% c/ J; P8 }9 n o |
STM32L562DK探索板——串口通讯测试成功
STM32L562DK探索板——再试串口通讯仍不成
实战经验 | 基于STM32G0B1的全桥移相+同步整流PWM解决方案
STM32L562DK探索板——串口通讯的再测试
STM32L562DK探索板——串口通讯的测试
STM32L562DK探索板——运动传感器测试
STM32L562DK探索板——继续深入了解Audio Play的工作流程
STM32L562DK探索板——触摸菜单实验之触摸测试
STM32L562DK探索板——触摸菜单实验之LED闪烁
STM32L562DK探索板——Audio Play的再了解
微信公众号
手机版