1. 项目概述与核心功能解析
这个基于51单片机的公交报站系统设计,是我在智能交通领域的一次完整实践。整套方案包含硬件仿真、C语言程序、设计报告和操作演示视频四大模块,实现了公交车运行中最关键的自动报站功能。
系统最突出的特点是支持按键设置上行/下行方向。实际公交运营中,同一线路往返方向站点顺序相反,传统方案需要存储两套语音数据。而本设计通过方向判断逻辑,仅用一套语音文件就实现了双向报站,大幅降低了存储空间占用。
提示:Proteus仿真环境下测试时,务必注意晶振频率设置需与程序代码一致,否则会导致定时器计时不准,影响语音播放时序。
2. 系统架构设计思路
2.1 硬件组成框图
整个系统以STC89C52RC单片机为核心,外围电路包含:
- 按键矩阵(4×4矩阵键盘)
- LCD1602显示屏
- ISD1820语音模块
- LED方向指示灯
- 蜂鸣器提示音电路
在Proteus中的元件选择依据:
- 单片机选用兼容性最好的STC89C52RC模型
- 语音模块用Sounder元件模拟
- 显示部分采用通用LCD模块
- 按键使用BUTTON配合上拉电阻
2.2 软件流程设计
主程序采用状态机架构,包含三个核心状态:
- 待机状态:显示当前站点和方向
- 报站触发状态:检测到站点变更信号
- 设置状态:通过按键修改运行参数
状态转换逻辑如下图所示(伪代码):
c复制while(1) {
switch(current_state) {
case STANDBY:
if(KEY_DETECTED) enter_setting();
if(STATION_CHANGED) enter_announce();
break;
case ANNOUNCE:
play_voice();
update_display();
break;
case SETTING:
process_key_input();
break;
}
}
3. 核心功能实现细节
3.1 方向判断逻辑实现
系统通过一个bit标志位存储当前方向:
c复制bit direction_flag; // 0:上行 1:下行
站点数据存储在结构体数组中,每个元素包含:
c复制struct Station {
char name[16];
uint8_t voice_segment;
uint8_t next_up;
uint8_t next_down;
};
报站时根据方向选择下一站点:
c复制uint8_t get_next_station(uint8_t current) {
return direction_flag ?
station_list[current].next_down :
station_list[current].next_up;
}
3.2 语音播放控制
使用ISD1820模块时需注意:
- 每个语音片段需要单独录制为.wav文件
- 文件命名规则为SXX.wav(XX为站点编号)
- 播放控制时序:
c复制void play_voice(uint8_t seg) {
P1 = seg; // 输出片段编号
PLAY = 0; // 触发播放
delay(10);
PLAY = 1;
while(!BUSY); // 等待播放结束
}
3.3 按键扫描优化
采用行列扫描法时,加入了去抖处理:
c复制uint8_t key_scan() {
static uint8_t last_key = 0xFF;
uint8_t raw_key = get_raw_key();
if(raw_key != last_key) {
delay(20); // 去抖延时
if(raw_key == get_raw_key()) {
last_key = raw_key;
return raw_key;
}
}
return 0xFF;
}
4. Proteus仿真要点
4.1 关键仿真参数设置
- 单片机属性:
- Clock Frequency: 11.0592MHz
- 勾选"Load HEX File"
- 语音模块:
- 添加所有语音WAV文件
- 设置采样率为8kHz
- 调试配置:
- 启用8051 UART
- 设置波特率9600
4.2 常见仿真问题排查
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| LCD不显示 | 对比度设置不当 | 调节V0引脚电压 |
| 语音不同步 | 晶振频率不匹配 | 检查代码和仿真设置 |
| 按键无响应 | 上拉电阻缺失 | 添加10kΩ上拉电阻 |
| 显示乱码 | 初始化时序错误 | 增加LCD初始化延时 |
5. 实际应用中的经验技巧
-
语音录制技巧:
- 使用Audacity录制时选择单声道
- 采样率设为8kHz可节省空间
- 每个片段开头留0.5秒静音
-
功耗优化方案:
c复制void enter_low_power() { PCON |= 0x01; // 进入空闲模式 // 通过外部中断唤醒 } -
扩展功能建议:
- 添加GPS模块实现自动报站
- 增加蓝牙配置接口
- 支持TF卡存储更多语音
在真实公交环境中测试时,发现语音模块需要做防震处理,否则车辆颠簸会导致接触不良。后来改用热熔胶固定连接器后稳定性大幅提升。
6. 完整代码结构解析
项目代码采用模块化设计:
code复制├── main.c // 主状态机逻辑
├── key.c // 按键处理
├── lcd1602.c // 显示驱动
├── voice.c // 语音控制
├── station.c // 站点数据
└── config.h // 硬件配置
关键初始化流程:
c复制void hardware_init() {
LCD_Init(); // 显示屏初始化
Voice_Init(); // 语音模块准备
Timer0_Init(); // 定时器配置
EA = 1; // 开启总中断
}
定时器中断服务程序负责站点计时:
c复制void Timer0_ISR() interrupt 1 {
static uint16_t counter = 0;
TH0 = 0xDC; TL0 = 0x00; // 重装10ms定时
if(++counter >= 100) { // 1秒到达
counter = 0;
if(auto_mode) station_timer++;
}
}
7. 项目文档编写要点
技术报告应包含:
- 需求分析:明确功能指标
- 硬件设计:电路原理图+说明
- 软件设计:流程图+关键代码
- 测试方案:仿真与实际测试对比
- 改进方向:后续优化建议
演示视频拍摄技巧:
- 先展示整体硬件连接
- 重点拍摄按键操作和语音响应
- 最后展示Proteus仿真同步运行
- 添加字幕说明关键操作步骤
在项目验收时,评委特别关注了方向切换的实时性表现。我们通过预加载下一站点语音数据,将切换延迟控制在300ms以内,这个优化细节最终获得了额外加分。