基于 STC89C52 单片机的机动车里程表设计与实现

摘要

本文介绍一种基于 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 存储里程数据(掉电不丢失)或扩展无线传输功能(如蓝牙数据上报)。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容