摘要
本文介绍一种基于 STC89C52 单片机的机动车里程表设计方案,通过霍尔传感器采集车轮转速信号,结合 LCD1602 显示模块实现里程和速度的实时显示。方案涵盖硬件选型、电路设计及软件编程,具有成本低、精度高、扩展性强等特点。
一、硬件设计
1. 核心芯片选型
单片机:选用STC89C52(8 位微控制器,兼容 51 内核,内置 8KB Flash、512B RAM,支持定时器 / 计数器和外部中断,适合低成本控制场景)。
2. 功能模块选型
(1)转速采集模块
传感器:AH44E 霍尔传感器(感应磁场变化输出脉冲信号,灵敏度高,抗干扰能力强)。
辅助元件:永磁体(安装于车轮辐条上,随车轮转动触发霍尔传感器)。
(2)显示模块
LCD1602(16×2 字符型液晶显示器,支持 ASCII 字符显示,通过并行接口与单片机通信)。
(3)电源模块
5V 稳压电源(为单片机和传感器供电,可选用 LM7805 稳压芯片或 USB 供电)。
3. 硬件接线图
| 模块 | 单片机引脚 | 功能说明 |
|---|---|---|
| 霍尔传感器 | P3.2(INT0) | 脉冲信号输入(外部中断 0) |
| LCD1602-RS | P2.0 | 寄存器选择(高电平为数据) |
| LCD1602-RW | P2.1 | 读写控制(接地为写模式) |
| LCD1602-EN | P2.2 | 使能信号(下降沿触发) |
| LCD1602-D0-D7 | P0.0-P0.7 | 8 位数据总线(需外接 10kΩ 上拉电阻) |
| 电源 | VCC/GND | 5V 供电 |
二、软件设计
1. 系统功能逻辑
信号采集:霍尔传感器每检测到一次永磁体磁场,输出一个下降沿脉冲,触发单片机外部中断计数。
数据处理:通过定时器定时(如 1 秒)计算脉冲频率,结合车轮周长换算为速度(km/h)和累计里程(km)。
结果显示:LCD1602 实时显示速度和里程值,每 100ms 刷新一次。
2. 软件流程图

3. 代码实现(C 语言)
#include <reg52.h>
#include <intrins.h>
// 引脚定义
#define LCD_DATA P0
sbit LCD_RS = P2^0;
sbit LCD_RW = P2^1;
sbit LCD_EN = P2^2;
sbit HALL_SENSOR = P3^2; // 霍尔传感器接INT0
// 全局变量
unsigned long pulse_count = 0; // 脉冲计数
float speed = 0.0; // 速度(km/h)
float mileage = 0.0; // 里程(km)
unsigned char display_buf[16]; // 显示缓冲区
// 车轮参数(需根据实际轮胎规格设置,示例:直径60cm,周长=π×直径=1.88496米)
#define WHEEL_CIRCUMFERENCE 1.88496 // 单位:米/圈
// 延时函数
void delay_ms(unsigned int ms) {
unsigned int i, j;
for (i = ms; i > 0; i--)
for (j = 110; j > 0; j--);
}
// LCD写命令
void lcd_write_cmd(unsigned char cmd) {
LCD_RS = 0;
LCD_RW = 0;
LCD_DATA = cmd;
_nop_();
LCD_EN = 1;
delay_ms(2);
LCD_EN = 0;
}
// LCD写数据
void lcd_write_data(unsigned char dat) {
LCD_RS = 1;
LCD_RW = 0;
LCD_DATA = dat;
_nop_();
LCD_EN = 1;
delay_ms(2);
LCD_EN = 0;
}
// LCD初始化
void lcd_init() {
lcd_write_cmd(0x38); // 8位数据总线,2行显示,5×8点阵
lcd_write_cmd(0x0C); // 显示开,光标关,闪烁关
lcd_write_cmd(0x06); // 写数据后光标右移
lcd_write_cmd(0x01); // 清屏
delay_ms(2);
}
// 外部中断0服务函数(脉冲计数)
void int0_isr() interrupt 0 {
pulse_count++;
}
// 定时器0初始化(1秒定时,晶振12MHz)
void timer0_init() {
TMOD |= 0x01; // 定时器0模式1(16位计数器)
TH0 = 0x3C; // 初值计算:50ms定时((65536-50000)/256)
TL0 = 0xB0;
ET0 = 1; // 使能定时器0中断
TR0 = 1; // 启动定时器
}
// 数据处理函数
void calculate_data() {
unsigned long temp_pulse;
float temp_mileage;
// 读取当前脉冲数并清零
temp_pulse = pulse_count;
pulse_count = 0;
// 计算速度(km/h):脉冲数/秒 × 周长(米) × 3.6/1000
speed = (temp_pulse * WHEEL_CIRCUMFERENCE * 3.6) / 1000;
// 累计里程(km)
temp_mileage = temp_pulse * WHEEL_CIRCUMFERENCE / 1000;
mileage += temp_mileage;
}
// 显示更新函数
void update_display() {
// 速度显示:SPEED: XX.X km/h
sprintf(display_buf, "SPEED:%5.1f km/h", speed);
lcd_write_cmd(0x80); // 第一行起始地址
for (int i = 0; i < 16; i++) {
lcd_write_data(display_buf[i]);
}
// 里程显示:MILE: XXX.XX km
sprintf(display_buf, "MILE:%6.2f km ", mileage);
lcd_write_cmd(0xC0); // 第二行起始地址
for (int i = 0; i < 16; i++) {
lcd_write_data(display_buf[i]);
}
}
// 主函数
void main() {
EA = 1; // 开总中断
EX0 = 1; // 使能外部中断0
IT0 = 1; // 下降沿触发
lcd_init();
timer0_init();
while (1) {
delay_ms(100); // 刷新间隔
update_display();
}
}
// 定时器0中断服务函数(1秒定时)
void timer0_isr() interrupt 1 {
static unsigned char count = 0;
TH0 = 0x3C; // 重新装载初值
TL0 = 0xB0;
count++;
if (count >= 20) { // 20次50ms=1秒
count = 0;
calculate_data();
}
}
三、系统调试与优化
传感器安装:确保永磁体与霍尔传感器间距小于 1cm,避免信号丢失。
参数校准:通过实际路测调整WHEEL_CIRCUMFERENCE值,提高里程计算精度。
抗干扰:传感器信号线需屏蔽处理,避免电磁干扰导致误计数。
四、总结
本方案通过 STC89C52 单片机与霍尔传感器、LCD1602 的结合,实现了机动车里程和速度的实时监测与显示。硬件结构简单、成本低廉,软件逻辑清晰,可扩展性强,适用于各类机动车的里程计量场景。
注:本设计如有疑问需要解惑可直接私信本人,看我个人简介
如需进一步优化,可增加按键设置功能(如校准周长)、EEPROM 存储里程数据(掉电不丢失)或扩展无线传输功能(如蓝牙数据上报)。


















暂无评论内容