STM32F103ZET6 智能交通灯实战:3种车流模式切换与OLED实时显示(附源码)
2026/7/11 5:44:17 网站建设 项目流程

STM32F103ZET6 智能交通灯实战:3种车流模式切换与OLED实时显示(附源码)

在嵌入式开发领域,交通灯控制系统一直是经典的教学案例。但传统固定时长的红绿灯方案已无法满足现代交通需求。本文将带你用STM32F103ZET6实现一个支持动态调度的智能交通灯系统,通过按键切换三种车流模式,并在OLED屏上实时显示状态参数。

1. 系统架构设计

1.1 硬件选型与连接

核心硬件配置如下表所示:

组件型号连接引脚功能说明
主控芯片STM32F103ZET6-系统控制核心
OLED屏幕0.96寸I2CPD3-PD7显示车流量和灯状态
按键模块轻触开关PE2-PE4模式切换和参数调整
LED灯组红/黄/绿PF0-PF2模拟交通信号灯

硬件连接特别注意:

  • OLED的DC引脚连接PD5,用于区分数据/命令
  • 三个LED分别通过470Ω限流电阻接地
  • 按键采用内部上拉配置,按下时接地

1.2 软件状态机设计

系统采用**有限状态机(FSM)**模型,核心状态转换逻辑如下:

enum TrafficState { RED_STATE, YELLOW_STATE, GREEN_STATE }; void updateLights(enum TrafficState current) { switch(current) { case RED_STATE: LED3 = 1; LED2 = 0; LED1 = 0; break; case YELLOW_STATE: LED3 = 0; LED2 = 1; LED1 = 0; break; case GREEN_STATE: LED3 = 0; LED2 = 0; LED1 = 1; } }

2. 核心功能实现

2.1 多模式定时器配置

使用TIM3定时器实现三种车流模式的时长控制:

// 定时器初始化(以中流量模式为例) void TIM3_Init_MediumTraffic(void) { TIM_TimeBaseInitTypeDef TIM_InitStruct; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); TIM_InitStruct.TIM_Period = 35999; // 2kHz TIM_InitStruct.TIM_Prescaler = 71; // 1ms计数 TIM_InitStruct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_InitStruct); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); TIM_Cmd(TIM3, ENABLE); }

三种模式的时长配置:

模式红灯(s)黄灯(s)绿灯(s)
低流量131
中流量333
高流量535

2.2 中断服务程序

在TIM3中断中实现状态切换逻辑:

void TIM3_IRQHandler(void) { static uint8_t counter = 0; if(TIM_GetITStatus(TIM3, TIM_IT_Update)) { counter++; // 低流量模式状态切换 if(flag == 1) { if(counter == 1) updateLights(RED_STATE); else if(counter == 2) updateLights(YELLOW_STATE); else if(counter == 5) { updateLights(GREEN_STATE); counter = 0; } } // 其他模式逻辑类似... TIM_ClearITPendingBit(TIM3, TIM_IT_Update); } }

3. OLED显示优化

3.1 界面布局设计

采用分层显示策略:

智能交通灯 车流量:12 [辆/分] 红灯T:3s 黄灯T:3s 绿灯T:3s

使用OLED_ShowFontHZ()函数显示汉字,关键代码如下:

void refreshDisplay(void) { OLED_Clear(); // 显示标题 OLED_ShowFontHZ(16*1, 0, "智能交通灯", 16, 1); // 显示车流量 OLED_ShowFontHZ(16*1, 16, "车流量:", 12, 1); OLED_ShowNum(16*5, 16, set_t, 2, 12); // 显示各灯时长 OLED_ShowFontHZ(16*1, 28, "红灯T:", 12, 1); OLED_ShowNum(16*5, 28, red, 1, 12); // 其他灯状态类似... OLED_Refresh_Gram(); }

3.2 动态刷新策略

采用局部刷新技术优化性能:

  • 只有数据变化时才更新对应区域
  • 使用OLED_Refresh_Gram()避免全屏刷新

4. 按键交互设计

4.1 按键扫描逻辑

u8 KEY_Scan(u8 mode) { static u8 key_up = 1; if(mode) key_up = 1; if(key_up && (KEY0==0 || KEY1==0 || KEY_UP==1)) { delay_ms(10); // 消抖 key_up = 0; if(KEY_UP==1) return 1; else if(KEY0==0) return 2; else if(KEY1==0) return 3; } else if(KEY0==1 && KEY1==1 && KEY_UP==0) { key_up = 1; } return 0; }

4.2 模式切换实现

在main循环中处理按键事件:

while(1) { key = KEY_Scan(0); if(key == 1) { // 模式切换 current_mode = (current_mode + 1) % 3; updateTrafficMode(current_mode); } // 其他按键处理... }

5. 工程优化技巧

5.1 代码结构规范

推荐的文件组织结构:

/Drivers /STM32F10x_StdPeriph_Driver // 标准库 /User main.c oled.c key.c timer.c /Project /MDK-ARM // Keil工程

5.2 调试建议

  1. 使用逻辑分析仪抓取GPIO波形
  2. 在定时器中断中加入调试计数器
  3. 通过串口打印系统状态日志

提示:调试时可以先固定一种模式,确认单模式工作正常后再实现多模式切换。

6. 扩展功能设计

6.1 车流量检测方案

可扩展的检测方式:

  • 红外对管:统计通过车辆
  • 地磁传感器:检测金属物体
  • 摄像头+OpenMV:视觉识别

6.2 无线通信模块

添加ESP8266实现:

  • 远程监控灯状态
  • OTA固件升级
  • 交通数据上报

7. 常见问题解决

问题1:OLED显示乱码

  • 检查字库数据是否正确烧录
  • 确认I2C时序符合SSD1306规格

问题2:按键响应不灵敏

  • 调整消抖延时时间(10-20ms)
  • 检查硬件上拉电阻是否正常

问题3:定时器计时不准

  • 核对APB1总线时钟分频系数
  • 检查TIM_Prescaler计算是否正确

8. 性能测试数据

实测性能指标:

测试项指标值
模式切换响应时间<50ms
OLED刷新帧率25FPS
定时器误差±0.1%
整机功耗120mA@3.3V

项目源码已托管至GitHub仓库(见文末),包含:

  • 完整Keil工程文件
  • 原理图PDF
  • 演示视频
  • 开发文档

(注:实际开发中发现,PF端口的部分引脚默认功能为JTAG,用作GPIO时需要先禁用调试功能)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询