#include<reg52.h>
#include<stdio.h> //标准输入输出
#include<intrins.h>
#define Data P0//数据端口
sbit RS = P2^4; //Pin4
sbit RW = P2^5; //Pin5
sbit E = P2^6; //Pin6
sbit LED1=P1^3; //脉冲接收指示灯
sbit IR=P1^0; //霍尔传感器脉冲输入端
unsigned char count,second,minute,hour,hour_shiwei,hour_gewei;
fen_shiwei,fen_gewei,miao_shiwei,miao_gewei;//秒表计时参数
unsigned char count1,sssd_shiwei,sssd_gewei;
sssd_fenwei,sssd_shifenwei;//瞬时速度参数
unsigned char key,choose,z,sj1,sj2,t1;
unsigned char pjsd_shiwei,pjsd_gewei,pjsd_fenwei,pjsd_shifenwei;//平均速度参数
unsigned char L_baiwei,L_shiwei,L_gewei;// 车轮周长参数
unsigned char Lc_qianwei,Lc_baiwei,Lc_shiwei,Lc_gewei;Lc_fenwei;// 秒表计时里程计算参数
unsigned char ZLc_qianwei,ZLc_baiwei,ZLc_shiwei,ZLc_gewei;ZLc_fenwei;//总里程参数
unsigned long t,qs,qs1,qs2,qs3,L,V,Vt,dis,dis1,dis2,dis3;
/***************************************************
微秒函数声明
****************************************************/
void DelayUs(unsigned char us)//delay us
{
unsigned char uscnt;
uscnt=us>>1; /*12MHz频率*/
while(--uscnt);
}
/****************************************************
毫秒函数声明
****************************************************/
void DelayMs(unsigned char ms)
{
while(--ms)
{
DelayUs(250);
DelayUs(250);
DelayUs(250);
DelayUs(250);
}
}
/****************************************************
写入命令函数
****************************************************/
void WriteCommand(unsigned char c)
{
DelayMs(2);//操作前短暂延时,保证信号稳定
E=0;
RS=0;
RW=0;
E=1;
Data=c;
E=0;
}
/****************************************************
写入数据函数
***************************************************/
void WriteData(unsigned char c)
{
DelayMs(2); //操作前短暂延时,保证信号稳定
E=0;
RS=1;
RW=0;
E=1;
Data=c;
E=0;
RS=0;
}
/****************************************************
写入字节函数
****************************************************/
void ShowChar(unsigned char pos,unsigned char c)
{
unsigned char p;
if (pos>=0x10)
p=pos+0xc0; //是第二行则命令代码高4位为0xc
else
p=pos+0x80; //是第一行则命令代码高4位为0x8
WriteCommand (p);//写命令
WriteData (c); //写数据
}
/****************************************************
初始化函数
****************************************************/
void InitLcd()
{
DelayMs(15);
WriteCommand(0x38); //display mode
WriteCommand(0x38); //display mode
WriteCommand(0x38); //display mode
WriteCommand(0x06); //显示光标移动位置
WriteCommand(0x0c); //显示开及光标设置
WriteCommand(0x01); //显示清屏
}
/****************************************************
秒表计时模块
*****************************************************/
void Init_Timer0(void)
{
TMOD |=0x01;
TH0=0x3c;
TL0=0xb0;
EA=1;
ET0=1;
}
void Timer0_isr(void) interrupt 1 using 1
{
TH0=0x3c; //重新赋值
TL0=0xb0;
count++;
if (count==20) //20x50ms=1S,大致延时时间
{
count=0;
second++; //秒加1
if(second==60)
{
second=0;
minute++;
if(minute==60)
{
minute=0;
hour++;
if(hour==60)
{
hour=0;
}
hour_shiwei=hour/10;
hour_gewei=hour%10;
}
fen_shiwei=minute/10;
fen_gewei=minute%10;
}
miao_shiwei=second/10;//十位显示值处理
miao_gewei=second%10; //个位显示处理
}
}
/****************************************************
速度模块
*****************************************************/
void Init_Timer1(void)
{
TMOD |=0x10;
TH1=0xd8;
TL1=0xf0;
EA=1;
ET1=1;
TR1=1;
}
void Timer1_isr(void) interrupt 3 using 1
{
TH1=0xd8; //重新赋值
TL1=0xf0;
count1++;
if (count1==100) //100x10ms=1S,大致延时时间
{
count1=0;
dis1=qs1*L;
qs1=0;
Vt=dis1*36/1;
sssd_shiwei=Vt/10000;
sssd_gewei=Vt%10000/1000;
sssd_fenwei=Vt%1000/100;
sssd_shifenwei=Vt%100/10;
if(qs2!=0)
{
t++;
t1++;
dis2=qs2*L;
V=dis2*36/t;
if(t1==5)
{
t1=0;
qs2=0;
}
pjsd_shiwei=V/10000;
pjsd_gewei=V%10000/1000;
pjsd_fenwei=V%1000/100;
pjsd_shifenwei=V%100/10;
}
else
{
t=0;
dis2=0;
qs2=0;
V=0;
pjsd_shiwei=0;
pjsd_gewei=0;
pjsd_fenwei=0;
pjsd_shifenwei=0;
}
}
}
/****************************************************
里程模块
*****************************************************/
void distance(void)
{
dis=qs*L;
ZLc_qianwei=dis/100000;
ZLc_baiwei=dis%100000/10000;
ZLc_shiwei=dis%10000/1000;
ZLc_gewei=dis%1000/100;
ZLc_fenwei=dis%100/10;
if(z==1)
{
dis3=qs3*L;
Lc_qianwei=dis3/100000;
Lc_baiwei=dis3%100000/10000;
Lc_shiwei=dis3%10000/1000;
Lc_gewei=dis3%1000/100;
Lc_fenwei=dis3%100/10;
}
}
/****************************************************
外部中断0 设置车轮周长
*****************************************************/
void set_L(void) interrupt 0
{
L+=10;
L_baiwei=L/100;
L_shiwei=L%100/10;
L_gewei=L%10;
}
/****************************************************
脉冲接收模块
****************************************************/
void pulse_recieve(void)
{
LED1=IR;
if(IR==0)
{
sj1++; //接收脉冲判断参数
if(sj1==2)
{
sj1=0;
}
}
else
{
sj2++; //不接收脉冲判断参数
if(sj2==2)
{
sj2=0;
}
}
if(sj1&sj2)
{
sj1=0;
sj2=0;
qs++;
qs1++;
if(z==1)
{
qs2++;
qs3++;
}
else
{
qs2=0;
}
}
}
/****************************************************
显示欢迎信息
*****************************************************/
void show_welcome(void)
{
ShowChar(0,' ');
ShowChar(1,0x57);//W
ShowChar(2,0x65);//e
ShowChar(3,0x6c);//l
ShowChar(4,0x63);//c
ShowChar(5,0x6f);//o
ShowChar(6,0x6d);//m
ShowChar(7,0x65);//e
ShowChar(8,' ');
ShowChar(9,0x74);//t
ShowChar(10,0x6f);//o
ShowChar(11,' ');
ShowChar(12,0x75);//u
ShowChar(13,0x73);//s
ShowChar(14,0x65);//e
ShowChar(15,' ');
ShowChar(16,' ');
ShowChar(17,' ');
ShowChar(18,0x22);
ShowChar(19,0x6d);//m
ShowChar(20,0x69);//i
ShowChar(21,0x6c);//l
ShowChar(22,0x65);//e
ShowChar(23,0x73);//s
ShowChar(24,0x74);//t
ShowChar(25,0x6f);//o
ShowChar(26,0x6e);//n
ShowChar(27,0x65);//e
ShowChar(28,0x73);//s
ShowChar(29,0x22);
ShowChar(30,' ');
ShowChar(31,' ');
}
/****************************************************
显示周长设置
*****************************************************/
void show_lcd_one(void)
{
ShowChar(0,0x53);//S
ShowChar(1,0x65);//e
ShowChar(2,0x74);//t
ShowChar(3,' ');
ShowChar(4,0x42);//B
ShowChar(5,0x69);//i
ShowChar(6,0x6b);//k
ShowChar(7,0x65);//e
ShowChar(8,' ');
ShowChar(9,0x54);//T
ShowChar(10,0x69);//i
ShowChar(11,0x72);//r
ShowChar(12,0x65);//e
ShowChar(13,' ');
ShowChar(14,0x4c);//L
ShowChar(15,0x3d);//=
ShowChar(16,' ');
ShowChar(17,' ');
ShowChar(18,' ');
ShowChar(19,' ');
ShowChar(20,' ');
ShowChar(21,L_baiwei+0x30);
ShowChar(22,L_shiwei+0x30);
ShowChar(23,L_gewei+0x30);
ShowChar(24,0x63);//c
ShowChar(25,0x6d);//m
ShowChar(26,' ');
ShowChar(27,' ');
ShowChar(28,' ');
ShowChar(29,' ');
ShowChar(30,' ');
ShowChar(31,' ');
}
/****************************************************
显示秒表里程、时间
*****************************************************/
void show_lcd_two(void)
{
ShowChar(0,' ');
ShowChar(1,' ');
ShowChar(2,0x53);//S
ShowChar(3,0x74);//t
ShowChar(4,' ');
ShowChar(5,' ');
ShowChar(6,' ');
ShowChar(7,' ');
ShowChar(8,Lc_qianwei+0x30);
ShowChar(9,Lc_baiwei+0x30);
ShowChar(10,Lc_shiwei+0x30);
ShowChar(11,Lc_gewei+0x30);
ShowChar(12,0x2e);
ShowChar(13,Lc_fenwei+0x30);
ShowChar(14,0x6d);//m
ShowChar(15,' ');
ShowChar(16,' ');
ShowChar(17,' ');
ShowChar(18,0x54);//T
ShowChar(19,0x69);//i
ShowChar(20,0x6d);//m
ShowChar(21,0x65);//e
ShowChar(22,' ');
ShowChar(23,hour_shiwei+0x30);
ShowChar(24,hour_gewei+0x30);
ShowChar(25,0x3a);
ShowChar(26,fen_shiwei+0x30);
ShowChar(27,fen_gewei+0x30);
ShowChar(28,0x3a);
ShowChar(29,miao_shiwei+0x30);
ShowChar(30,miao_gewei+0x30);
ShowChar(31,' ');
}
/****************************************************
显示平均速度和瞬时速度
*****************************************************/
void show_lcd_three(void)
{
ShowChar(0,' ');
ShowChar(1,' ');
ShowChar(2,0x56);//V
ShowChar(3,' ');
ShowChar(4,' ');
ShowChar(5,pjsd_shiwei+0x30);
ShowChar(6,pjsd_gewei+0x30);
ShowChar(7,0x2e);
ShowChar(8,pjsd_fenwei+0x30);
ShowChar(9,pjsd_shifenwei+0x30);
ShowChar(10,0x6b);//k
ShowChar(11,0x6d);//m
ShowChar(12,0x2f);// /
ShowChar(13,0x68);//h
ShowChar(14,' ');
ShowChar(15,' ');
ShowChar(16,' ');
ShowChar(17,' ');
ShowChar(18,0x56);//V
ShowChar(19,0x74);//t
ShowChar(20,' ');
ShowChar(21,sssd_shiwei+0x30);
ShowChar(22,sssd_gewei+0x30);
ShowChar(23,0x2e);
ShowChar(24,sssd_fenwei+0x30);
ShowChar(25,sssd_shifenwei+0x30);
ShowChar(26,0x6b);//k
ShowChar(27,0x6d);//m
ShowChar(28,0x2f);// /
ShowChar(29,0x68);//h
ShowChar(30,' ');
ShowChar(31,' ');
}
/****************************************************
显示总里程、秒表里程
*****************************************************/
void show_lcd_four(void)
{
ShowChar(0,' ');
ShowChar(1,' ');
ShowChar(2,0x53);//S
ShowChar(3,' ');
ShowChar(4,' ');
ShowChar(5,' ');
ShowChar(6,' ');
ShowChar(7,' ');
ShowChar(8,ZLc_qianwei+0x30);
ShowChar(9,ZLc_baiwei+0x30);
ShowChar(10,ZLc_shiwei+0x30);
ShowChar(11,ZLc_gewei+0x30);
ShowChar(12,0x2e);
ShowChar(13,ZLc_fenwei+0x30);
ShowChar(14,0x6d);//m
ShowChar(15,' ');
ShowChar(16,' ');
ShowChar(17,' ');
ShowChar(18,0x53);//S
ShowChar(19,0x74);//t
ShowChar(20,' ');
ShowChar(21,' ');
ShowChar(22,' ');
ShowChar(23,' ');
ShowChar(24,Lc_qianwei+0x30);
ShowChar(25,Lc_baiwei+0x30);
ShowChar(26,Lc_shiwei+0x30);
ShowChar(27,Lc_gewei+0x30);
ShowChar(28,0x2e);
ShowChar(29,Lc_fenwei+0x30);
ShowChar(30,0x6d);//m
ShowChar(31,' ');
}
/****************************************************
显示平均速度和瞬时速度
*****************************************************/
void show_lcd_five(void)
{
ShowChar(0,' ');
ShowChar(1,' ');
ShowChar(2,0x56);//V
ShowChar(3,' ');
ShowChar(4,' ');
ShowChar(5,' ');
ShowChar(6,pjsd_shiwei+0x30);
ShowChar(7,pjsd_gewei+0x30);
ShowChar(8,0x2e);
ShowChar(9,pjsd_fenwei+0x30);
ShowChar(10,pjsd_shifenwei+0x30);
ShowChar(11,0x6b);//k
ShowChar(12,0x6d);//m
ShowChar(13,0x2f);// /
ShowChar(14,0x68);//h
ShowChar(15,' ');
ShowChar(16,' ');
ShowChar(17,' ');
ShowChar(18,0x54);//T
ShowChar(19,0x69);//i
ShowChar(20,0x6d);//m
ShowChar(21,0x65);//e
ShowChar(22,' ');
ShowChar(23,hour_shiwei+0x30);
ShowChar(24,hour_gewei+0x30);
ShowChar(25,0x3a);
ShowChar(26,fen_shiwei+0x30);
ShowChar(27,fen_gewei+0x30);
ShowChar(28,0x3a);
ShowChar(29,miao_shiwei+0x30);
ShowChar(30,miao_gewei+0x30);
ShowChar(31,' ');
}
/****************************************************
选择显示内容模块
*****************************************************/
void choosed(void)
{
if(choose==1)
{
show_lcd_one();//显示设置的车轮周长为多长
}
else if(choose==2)
{
show_lcd_two();//显示秒表里程和时间
}
else if(choose==3)
{
show_lcd_three();//显示平均速度和瞬时速度
}
else if(choose==4)
{
show_lcd_four();//显示总里程和秒表里程
}
else if(choose==5)//显示平局速度和时间
{
show_lcd_five();
}
}
/****************************************************
延时程序
****************************************************/
void delay(unsigned int cnt)
{
while(--cnt);
}
/****************************************************
键盘扫描函数
****************************************************/
unsigned char keyscan(void) //使用行列反转扫描法
{
unsigned char cord_h,cord_l;//行列值中间变量
P3=0x0f; //行线输出全为0
cord_h=P3&0x0f; //读入列线值
if(cord_h!=0x0f) //先检测有无按键按下
{
delay(100); //去抖
if(cord_h!=0x0f)
{
cord_h=P3&0x0f; //读入列线值
P3=cord_h|0xf0; //输出当前列线值
cord_l=P3&0xf0; //读入行线值
return(cord_h+cord_l);//键盘最后组合码值
}
}return(0xff);
}
/****************************************************
键盘输入模块
****************************************************/
void keyinput(void)
{ switch (key)
{case 0x7e:choose=1;break; //显示设置的车轮周长为多长
case 0xbe:choose=2;break; //显示秒表里程和时间
case 0xde:choose=3;break; //显示平均速度和瞬时速度
case 0xee:choose=4;break; //显示总里程和秒表里程
case 0x7d:choose=5;break; //显示平均速度和时间
case 0x77:TR0=1,z=1;break; //秒表计时开始
case 0xb7:TR0=0,z=0;break; //秒表计时暂停
case 0xd7:TR0=0;z=0;count=0;second=0;minute=0;hour=0;
hour_shiwei=0;hour_gewei=0;fen_shiwei=0;fen_gewei=0;miao_shiwei=0;
miao_gewei=0;break; //秒表清零并且暂停
case 0xdd:qs=0;dis=0;ZLc_qianwei=0;ZLc_baiwei=0;ZLc_shiwei=0;
ZLc_gewei=0;ZLc_fenwei=0;break; //总里程清零
case 0xed:dis3=0;qs3=0;Lc_qianwei=0;Lc_baiwei=0;Lc_shiwei=0;
Lc_gewei=0;Lc_fenwei=0; //秒表里程清零
}
}
/******************************************************************
主函数
******************************************************************/
main()
{
InitLcd(); //初始化LCD
DelayMs(15); //延时保证信号稳定
Init_Timer0();
Init_Timer1();//定时器初始化
EA=1;
EX0=1; //外部中断0开
IT0=1; //外部中断0触发,为边沿触发方式(下降沿有效)
show_welcome(); //显示欢迎信息
while(1)
{
pulse_recieve(); //脉冲接收
key=keyscan(); //调用键盘扫描,
keyinput(); //键盘输入
distance(); //执行里程模块
choosed(); //执行显示选择模块
}
} |