1. 项目概述
作为一名嵌入式开发工程师,我最近完成了一个基于STM32的简易出租车计费系统设计项目。这个系统虽然结构简单,但完整实现了出租车计费的核心功能,包括时间模拟计费、费用显示和模式切换等。下面我将详细介绍这个项目的设计思路、实现过程和关键细节。
这个计费系统的核心功能包括:
- 使用定时器模拟行驶时间
- 前三秒固定收费8元,之后每增加一秒费用增加1元
- 数码管显示费用和时间
- 按键切换显示模式
- 蜂鸣器按键提示音
2. 硬件设计解析
2.1 主控芯片选型
我选择了STM32F103C8T6作为主控芯片,主要基于以下几点考虑:
- 性价比高:这款芯片价格适中,性能足够满足本项目需求
- 丰富的外设:内置多个定时器,可以精确控制时间
- 开发资源丰富:有成熟的开发工具链和大量参考例程
提示:STM32F103系列是STM32的经典入门型号,对于初学者来说学习曲线相对平缓。
2.2 显示模块设计
显示部分采用了4位共阳数码管配合74HC138译码器驱动。这种设计方案的优点在于:
- 硬件成本低
- 驱动电路简单
- 显示效果清晰明亮
数码管显示内容分为两种模式:
- 计费模式:显示当前费用(格式:XX.XX元)
- 时间模式:显示行驶时间(格式:XXXX秒)
2.3 按键与蜂鸣器电路
系统设置了两个按键:
- 开始/暂停按键:控制计费开始和暂停
- 模式切换按键:在费用显示和时间显示之间切换
每个按键按下时,蜂鸣器会发出短暂的提示音,提供操作反馈。蜂鸣器采用无源蜂鸣器,通过PWM信号驱动。
3. 软件设计实现
3.1 系统初始化
系统上电后,首先进行硬件初始化:
c复制void System_Init(void)
{
HAL_Init(); // HAL库初始化
SystemClock_Config(); // 系统时钟配置
MX_GPIO_Init(); // GPIO初始化
MX_TIM2_Init(); // 定时器2初始化
MX_TIM3_Init(); // 定时器3初始化
Buzzer_Init(); // 蜂鸣器初始化
Display_Init(); // 显示初始化
}
3.2 主程序设计
主程序采用状态机设计,主要流程如下:
- 检测按键状态
- 根据按键动作更新系统状态
- 计算当前费用
- 刷新数码管显示
c复制while (1)
{
Key_Scan(); // 按键扫描
switch(systemState)
{
case IDLE:
// 待机状态处理
break;
case RUNNING:
// 运行状态处理
Calculate_Fare(); // 费用计算
break;
case PAUSED:
// 暂停状态处理
break;
}
Display_Refresh(); // 显示刷新
HAL_Delay(10); // 延时10ms
}
3.3 费用计算算法
费用计算是本项目的核心算法,实现逻辑如下:
c复制void Calculate_Fare(void)
{
uint32_t currentTime = Get_Elapsed_Time(); // 获取已行驶时间
if(currentTime <= 3) // 前3秒
{
currentFare = 800; // 固定收费8元(单位:分)
}
else // 3秒后
{
currentFare = 800 + (currentTime - 3) * 100; // 每增加1秒加1元
}
}
4. 关键问题与解决方案
4.1 数码管显示闪烁问题
在初期测试中,发现数码管显示存在闪烁现象。经过分析,原因是刷新频率过低。解决方法:
- 提高定时器中断频率
- 优化显示刷新算法
- 确保每个数码管的点亮时间均匀
最终将显示刷新频率提高到200Hz,完全消除了闪烁现象。
4.2 定时器精度问题
使用STM32的定时器时,需要注意:
- 定时器时钟配置要正确
- 中断优先级设置合理
- 定时器溢出处理要完善
本项目使用TIM2作为系统计时基准,配置为1kHz频率,通过软件计数器扩展计时范围。
4.3 按键消抖处理
机械按键存在抖动问题,会导致误触发。解决方法:
c复制uint8_t Key_Scan(void)
{
static uint8_t keyState = 0;
uint8_t keyValue = HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin);
if(keyValue == 0) // 按键按下
{
if(keyState == 0)
{
HAL_Delay(20); // 延时消抖
if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == 0)
{
keyState = 1;
return 1; // 返回有效按键
}
}
}
else
{
keyState = 0;
}
return 0;
}
5. 系统测试与优化
5.1 功能测试
测试项目包括:
- 基本计费功能测试
- 显示切换功能测试
- 按键响应测试
- 长时间运行稳定性测试
测试结果表明,系统各项功能均达到设计要求,计费准确,显示清晰,操作响应及时。
5.2 性能优化
在保证功能完整的前提下,我对系统进行了以下优化:
- 降低功耗:在空闲状态关闭不必要的外设
- 提高响应速度:优化中断处理流程
- 增强稳定性:增加看门狗定时器
6. 项目扩展思考
这个基础版本完成后,还可以考虑以下扩展功能:
- 增加实际里程传感器,实现真实里程计费
- 添加GPS模块,实现基于位置的计费规则
- 集成无线通信模块,实现远程数据上传
- 增加打印功能,提供乘车票据
在实际开发过程中,我发现STM32的HAL库虽然方便,但在某些情况下效率不如直接操作寄存器。对于时间要求严格的场合,可以考虑混合使用HAL库和寄存器操作。