//本程序采用1秒定時方法對1秒內脈沖進行計數,以此計數轉速,本程序經測試正常,用霍爾元件進行速度傳感!
//本程序 采用1602液晶作為顯示!
//李干云
源程序如下
#include <AT89X52.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
sbit d_led=P1^7;
sbit rs = P3^5 ;
sbit rw = P3^6 ;
sbit en = P3^7 ;
uchar time[3];
uchar dis_buf[24];
uchar pos_d;
uchar dis_d;
uchar dl=20;//時間循環次數//50ms中斷一次
uint temp1,n2;
uchar n,n3;
//uint table[6];
//------------------------------------------------------------
bit r_busy() //測試忙狀態
{
bit busy;
rs=0;
rw=1;
en=1;
//busy=(bit)(P0&0x80);
if((P0&0X80)==0X80) busy=0;else busy=0;
en=0;
return busy;
}
//------------------------------------------------------------
void w_cmd(cmd)// 寫命令
{
rs=0;
rw=0;
en=0;
P0=cmd;
en=1;
en=0;
}
//------------------------------------------------------------
void w_pos(uchar pos)// 寫顯示位置 地址數據
{
w_cmd(pos +0x82) ; //顯示第一行或第二行,第一行0x80
}
//------------------------------------------------------------
void w_pos1(uchar pos)// 寫顯示位置 地址數據
{
w_cmd(pos +0xc1) ; //顯示第一行或第二行,第一行0x80
}
//------------------------------------------------------------
void w_dat(uchar dat)// 寫數據
{
while(r_busy());
rs=1;
rw=0;
en=0;
P0=dat;
en=1;
en=0;
}
//------------------------------------------------------------
void delay(uchar ms) // 延時子程序
{
uchar i ;
while(ms--)
{
for(i=0;i<250;i++) ;
}
}
//------------------------------------------------------------
dis_dat()//數據轉換
{
dis_buf[0]='<'; //顯示t
dis_buf[1]='L'; //i
dis_buf[2]='i'; // m
dis_buf[3]='a'; //e
dis_buf[4]='h';
dis_buf[5]='u';
dis_buf[6]='i';
dis_buf[7]='.';
dis_buf[8]='M';
dis_buf[9]='C';
dis_buf[10]='U';
dis_buf[11]='>';
dis_buf[12]='I';
dis_buf[13]='S';
dis_buf[14]=' ';
dis_buf[15]=((temp1/10000)+0x30);
dis_buf[16]=((temp1/1000%10)+0x30);
dis_buf[17]=((temp1/100%10)+0x30);
dis_buf[18]= ((temp1/10%10)+0x30);
dis_buf[19]=((temp1%10)+0x30);
dis_buf[20]=' ';
dis_buf[21]='P';
dis_buf[22]='P';
dis_buf[23]='M';
}
//------------------------------------------------------------
void timer0 (void) interrupt 1 //using 3
{
TH0=(65536-46080)/256;
TL0=(65536-46080)%256;
if(dl--==0)//判斷是否次數為20
{
dl=20;
d_led=!d_led;
if ((++time[0])>59)
{
time[1]++;
time[0]=0;
}
else if (time[1]>59)
{
time[2]++;
time[1]=0;
}
else if (time[2]>23)
{
time[2]=0;
time[1]=0;
time[0]=0;
}
}
else ; //跳出中斷
}
//------------------------------------------------------------
void lcd_inti(void)//lcd初始化
{
delay(15);
w_cmd(0x01);//清屏
delay(15);
w_cmd(0x09);//設定輸入模式,地址遞加
delay(15);
w_cmd(0x38);//功能設置,數據長度8位,雙列字形,1:5*10字形
delay(15);
w_cmd(0x0f);//開顯示,關閉光標字符不閃爍
delay(15);
}
//------------------------------------------------------------
void timer0_inti(void)//定時器TO中斷初始化
{
TMOD=0X11;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
PX0=1;// 中斷0高優先級
IT0=1;
EX0=1;
}
//------------------------------------------------------------
main()
{
time[0]=0; //sec
time[1]=11; //min
time[2]=14; //hour
lcd_inti();
timer0_inti();
//TH0=15;TL0=160;
TH0=0;TL0=0;
while(1)
{
for(pos_d=0;pos_d<=23;pos_d++)
{
if(pos_d<=11) w_pos(pos_d); //寫地址
else
{ dis_dat(); //數據轉換
w_pos1(pos_d-11);
}
dis_d=dis_buf[pos_d];
w_dat(dis_d);
delay(1);
}
}
}
void time0(void) interrupt 1 using 2
{
TH0=(65536-49550)/256;
TL0=(65536-49550)%256;
n3++;
if(n3==20)
{ P1_6=0;
temp1=n2*60;n2=0;n3=0;TR0=0;
}
}
void int0_srv(void) interrupt 0 using 1 //外部中斷0
{
n2++; TR0=1;
}
|