#include<reg52.h>
#include<intrins.h> //包含_nop_();函數定義的頭文件
void timer0_int();
sbit LED=P3^7;
sbit E=P3^2; //1602使能引腳
sbit RW=P3^1; //1602讀寫引腳
sbit RS=P3^0; //1602數據/命令選擇引腳
unsigned char hour,minute,second;
unsigned char n,count;
unsigned long lengthbuf,lengthvalue;
unsigned char code
Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//0~9的共陰極七段管代碼
unsigned char code
Table1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
//0~9的共陰極七段管代碼帶小數點
void Delay0(int Times);
void Display(unsigned int x);
void delay() //延時5US
{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
}
bit Busy(void) //讀狀態函數判斷液晶模塊的忙碌狀態
{
bit busy_flag = 0;
RS = 0;
RW = 1;
E = 1;
delay();
busy_flag = (bit)(P0 & 0x80);
E = 0;
return busy_flag;
}
void wcmd(unsigned char del) //將模式設置指令或顯示地址寫入液晶模
{
while(Busy());
RS = 0;
RW = 0;
E = 0;
delay();
P0 = del;
delay();
E = 1;
delay();
E = 0;
}
void wdata(unsigned char del)
///將數據字符ASCII碼寫入液晶
{
while(Busy());
RS = 1;
RW = 0;
E = 0;
delay();
P0 = del;
delay();
E = 1;
delay();
E = 0;
}
void L1602_init(void) //初始化液晶模塊
{
wcmd(0x38); //功能設置8位字長2行5*7點陣
wcmd(0x0c); //顯示設置顯示屏右移
wcmd(0x06); //顯示設置光標右移字符不移
wcmd(0x01); //清屏命令
}
void L1602_string(unsigned char hang,unsigned char lie,unsigned char p)
//將數據寫入液晶模塊
{
unsigned char a;
if(hang == 1) a = 0x80; //顯示在第一行
if(hang == 2) a = 0xc0; //顯示在第一行
a = a + lie -1;
wcmd(a);
wdata(p);
}
void timer0_int() interrupt 1 using 3 //中斷用于構成時鐘
{
n++;
if(n==100)
{
n=0;
count++;
second++;
if(second>=60)
{
second=0;
minute++;
if(minute>=60)
{
minute=0;
hour++;
if(hour>=24) hour=0;
}
}
}
if(count==5)
{
count=0;
lengthvalue=(TL1+TH1*256)*215-lengthbuf;
lengthbuf=(TL1+TH1*256)*215;
}
TH0=0xd8;
TL0=0xf0;
}
int timer() //以秒為單位計算運行總時間
{
unsigned char a=100;
unsigned char b;
b=second+minute*60+hour*60*60;
return b;
}
void Delay0(int Time) //延時子程序
{
int i;
unsigned char j;
for(i=0;i<Time;i++)
{
for(j=0;j<150;j++)
{
}
}
}
void Display(unsigned int x) //在LED七段管中顯示最高速度
{
unsigned char slc;
unsigned char a,b,c,d;
slc=0xef; //LED七段管選通
a= x/1000;
b=( x-a*1000)/100;
c=( x-a*1000-b*100)/10;
d= x%10;
{
P2=slc; //分別將最大速度的各個位掃描顯示
slc=slc<<1;
P1=Table[a];
Delay0(10);
P2=slc;
slc=slc<<1;
P1=Table1[b];
Delay0(10);
P2=slc;
slc=slc<<1;
P1=Table[c];
Delay0(10);
P2=slc;
slc=slc<<1;
P1=Table[d];
Delay0(10);
}
return;
}
void main()
{
unsigned char i=0 ;
unsigned int v=0; //運行速度
unsigned int vnow; //當前速度
unsigned int a,b,c,d; //分別顯示速度的十位個位十分位 百分位
unsigned long quanshu; //定義車輪轉動圈數
unsigned long
length,length1,length2,length3,length4,length5,length6;
unsigned int second1,second2,minute1,minute2,hour1,hour2;
L1602_init();
TMOD=0x51; //定時器T0計數器T1允許外部中斷T1工作方式01
TH1=0x00; //計數器T1高位裝初值
TL1=0x00; //計數器T1低位裝初值
ET1=1; //計數器0開中斷
TR1=1; //計數器0開始工作
TH0=0XD8; //T0設置時間常數
TL0=0XF0;
ET0=1;
EA=1;
TR0=1;
IT1=1; //外部中斷1請求觸發方式
EX1=1;
P1=0X00; //P1、P2口裝初值用于LED七段管顯示用
P2=0xff;
while(1)
{
quanshu=TL1+TH1*256; //計算車輪旋轉圈數
length=quanshu*215; //騎行距離
//計算里程各個進位
length1=length/100000;
length2=(length-length1*100000)/10000;
length3=(length-length1*100000-length2*10000)/1000;
length4=(length-length1*100000-length2*10000-length3*1000)/100;
length5=(length-length1*100000-length2*10000-length3*1000-length4
*100)/10;
length6=length%10;
if(timer()>0)
v=length/timer(); //計算速度
vnow=lengthvalue/5; //計算當前速度5秒內
if(vnow>=695) LED=0;else LED=1; //速度超過6.95m/s(即
Display(vnow); //在LED七段管上顯示當前速度5秒內速度
Delay0(20);
a=(v/1000); //計算速度的各個進位
b=(v-a*1000)/100;
c=(v-a*1000-b*100)/10;
d=v%10;
second1=second/10; //計算分秒時的十位與個位
second2=second%10;
minute1=minute/10;
minute2=minute%10;
hour1=hour/10;
hour2=hour%10;
L1602_string(1,1,'s'); //在LCD相應位置顯示變量或者常量
L1602_string(1,2,'p');
L1602_string(1,3,'e');
L1602_string(1,4,'e');
L1602_string(1,5,'d');
L1602_string(1,6,' ');
L1602_string(1,7,'L');
L1602_string(1,8,'=');
L1602_string(1,9,length1+48);
L1602_string(1,10,length2+48);
L1602_string(1,11,length3+48);
L1602_string(1,12,length4+48);
L1602_string(1,13,'.');
L1602_string(1,14,length5+48);
L1602_string(1,15,length6+48);
L1602_string(1,16,'m');
L1602_string(2,1,a+48);
L1602_string(2,2,b+48);
L1602_string(2,3,'.');
L1602_string(2,4,c+48);
L1602_string(2,5,d+48);
L1602_string(2,6,'m');
L1602_string(2,7,'/');
L1602_string(2,8,'s');
L1602_string(2,9,hour1+48);
L1602_string(2,10,hour2+48);
L1602_string(2,11,':');
L1602_string(2,12,minute1+48);
L1602_string(2,13,minute2+48);
L1602_string(2,14,':');
L1602_string(2,15,second1+48);
L1602_string(2,16,second2+48);
while(i<2) //LCD顯示延遲
{delay();
i++; }
i=0;
}
} |