|
本节详细说明如何在本项目中新增串口通信,将超声波距离 dist_cm 通过 USART1 发送到电脑串口。# H( ~3 y6 n! K+ \2 z 1. 目标与环境 MCU: STM32F103C8T6 串口: USART1 (PA9 TX, PA10 RX) 波特率: 115200 8N1(无校验,无流控) 工具链: Keil MDK / ARMCC 5.06* k$ {9 E1 u+ N' k4 U4 a1 _7 R& Q 2. 新增文件 头文件与实现放在 Hardware/ 目录:. d. P s" N: Z& j4 | #ifndef __USART_H, Z' q) U6 l' s+ Y2 j #define __USART_H #include "stm32f10x.h" #include <stdint.h> 0 I0 q. H# `4 U void USART1_Init(uint32_t baudrate);: k9 B+ X8 e* [, G8 b! t2 T. ~ void USART1_SendChar(char c);: V! V! U: ?4 ` void USART1_SendString(const char *s);; j% C. \! U. Z! E. P6 K- `% q void USART1_SendNumber(uint32_t num); #endif) e! A6 a1 E' D/ z+ {/ } 0 e/ U3 K/ `: Q0 q , y5 k! t- h" }$ _0 O# w* H #include "USART.h": v8 k1 t4 L# I& s$ O 5 l1 J' e+ Y. D( |6 |6 a, [" }1 u void USART1_Init(uint32_t baudrate) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE);% H5 B" Y/ J% L- S- h% `2 ^7 P GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; // PA9 TX- S, _' p d$ G# N3 Z$ O: | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;" |# K1 f- P" ]( G# n* N9 w GPIO_Init(GPIOA, &GPIO_InitStructure);2 E8 P7 x/ N E9 q GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; // PA10 RX GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = baudrate; USART_InitStructure.USART_WordLength = USART_WordLength_8b;) s% W* ^# g: L5 ~: }; @/ k) k5 L USART_InitStructure.USART_StopBits = USART_StopBits_1;0 s( E$ W7 M% ]( R USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;! k5 g0 W& b& A2 p7 p$ f+ q/ U0 {$ Y USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(USART1, &USART_InitStructure);. Y/ ?& i9 `, `+ H - H+ _8 d6 ^! b+ z% {4 l USART_Cmd(USART1, ENABLE);6 O' E6 j7 V+ h8 Q4 Q4 z } void USART1_SendChar(char c) {: F8 Q/ O( B1 U while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);: u: G8 ^" B. P( w USART_SendData(USART1, (uint16_t)c); } & _2 x$ B* V* T& \0 l" g( j" G6 w, { void USART1_SendString(const char *s)1 n: @, G! ~3 F; X ]3 F { while (*s) { USART1_SendChar(*s++); }. T4 U; e4 Y6 [* C' [) L3 [ } void USART1_SendNumber(uint32_t num)6 V# _' Q4 F9 j# W; V/ U { char buf[12]; int i = 0, j = 0; char tmp; if (num == 0) {- F ^! q5 d2 e# R USART1_SendChar('0');9 j% \$ c% w5 r" X$ a" E+ Q return; }1 i7 j; L3 A. I while (num > 0 && i < (int)(sizeof(buf)))' n" T1 [- W3 ]1 |8 H {3 v+ i) y1 J- ^ _ buf[i++] = (char)('0' + (num % 10)); num /= 10;. }0 z! Z: \: V* _4 x8 T } for (j = 0; j < i / 2; j++) { tmp = buf[j]; buf[j] = buf[i - 1 - j]; buf[i - 1 - j] = tmp;" s+ V1 d0 ]) h, A3 k }& B$ Z7 w# U" d0 Q( B! p) p. n for (j = 0; j < i; j++)+ }2 d' W0 i" F: r/ {+ H { USART1_SendChar(buf[j]);5 I, a% n6 g1 }! _3 @ }; B% p- A8 U6 K0 c }7 P: `. R* W Q( j1 {1 s% u , }0 R2 j6 D1 r+ U) R" A q7 N- W5 C) \$ g7 B2 O, A 将上述两个文件添加进 Keil 工程:Project.uvprojx → Hardware 组已加入 USART.c/.h(如未加入,请在工程里右键组名 → Add Existing Files…)。3 n+ C; A$ R% e' m, } L! e/ h; c 3. 硬件连接 PA9 → USB 转串口模块 RX(注意是对接到对方的 RX) PA10 ← USB 转串口模块 TX(如仅发送可不接) GND ↔ GND 共地 串口工具设置:波特率 115200,8-N-1,无流控。 4. 在 main 中初始化与发送 在 User/main.c 中包含头文件并初始化串口,同时将距离通过串口发送到 PC。/ [- q4 D1 m3 A0 P4 y #include "stm32f10x.h" // Device header5 L. z1 r. o. J; D+ G #include "Delay.h"0 Q2 B' s/ D* v+ K1 z #include "OLED.h" #include "ultrasonic.h"# G! D. A- N1 K1 `% J1 {8 y #include "USART.h" int main(void). D$ `+ D# ]( D) M: i9 o {7 [1 R; Y9 f5 w. @& B/ I& K6 C /*模块初始化*/ OLED_Init(); //OLED初始化: F# a) c/ l- N) H- P- |- E# X" t- P Ultrasonic_Init(); //超声波初始化 USART1_Init(115200); //串口初始化(115200 8N1) /*OLED显示*/7 a3 ]" v6 {2 q }! {7 [: P OLED_Clear(); OLED_ShowString(1, 1, "Ultrasonic:");2 K1 s7 k0 [9 ? q( o while (1) { float dist_cm = UltrasonicGetLength(); OLED_ShowString(2, 1, "Dist(cm): "); {# N( D- ?! o. `$ L4 @ uint32_t d10 = (uint32_t)(dist_cm * 10.0f + 0.5f); // 四舍五入到一位小数& |3 A, X( f. Q# |# Z t5 l) @0 \ uint32_t intPart = d10 / 10; uint32_t fracPart = d10 % 10; OLED_ShowNum(2, 11, intPart, 4); OLED_ShowChar(2, 15, '.');9 [7 Z% L" g5 E! {% {0 Y OLED_ShowNum(2, 16, fracPart, 1);: l# k3 b: X; c$ I# x. @: y8 L; J // 串口输出:如 123.4cm\r\n USART1_SendString("dist="); USART1_SendNumber(intPart);- a6 L% `" C, S USART1_SendChar('.'); USART1_SendNumber(fracPart); USART1_SendString("cm\r\n");/ h' g3 U; g9 ~3 D% t2 Y7 f) t }! X" e& I) j) o: N( P Delay_ms(200);% B& D, k5 B' s/ F }2 }0 G: o5 j# M; `! m$ k } ) m& d- F' r3 d# k8 f ` 5. 常见问题与排错 O# Q5 g$ b1 O0 h 无法编译,提示 stm32f10x.h 找不到:' x+ ~3 z6 O: r' X' _' |" X3 \5 f 确认 Keil 工程 C/C++ Include Path 包含 ./Start; ./Library; ./User; ./System; ./Hardware。 USART1_Init 等函数隐式声明: 确认 User/main.c 已包含 #include "USART.h"。 电脑无数据:2 x4 o% y. Y9 F 检查波特率设置一致;检查 TX 线连接是否正确,GND 是否共地。 若只接 TX/GND,PC 只能接收;如需从 PC 发回 MCU,再接 RX。0 B5 u. \2 G2 y: o 波特率更改:; P# b. l! U7 K6 z- Z 将 USART1_Init(115200) 替换为所需值(如 9600),PC 工具一并修改。3 u6 R+ R$ t' j 6. 可选增强 增加 printf 重定向到 USART,便于调试。 加环形缓冲区与中断接收,支持命令解析与上位机交互。 采用 DMA 发送以降低占用。 |
STM32L562DK探索板——串口通讯测试成功
STM32L562DK探索板——再试串口通讯仍不成
实战经验 | 基于STM32G0B1的全桥移相+同步整流PWM解决方案
STM32L562DK探索板——串口通讯的再测试
STM32L562DK探索板——串口通讯的测试
STM32L562DK探索板——运动传感器测试
STM32L562DK探索板——继续深入了解Audio Play的工作流程
STM32L562DK探索板——触摸菜单实验之触摸测试
STM32L562DK探索板——触摸菜单实验之LED闪烁
STM32L562DK探索板——Audio Play的再了解
微信公众号
手机版