#include<reg52.h>
#include<intrins.h>
#include<absacc.h>
#include<string.h>
#define uchar unsigned char
#define uint unsigned int
uint count; //當前計數值
uint distance;
bit intt=1;
unsigned char cont=0;
unsigned char co=0;
uchar buf;
//uchar m,lm,cm;
/**************針腳定義************/
sbit rect_wave=P2^0; //晶振控制信號
sbit RS=P1^0;
sbit RW=P1^1;
sbit EN=P1^2;
sbit CLR=P1^3;
sbit DATA=P1^4;
sbit CLK=P1^5;
sbit d=P2^1;
sbit cp=P2^2;
sbit dir=P2^3;
/***********************************/
/**************函數聲明************/
void time0over(void); //定時器計時程序
void clrlcd(void); //clr LCD
void c_send(unsigned char y); //發命令
void reset(void); // reset LCD
void d_send(unsigned char x); //發數據
void pos(unsigned char pos); //設定顯示位置
void l_delay(unsigned int t); //長延時
void trans(j);
void ret(void); //初始化系統
void retcont(void); //定時器復位
void math(void); //計算測量距離
/***************************/
void init(void)
{ TH1=0xf3;
TL1=0xf3;
PCON=0x80;
TR1=1;
SCON=0x50; /*串口初始化設置,波特率4800BPS*/
}
//*******************************//
void send(uchar dat) /*發送子程序*/
{ //uchar i;
/*發送壹個數據*/
SBUF=dat;
while(TI==0);
TI=0;
}
/***********************************/
void turn (void) //電機轉動控制
{
unsigned char x;
cont++;
cp=~cp;
l_delay(50);
cp=~cp;
co++;
if(co == 3)
{d=~d;
}
if(co == 4)
{d=~d;
co=0;
}
if (cont == 200) //判斷是否進行反轉復位
{dir=~dir;
cont=0;
for(x=0;x < 200;x++)
{cp=~cp;
l_delay(5);
cp=~cp;
co++;
if(co == 3)
{d=~d;
}
if(co == 4)
{d=~d;
co=0;
}
}
dir=~dir;
cont=0;
}
}
/**************子程序**********************/
void int0 () interrupt 0 //中斷0服務程序
{
EX0=0; //關閉中斷
TR0=0; //關閉定時器
TF0=0; //標誌位清零
rect_wave=0; //停止發送超聲波
intt=0;
}
void work(void)
{
if(!intt)
{
intt=1;
if (distance < 400)
{
buf=distance;
send(buf);
turn();
math();} //計算所測得的距離
l_delay(5); //延時
retcont(); //定時器復位
rect_wave=1;
count=0;
}
}
void math(void) //計算所測得的距離
{ uchar m,lm,cm;
cm=distance%10; //取距離的最低位
distance=distance/10; //取距離的次高位
lm=distance%10;
distance=distance/10; //取距離的最高位
m=distance%10;
clrlcd(); //輸出計算結果
pos(0);
d_send('d');
d_send('i');
d_send('s');
d_send('=');
//pos(4);
d_send(m+0x30);
d_send(lm+0x30);
d_send(cm+0x30);
d_send('c');
d_send('m');
l_delay(500);
}
void time0over(void) //定時器計時程序
{ TF0=0;
count++;
distance=count;
}
/*
void trans(j)
{
switch(j)
{
case 0: d_send('0');break;
case 1: d_send('1');break;
case 2: d_send('2');break;
case 3: d_send('3');break;
case 4: d_send('4');break;
case 5: d_send('5');break;
case 6: d_send('6');break;
case 7: d_send('7');break;
case 8: d_send('8');break;
case 9: d_send('9');break;
}
}
*/
delay() //延時
{
int i;
for(i=0;i<1000;i++);
}
void l_delay(unsigned int t) //延時
{
unsigned int p;
unsigned int j;
for(j=0;j<t;j++)
{
for(p=0;p<1000;p++);
}
}
void reset(void) // reset LCD
{
delay();
c_send(0x38);
c_send(0x01);
c_send(0x06);
c_send(0x0c);
c_send(0x80);
}
void clrlcd(void) // clr LCD
{
delay();
c_send(0x01);
}
void pos(unsigned char pos) //設定顯示位置
{
c_send(pos | 0x80);
}
void c_send(unsigned char y) //發命令
{
unsigned char i;
EN=1;
RS=0;
RW=0;
for(i=0;i<8;i++)
{
if(_crol_(y,i)&0x80)
DATA=1;
else
DATA=0;
CLK=0;
CLK=1;
}
EN=0;
delay();
}
void d_send(unsigned char x) //發數據
{
unsigned char i;
EN=1;
RS=1;
RW=0;
for(i=0;i<8;i++)
{
if(_crol_(x,i)&0x80)
DATA=1;
else
DATA=0;
CLK=0;
CLK=1;
}
EN=0;
delay();
}
void ret(void) //初始化計數器
{ TMOD=0x22; //設置定時器計數器1為工作方式2
TH0=0xc6; //設置計數初值高字節
TL0=0xc6; //設置計數初值低字節
count=0;
IE=0x00; //禁止中斷
TF0=0; //溢出標誌位清零
TR0=1; //打開定時器1
rect_wave=1;
EA=1; //打開中斷
IP=0x01; //外部中斷0為高中斷優先級
IT0=0; //外部中斷低電平觸發シ?
EX0=1;
}
void retcont(void)
{ TF0=0; //溢出標誌位清零
TR0=1; //打開定時器1
EA=1; //打開中斷
IP=0x01; //外部中斷0為高中斷優先級
IT0=0; //外部中斷下降沿觸發
EX0=1;
rect_wave=1;
}
/**************主程序************/
void main(void)
{ rect_wave=0;
reset();
l_delay(10);
ret();
init();
math();
for(;;)
{
if(TF0)
{
time0over();
}
work();
}
}