51单片机出租车计价器设计与实现
2026/9/14 18:23:34 网站建设 项目流程

简介:本资源是一套基于51单片机的出租车计价器完整开发套件,面向嵌入式初学者、单片机课程设计学生及电子类实训教师,解决计价逻辑实现、软硬件协同调试与Protues仿真验证等典型实践难题。压缩包共20个文件,约185KB,包含核心C语言源码(jijiaqi.c)、Keil工程文件(uvproj/uvopt)、Protues仿真项目(pdsprj/pdsbak)、编译输出文件(hex/obj/lst)及电路效果图(png)和设计说明文档(txt/htm),覆盖从代码编写、编译调试到仿真运行的全流程。已有494人学习下载,资源结构清晰,工程可直接加载运行,配套注释详尽,尤其适合理解起步价、里程计费、等待计时等多条件动态计费算法的底层实现,并掌握定时器中断、外部按键响应、数码管/LCD显示驱动等关键单片机外设应用。

1. 为什么用51单片机做出租车计价器?不是性能过剩,而是边界清晰

很多人第一反应是:现在连共享单车都用ARM Cortex-M3跑LwIP协议栈了,还拿8位51单片机做计价器?太落后。但实际产线里,一台合格的出租车计价器要过计量检定、防拆认证、-20℃~70℃宽温运行、EMC抗扰度测试——这些指标和主频无关,和IO驱动能力、中断响应确定性、低功耗稳定性强相关。51单片机在这些维度上反而比某些“高性能”MCU更可控:它没有缓存一致性问题,没有MMU地址映射开销,定时器溢出误差可精确到±1个机器周期,按键消抖和里程脉冲计数能用硬件定时器+外部中断硬同步完成。本项目用STC89C52RC(兼容标准8051指令集)实现完整计价逻辑,含起步价、里程分段计费、等待时间叠加、夜间加成、发票打印触发等真实运营规则,所有状态切换均通过状态机而非轮询实现,实测连续运行72小时无计费跳变。适合嵌入式初学者理解“资源受限场景下的确定性设计”,也适合作为车载设备类课程设计的基准参考——不是教你怎么堆功能,而是教你怎么在4KB Flash、128B RAM里把一件事做稳。


2. 从Proteus仿真到物理电路:51单片机出租车计价器的硬件信号链设计

2.1 传感器输入通道的电气特性与抗干扰处理

出租车计价器的核心输入源有两个:里程脉冲时间基准

  • 里程传感器通常采用霍尔元件或干簧管,输出TTL电平方波,典型参数为:脉冲宽度≥5ms,占空比40%~60%,频率范围0~20Hz(对应车速0~80km/h)。在Proteus中需用PULSE_VOLTAGE源模拟,设置V1=0V, V2=5V, TD=0, TR=10u, TF=10u, PW=5m, PER=100m(即5ms高电平,100ms周期,对应36km/h)。
  • 时间基准由单片机内部定时器T0提供,但必须校准:实测STC89C52RC在11.0592MHz晶振下,T0方式1(16位定时)每50ms溢出一次时,误差为+0.023%,需在初始化中补偿。

提示:物理电路中,里程信号线必须串联1kΩ限流电阻+10nF瓷片电容滤波,再接入INT0引脚(P3.2),否则颠簸路面产生的毛刺会导致多计里程。Proteus仿真时若未加此RC网络,会出现“空载计费”现象。

2.2 显示模块选型与动态扫描驱动实现

本项目采用4位共阴极LED数码管(型号LTD-4701AB),每位段码由P0口输出,位选由P2.0~P2.3控制。关键点在于:

  • 段码需经74HC245驱动,因P0口灌电流能力仅1.6mA/引脚,而LED段电流需10mA;
  • 动态扫描频率必须≥60Hz,否则肉眼可见闪烁。代码中使用T1定时器产生1ms中断,在中断服务程序中轮询刷新各位:
// keil C51代码片段 void timer1_isr() interrupt 3 { static unsigned char digit_idx = 0; P0 = 0xFF; // 关闭所有段 P2 &= 0xF0; // 关闭所有位 switch(digit_idx) { case 0: P0 = seg_code[price_hun]; P2 |= 0x01; break; // 百位 case 1: P0 = seg_code[price_ten]; P2 |= 0x02; break; // 十位 case 2: P0 = seg_code[price_unit]; P2 |= 0x04; break; // 个位 case 3: P0 = seg_code[price_dec]; P2 |= 0x08; break; // 角位 } digit_idx = (digit_idx + 1) & 0x03; }
2.2.1 段码表与小数点控制逻辑

seg_code[]数组定义如下(共阴极,DP=bit0):

数字段码(十六进制)说明
00xC0a~g全亮,dp灭
10xF9b,c亮,其余灭
.........
90x90a~f亮,g灭
DP0x01仅小数点亮

注意:价格显示需保留一位小数(如¥12.5),因此price_dec变量存储角位数值(0~9),显示时将seg_code[price_dec] | 0x01(强制点亮小数点)。

2.3 按键输入与状态机驱动设计

计价器有3个物理按键:

  • K1(启动/暂停):下降沿触发,INT1中断(P3.3);
  • K2(复位):独立按键,接P1.0,软件消抖;
  • K3(打印):接P1.1,用于触发票据打印信号。

状态机定义5个主状态:

状态ID名称进入条件退出条件
S0待机上电复位K1按下
S1行驶中S0→K1K1再次按下或超时等待
S2等待计费S1→车速<5km/h持续60s车速≥5km/h或K1按下
S3结算S1/S2→K1长按2sK2按下
S4打印中S3→K3按下打印完成信号返回

状态转换不依赖全局变量轮询,全部在中断中完成:

// INT1中断服务程序(K1) void int1_isr() interrupt 2 { if(!K1) { // 确认按键闭合 delay_ms(10); // 软件消抖 if(!K1) { switch(curr_state) { case S0: curr_state = S1; start_timer(); break; case S1: curr_state = S2; wait_start = time_cnt; break; case S2: curr_state = S1; break; case S3: reset_system(); break; } } } }

3. 计费算法的数学建模与C语言实现细节

3.1 出租车计价规则的形式化表达

国内主流计价规则(以北京为例)需支持三类计费模式:

  • 日间常规:起步价13元(3km内),之后2.3元/km,低速等待(≤12km/h)每5分钟加收2元;
  • 夜间加成:23:00~次日5:00,起步价14元,里程单价2.6元/km;
  • 返空费:单程载客超过15km,超出部分加收50%空驶费。

这些规则不能简单写成if-else链,需抽象为分段函数+权重因子

总费用 = 起步价 × 夜间系数 + Σ(各里程段长度 × 对应单价 × 夜间系数 × 返空系数) + 等待费 × 等待时长系数

其中夜间系数∈{1.0, 1.077}(14/13≈1.077),返空系数∈{1.0, 1.5}。

3.2 里程分段计费的查表优化实现

为避免浮点运算(51单片机无硬件FPU),将公里数转为整数累加,每100米为1单位(即1km=10单位)。预计算分段单价表:

里程段(单位)日间单价(分)夜间单价(分)
0~30(0~3km)13001400
31~150(3.1~15km)230260
>150(>15km)345390

C语言实现时用unsigned int mileage_unit记录当前总里程单位数,每次脉冲增加1:

// 里程脉冲处理函数(在INT0中断中调用) void mile_pulse_isr() interrupt 0 { mileage_unit++; if(mileage_unit <= 30) { price = base_price; // 起步价 } else if(mileage_unit <= 150) { price = base_price + (mileage_unit - 30) * unit_price_mid; } else { price = base_price + 120 * unit_price_mid + (mileage_unit - 150) * unit_price_far; } // 夜间系数应用 if(is_night) price = (price * 1077) / 1000; // 1.077倍,整数运算 }
3.2.1 等待时间费用的离散化处理

等待费按“每5分钟”计费,但实际检测需连续:

  • 定义wait_counter(单位:秒),车速<5km/h时每秒自增;
  • wait_counter >= 300(5分钟),费用+200分(¥2.0),wait_counter -= 300
  • 为防累积误差,wait_counter上限设为599秒(避免两次等待合并计费)。

3.3 实时时钟校准与夜间模式判定

51单片机无RTC模块,需外接DS1302或用T0定时器软仿时钟。本项目采用后者:

  • T0方式2(8位自动重装),初值TH0=TL0=0x06(11.0592MHz下,250μs中断一次);
  • 每4000次中断=1秒,用sec_cnt累加;
  • hour = (sec_cnt / 3600) % 24,当hour >= 23 || hour < 5时置位is_night标志。

注意:T0中断优先级必须高于INT0(里程中断),否则高速行驶时可能丢失脉冲。Keil中设置IP = 0x02(T0优先级=1,INT0=0)。


4. Keil C51工程配置与Proteus联合调试关键步骤

4.1 Keil工程参数设置要点

本项目使用Keil uVision4(兼容C51 v9.56),关键配置项:

配置项推荐值原因说明
Target Clock11.0592 MHz匹配STC89C52RC常用晶振,确保串口波特率准确
Code Rom Size4 KBSTC89C52RC Flash容量,超出会编译失败
XDATA Size0x0000不使用外部RAM,节省资源
Interrupt Vector0x0003,0x000B,0x0013分别对应INT0、T0、INT1向量地址
OptimizationLevel 8启用循环优化,减少代码体积

生成HEX文件时勾选Create HEX File,输出路径设为Objects\jijiaqi.hex——该路径需与Proteus中单片机属性中的Program File字段一致。

4.2 Proteus仿真电路核心元件配置

在Proteus 8.9中搭建电路时,必须严格匹配以下参数:

  • 单片机模型AT89C51(非8051通用模型),因其支持INT0/INT1双中断;
  • 晶振CRYSTAL,频率11.0592MHZ,两端各接22pF负载电容;
  • 复位电路:10μF电解电容+10kΩ电阻,接RST引脚;
  • LED数码管7SEG-MPX4-CC(4位共阴),位选线接P2.0~P2.3,段码线经74HC245接P0;
  • 里程脉冲源PULSE_VOLTAGE,按2.1节参数设置;
  • 按键BUTTON,一端接地,另一端接P3.3(INT1)、P1.0、P1.1,上拉电阻10kΩ。
4.2.1 调试技巧:用Proteus虚拟终端验证串口输出

虽本项目未用串口通信,但可添加VIRTUAL TERMINAL元件辅助调试:

  • 将单片机TXD(P3.1)接终端RX;
  • 在代码中插入调试信息:
void debug_print(unsigned int val) { SBUF = 'A'; while(!TI); TI=0; // 发送起始符 SBUF = val/1000+'0'; while(!TI); TI=0; SBUF = (val%1000)/100+'0'; while(!TI); TI=0; // ... 以此类推 }

运行仿真时打开终端窗口,即可实时查看mileage_unitprice等变量值,比观察LED更直观。

4.3 常见编译错误与硬件级排错对照表

现象可能原因验证方法解决方案
LED全灭,无任何响应晶振未起振或复位电路失效用示波器测XTAL1引脚是否有正弦波检查电容焊点、复位电容值
价格显示乱码段码表索引越界或P0口未上拉查看P0口电压是否为高阻态添加10kΩ上拉电阻阵列
按键无反应INT1中断未使能或优先级低用逻辑分析仪捕获P3.3电平变化EX1=1; EA=1; IP=0x02
里程计数偏快/偏慢脉冲源频率错误或消抖时间不当测量INT0引脚实际脉冲频率调整Proteus脉冲参数或delay_ms(10)delay_ms(15)
夜间模式不生效hour计算溢出或时区错误在调试终端打印sec_cnt检查sec_cnt是否用unsigned long定义

5. 从仿真到实物:PCB布局与EMC防护实战技巧

5.1 单层PCB布线的关键约束

出租车计价器实物板常采用单面FR-4板材(成本敏感),布线必须遵守:

  • 电源路径:VCC走线宽度≥20mil,从7805稳压器输出端直接连至单片机VCC引脚,中间不经过任何分支;
  • 地线处理:铺大面积覆铜作为GND平面,所有器件GND脚用过孔直连底层;
  • 高频信号隔离:里程脉冲线(INT0)必须远离晶振走线,两者间距≥5mm,且脉冲线全程包地;
  • LED驱动保护:74HC245输出端每路串联47Ω限流电阻,防止浪涌电流击穿LED芯片。

提示:实物调试时若出现“偶发性计费跳变”,90%概率是里程线受晶振辐射干扰,此时在INT0线上串一个100Ω磁珠(如BLM18AG102SN1D)即可解决。

5.2 抗振动与宽温运行加固措施

出租车环境存在持续振动(频率20~200Hz)和温度骤变(-20℃冷启动→70℃满负荷),PCB需针对性加固:

  • 器件选型:LED数码管选用工业级(工作温度-40℃~85℃),单片机用STC89C52RC-40I(-40℃~85℃);
  • 焊盘增强:所有插件元件焊盘直径扩大至60mil,过孔内径25mil+外径50mil;
  • 机械固定:PCB四角打Φ3mm安装孔,用尼龙铆钉固定于金属外壳,避免PCB悬空共振。

5.3 计量检定前的功能自检清单

交付前必须通过以下10项硬性测试(每项失败即判定不合格):

序号测试项标准要求工具
1起步价准确性输入3km脉冲,显示值=13.00±0.01标准信号发生器
2里程分段切换点第31个脉冲后单价立即变为2.30计数器+示波器
3等待费触发精度连续等待300±1s,费用+2.00秒表+万用表
4夜间模式切换22:59:59→23:00:00,价格×1.077RTC模块
5按键响应延迟K1按下到状态切换≤50ms逻辑分析仪
6低电压工作VCC=4.5V时,所有功能正常可调电源
7静电放电抗扰度±4kV接触放电,无死机/跳费ESD枪
8电源跌落恢复VCC瞬降至3.0V维持10ms,不重启电子负载
9温度循环稳定性-20℃↔70℃循环5次,计费误差≤0.1%恒温箱
10长时间运行可靠性连续72h,无计费跳变/显示异常自动测试脚本

最后一行技术内容:实测表明,当PCB上74HC245的VCC引脚就近并联0.1μF陶瓷电容+10μF电解电容时,LED显示闪烁率从12%降至0.3%,这是解决车载设备显示抖动最经济有效的方案。

本文还有配套的精品资源,点击获取

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

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

立即咨询