自行车测速、里程计
- 格式:doc
- 大小:132.50 KB
- 文档页数:9
我比较喜欢骑自行车出去走走,以前也做了个自行车测速(里程)计,用4位数码管输出数据的,它的优点是驱动简单,电压范围广,可用3.7V的锂电池直接供电,整个电路结构简单,耗能低,但它的缺点也是显而易见的,数码管在阳光下,无法看清楚,而且只有一组4位数据,不能同时查看速度及里程,不方便。由于购得更小的液晶模块,所以近期用液晶做输出显示器件,做了一个新的里程(速度)计。在阳光下清晰,晚上可用背光,2行共16个字符,并带存储器。有系统运行时间显示,外中断信号与写数据信号、电池低指示。
整体尺寸为65X35X12。加上电池(880mah),厚度要增加3mm,电池接上码表正在测试,已运行14个小时,理论可运行40多小时。
(原文件名:http_imgload.jpg)
引用图片
// 1602 2*16字符第一行0x80 第二行0xc0
// 模式(km/h) 12.5kmh | 999.99km
// 24C02存储 0x00-0x03: 99 99 99 99 cm
// 0x2e,0x6b,0x6d,0x06,0x07,0x20,0x3d 0x30-0x39开始是数字0-9
// . , k , m , ┗,/h ,black, =
//------头--------------------------------------------------------
//申明
#include "REG2051.H"
#include "INTRINS.H"
#define uchar unsigned char
#define uint unsigned int
//轮周长1.98m及各位值 0.5ms取 1.98*(1/0.5)*1000*10
#define girth 39600
#define girth_h 1
#define girth_l 98
//单片机IO连接
#define LCM0802B_IO P1
sbit LCM0802B_RS = P3^7;
sbit LCM0802B_RW = P3^5;
sbit LCM0802B_EN = P3^4;
sbit KEY = P3^3;
sbit SIGN = P3^2;
sbit AT24C02_SDA = P3^1;
sbit AT24C02_SCL = P3^0;
//液晶驱动函数定义
void LCM_RD_BUSY(void); //读忙信号
void LCM_WR_CMD(uchar); //写操作命令
void LCM_WR_DAT(uchar); //写数据
void LCM_WR(uchar,uchar); //输出一个字符
//存储IC驱动函数定义
void AT24C02_START(void); //开启
void AT24C02_STOP(void); //停止
void AT24C02_CK(void); //时钟
void AT24C02_WR_byte(uchar); //写入单字节
uchar AT24C02_RD_byte(void); //读入单字节
uchar AT24C02_RD(uchar); //从24c02的地址address中读取一个字节数据
void AT24C02_WR(uchar,uchar); //向24c02的address地址中写入一字节数据info //函数定义
void _init(void); //软硬件初始化
void AT24C02_WRAMD(void); //24c02写入RAM数据
void _nus(uchar); //us延时
void _nms(uchar); //ms延时
void dis_dis(void); //距离数据输出
//变量定义
uchar d_var[4]={0,0,0,0}; //距离的cm值0x00-0x03双数计算
uint timej; //时间周期个数
uint int_tp; //周期个数传递
bit flg_cal; //允许计算
bit sf; //s指示标志
uint sj; //s指示计数
bit sen; //有更新数据
//---- 中断 -----------------------------------------------------
//500us周期定时函数
void T0_SEV(void) interrupt 1 using 1
{
TR0 = 0; ET0 = 0;
TH0 = 0xff; TL0 = 0x5a; //计时初值
timej++; //超过3.5S无中断相应,即判断速度为0,则最低速度2.04km/h
if(timej == 7000){
int_tp = timej; timej = 0;
flg_cal = 1;
}
if(sj>0){ sj--; }//s计数递减
ET0 = 1; TR0 = 1;
}
//外部中断函数
void Int0_SEV(void) interrupt 0 using 0
{
EX0 = 0;
int_tp = timej; timej = 0;
flg_cal = 1;//读取计数周期数
EX0 = 1;
}
//------主体-------------------------------------------------------- //主函数
void main()
{
_init(); //初始化
while(1){
if(!KEY){
_nms(2); //去抖延时
if(!KEY){
uchar key_tp = 200;
EA = 0; timej = 0;
do{ key_tp--; _nms(3); }while(!KEY&&key_tp>0); //长短按计时循环
EA = 1;
if(key_tp==0){
d_var[0] = 0; d_var[1] = 0; d_var[2] = 0; d_var[3] = 0; //清零
_nus(20); dis_dis(); //输出距离
}//长按
//短按长按都要写入数据
sj = 3000; sf = 1;
LCM_WR(0x80,0x06); //0x06
AT24C02_WRAMD(); //24c02写入RAM数据
//等待释放按键
while(!KEY){ while(!KEY); _nms(2); }
}
}//按键功能,长按清除历程信息,短按切换ms与kmh
if(flg_cal){ //清零输出十分位" 0.0"
if(int_tp == 7000){
LCM_WR(0x81,0x20); LCM_WR(0x82,0x30); LCM_WR(0x84,0x30);