当前位置: 首页 > news >正文

用STM32F103C8T6和串口通信,5分钟搞定一个简易红绿灯控制原型(附完整代码)

用STM32F103C8T6实现串口控制红绿灯原型开发指南

1. 项目概述与硬件准备

红绿灯控制系统是嵌入式开发的经典入门项目,能帮助初学者快速掌握GPIO控制和串口通信两大核心技能。我们选用STM32F103C8T6这款性价比极高的ARM Cortex-M3内核开发板,它内置丰富的外设资源,特别适合教学演示和小型原型开发。

所需硬件清单

  • STM32F103C8T6最小系统板(蓝色PCB版)
  • USB转TTL串口模块(推荐CH340G芯片)
  • 红黄绿LED各两个(共6个LED)
  • 220Ω限流电阻(6个)
  • 面包板和杜邦线若干

提示:购买开发板时注意区分正版(丝印清晰)和山寨版(可能存在USB接口问题)。LED建议选择3mm直径的,亮度适中且方便观察。

2. 开发环境搭建

2.1 软件工具链配置

对于STM32开发,我们推荐使用以下免费工具组合:

  1. Keil MDK-ARM:注册后即可获得32KB代码限制的免费版本
  2. ST-Link驱动:用于程序烧录和调试
  3. 串口调试助手:推荐使用SSCOM或Putty

安装步骤:

# ST-Link驱动安装示例(Windows) 1. 下载STSW-LINK009驱动包 2. 以管理员身份运行dpinst_amd64.exe 3. 连接开发板后应在设备管理器看到"STMicroelectronics STLink dongle"

2.2 工程模板创建

在Keil中新建工程的正确姿势:

  1. 选择Device为"STM32F103C8"
  2. 添加启动文件startup_stm32f10x_md.s
  3. 配置Target选项:
    • 勾选"Use MicroLIB"(简化串口打印)
    • 设置ROM地址为0x8000000,Size为64KB
    • 设置RAM地址为0x20000000,Size为20KB

3. 硬件电路设计

3.1 LED连接方案

采用共阳极接法,通过STM32的GPIO输出低电平点亮LED:

LED颜色GPIO引脚对应交通灯
红色PA0南北方向
黄色PA1南北方向
绿色PA2南北方向
红色PB0东西方向
黄色PB1东西方向
绿色PB2东西方向

电路连接注意事项:

  • 每个LED串联220Ω电阻防止过流
  • 开发板的3.3V电源作为共阳极端
  • 确保GND共地连接

3.2 串口通信配置

使用USART1与PC通信,接线方式:

开发板引脚USB-TTL模块
PA9(TX)RX
PA10(RX)TX
GNDGND

配置参数:115200波特率,8数据位,无校验,1停止位

4. 核心代码实现

4.1 GPIO初始化

void LED_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE); // 配置PA0-PA2为推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置PB0-PB2为推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2; GPIO_Init(GPIOB, &GPIO_InitStructure); // 初始状态全部熄灭 GPIO_SetBits(GPIOA, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2); GPIO_SetBits(GPIOB, GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2); }

4.2 串口初始化与中断配置

void USART1_Init(void) { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); // 配置PA9为复用推挽输出(TX) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置PA10为浮空输入(RX) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); // USART参数配置 USART_InitStructure.USART_BaudRate = 115200; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); // 使能接收中断 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 配置NVIC NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); USART_Cmd(USART1, ENABLE); }

4.3 红绿灯状态机实现

定义三种基本控制模式:

  1. 定时自动切换:固定时间间隔循环
  2. 串口指令控制:通过PC发送命令切换
  3. 紧急模式:所有方向红灯
typedef enum { MODE_AUTO, MODE_MANUAL, MODE_EMERGENCY } TrafficMode; void TrafficLight_Update(void) { static uint32_t lastTick = 0; static uint8_t state = 0; if(HAL_GetTick() - lastTick < 1000) return; lastTick = HAL_GetTick(); switch(currentMode) { case MODE_AUTO: // 状态自动切换逻辑 switch(state) { case 0: // 南北绿灯,东西红灯 GPIO_ResetBits(GPIOA, GPIO_Pin_2); // 南北绿 GPIO_SetBits(GPIOA, GPIO_Pin_0); GPIO_ResetBits(GPIOB, GPIO_Pin_0); // 东西红 GPIO_SetBits(GPIOB, GPIO_Pin_2); state = 1; break; case 1: // 南北黄灯,东西红灯 GPIO_SetBits(GPIOA, GPIO_Pin_2); GPIO_ResetBits(GPIOA, GPIO_Pin_1); // 南北黄 state = 2; break; // 其他状态类似... } break; case MODE_EMERGENCY: // 全方向红灯 GPIO_ResetBits(GPIOA, GPIO_Pin_0); GPIO_ResetBits(GPIOB, GPIO_Pin_0); GPIO_SetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2); GPIO_SetBits(GPIOB, GPIO_Pin_1 | GPIO_Pin_2); break; } }

5. 调试技巧与常见问题

5.1 串口通信调试

当串口无法正常工作时,按以下步骤排查:

  1. 检查接线是否正确(TX-RX交叉连接)
  2. 确认波特率设置一致
  3. 测量TXD引脚是否有波形输出
  4. 检查代码中USART时钟是否使能

5.2 LED不亮的可能原因

  • GPIO配置模式错误(应为推挽输出)
  • 限流电阻值过大导致亮度不足
  • 共阳/共阴接法混淆
  • 引脚复用功能未正确配置

5.3 程序下载失败处理

典型错误及解决方案:

错误现象可能原因解决方法
No target connected驱动未安装或连接不稳定重新插拔ST-Link,检查驱动
Flash timeout复位电路异常按住复位键再点击下载
Option bytes error读保护使能使用ST-Link Utility解除保护

6. 项目扩展思路

基础版本实现后,可以考虑以下增强功能:

  • 添加按键控制:通过开发板上的用户按键切换模式
  • OLED状态显示:使用I2C接口的OLED屏显示当前状态
  • 无线控制:通过蓝牙模块(如HC-05)实现手机控制
  • 车流量检测:外接红外传感器统计车辆通过数量

进阶开发建议:

// 示例:使用PWM实现灯光渐亮渐灭效果 void LED_PWM_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 配置PA1为复用推挽输出(TIM2_CH2) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 定时器基础配置 TIM_TimeBaseStructure.TIM_Period = 999; // 1kHz PWM TIM_TimeBaseStructure.TIM_Prescaler = 71; // 72MHz/72 = 1MHz TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); // PWM模式配置 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 500; // 初始占空比50% TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC2Init(TIM2, &TIM_OCInitStructure); TIM_Cmd(TIM2, ENABLE); }
http://www.jsqmd.com/news/562116/

相关文章:

  • Agent Skills 2.0:小白也能玩转的 AI 技能工程化指南
  • 年薪百万!AI Agent工程师:下一个风口职业,你准备好了吗?
  • Linux环境下Ollama离线部署全攻略
  • 【大英赛】全国大学生英语竞赛C类历年真题、样卷、听力音频及答案解析电子版PDF(2012-2026年)
  • Memcached delete 命令详解
  • 三. STM32 RCC时钟系统
  • 打造个性化鼠标指针:Bibata_Cursor主题全攻略
  • 终极指南:如何使用AutoML与TPOT工具实现自动化机器学习
  • 2026年软考全攻略:报名+备考+选科一文看懂
  • UniHacker:实现Unity全功能解锁的跨平台解决方案
  • 零门槛视频创作:OpenCut高效替代方案全解析
  • PPT制作网站大揭秘:轻松告别PPT噩梦 - 品牌测评鉴赏家
  • 告别API文档混乱:Swagger UI与Git集成的5个实战技巧
  • 如何使用USearch实现图像生成的检索增强:提示词相似性匹配完整指南
  • FinalBurn Neo终极指南:免费开源街机模拟器带你重温经典街机游戏
  • Practical Modern JavaScript快速入门:从零开始掌握现代JS开发
  • 基于树莓派的停车场车牌识别系统
  • CloudCompare进阶指南:PoissonRecon点云重建实战技巧
  • PPT生成网站大揭秘:打工人的效率神器 - 品牌测评鉴赏家
  • Flutter Go终极指南:140+组件库的完整开发实战教程
  • 终极Substrate开发环境搭建指南:从源码编译到IDE配置的完整步骤
  • STM32的ADC采集总是不准?手把手调试MQ135传感器数据(F407 HAL库实战)
  • Qwen3.5-4B辅助微信小程序开发:智能客服与内容生成功能实现
  • 六自由度机器人:重力补偿控制策略的研究与应用
  • AutoGLM-Phone-9B快速上手:图文语音全能AI,小白也能轻松部署
  • 百考通:AI智能化赋能开题报告,让学术研究起步更高效
  • Windows 10 USB鼠标失灵:驱动、电源问题排查指南
  • Phi-3-Mini-128K代码实例:扩展支持Markdown渲染与代码块语法高亮
  • 2026年广州吉时雨建筑咨询有限公司官方联系方式公示,建筑行业人才与企业综合服务合作便捷入口 - 第三方测评
  • Microsoft.Extensions.Http.Resilience实战:构建弹性的HTTP客户端的完整指南