|
#include <reg52.h>
#include <math.h>
#define LCD1602_DB P2
#define uchar unsigned char
#define uint unsigned int
sbit LCD1602_RS = P1^6;
sbit LCD1602_RW = P1^5;
sbit LCD1602_E = P1^4;
uchar code table[]="X:";
uchar code table1[]="Y:";
//液晶數(shù)據(jù)的讀與寫(xiě)控制
uchar num=0;
uchar flag=0; //標(biāo)志位,啟動(dòng)定時(shí)器2
double Ta,Tb,Tc,Td;
int x=0,y=0;
void delay(uint z)
{
uint m,n;
for(m=z;m>0;m--)
for(n=110;n>0;n--);
}
void LcdWaitReady()
{
uchar sta;
LCD1602_DB = 0xFF;
LCD1602_RS = 0;
LCD1602_RW = 1;
do {
LCD1602_E = 1;
sta = LCD1602_DB; //讀取狀態(tài)字
LCD1602_E = 0;
} while (sta & 0x80); //bit7等于1表示液晶正忙,重復(fù)檢測(cè)直到其等于0為止
}
/* 向LCD1602液晶寫(xiě)入一字節(jié)命令,cmd-待寫(xiě)入命令值 */
void LcdWriteCmd(uchar cmd)
{
LcdWaitReady();
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_DB = cmd;
LCD1602_E = 1;
LCD1602_E = 0;
}
/* 向LCD1602液晶寫(xiě)入一字節(jié)數(shù)據(jù),dat-待寫(xiě)入數(shù)據(jù)值 */
void LcdWriteDat(uchar dat)
{
LcdWaitReady();
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_DB = dat;
LCD1602_E = 1;
LCD1602_E = 0;
}
/* 設(shè)置顯示RAM起始地址,亦即光標(biāo)位置,(x,y)-對(duì)應(yīng)屏幕上的字符坐標(biāo) */
void LcdSetCursor(uchar x, uchar y)
{
unsigned char addr;
if (y == 0) //由輸入的屏幕坐標(biāo)計(jì)算顯示RAM的地址
addr = 0x00 + x; //第一行字符地址從0x00起始
else
addr = 0x40 + x; //第二行字符地址從0x40起始
LcdWriteCmd(addr | 0x80); //設(shè)置RAM地址
}
void Init_INT0(void) //外部中斷0初始化
{
EA=1; //總中斷開(kāi)
IT0=1; //為下降沿觸發(fā);如果IT0=0;低電平觸發(fā)
EX0=1; //開(kāi)外部中斷0
}
void Init_INT1(void) //外部中斷0初始化
{
EA=1; //總中斷開(kāi)
IT1=1; //為下降沿觸發(fā);如果IT0=0;低電平觸發(fā)
EX1=1; //開(kāi)外部中斷0
}
//計(jì)數(shù)器0
void InitTimer0() //初始化函數(shù)
{
TMOD|=0x05; //設(shè)置定時(shí)器0工作模式1
TH0=0x0FF; //計(jì)數(shù)器裝初值
TL0=0x0FF;
EA=1; //開(kāi)總中斷
ET0=1; //開(kāi)計(jì)數(shù)器0中斷
TR0=1; //啟動(dòng)定時(shí)器0
}
//計(jì)數(shù)器1
void InitTimer1() //初始化函數(shù)
{
TMOD|=0x50; //設(shè)置定時(shí)器1工作模式1
TH1=0x0FF; //計(jì)數(shù)器裝初值
TL1=0x0FF;
EA=1; //開(kāi)總中斷
ET1=1; //開(kāi)定時(shí)器1中斷
TR1=1; //啟動(dòng)定時(shí)器1
}
//定時(shí)器
void InitTimer2() //初始化函數(shù),打開(kāi)定時(shí)器2
{
TMOD|=0x01; //設(shè)置定時(shí)器2工作模式1
TH2=0; //定時(shí)器裝初值
TL2=0;
EA=1; //開(kāi)總中斷
ET2=1; //開(kāi)定時(shí)器2中斷
TR2=1; //啟動(dòng)定時(shí)器2
}
void printc(int cc) //將阿拉伯?dāng)?shù)字在液晶上準(zhǔn)確顯示
{
if(cc<0)
{
LcdWriteDat('-');
cc=0-cc;
}
LcdWriteDat(cc/100+0x30); //百位
LcdWriteDat(cc%100/10+0x30); //十位
// prints(".");
LcdWriteDat(cc%10+0x30); //個(gè)位
}
void InitLcd1602()
{
LcdWriteCmd(0x38); //16*2顯示,5*7點(diǎn)陣,8位數(shù)據(jù)接口
LcdWriteCmd(0x0C); //顯示器開(kāi),光標(biāo)關(guān)閉
LcdWriteCmd(0x06); //文字不動(dòng),地址自動(dòng)+1
LcdWriteCmd(0x01); //清屏
}
void date(double Ta,double Tb,double Tc,double Td) //定位算法
{
double m1,n1,m2,n2,b1,b2,c1,c2,c3,c4,d1,d2; //計(jì)算中的中間變量
int x1,x2,y1,y2;
c1=0.34*(Ta-Tb); //時(shí)間差到距離差 單位為毫米
c2=0.34*(Ta-Tc);
c3=0.34*(Tc-Td);
c4=0.34*(Tb-Td);
m1=(4*c2)/(c1*3);
n1=(c1*c2-c2*c2+300*300)/600; //計(jì)算中的中間變量
b1=m1*m1+1-(4*200*200)/(c1*c1);
b2=n1*n1+200*200-(c1*c1)/4;
x1=(int)((sqrt((m1*m1*n1*n1-b1*b2))-m1*n1)/b1); //第一組想(x,y)
y1=(int)(m1*x1+n1);
m2=4*c4/(3*c3);
n2=(c3*300*300+c3*c4*c4-c4*c3*c3)/(600*c3);
d1=m2*m2+1-(4*200*200)/(c3*c3);
d2=n2*n2-600*n2+300*300+200*200-(c3*c3)/4;
x2=(int)((sqrt((m2*m2*(n2-300)*(n2-300)-d1*d2))-m2*(n2-300))/d1); //第二組(x,y)
y2=(int)(m2*x2+n2);
x=(int)((x1+x2)/2); //最終的(x,y)(取算數(shù)平均值)
y=(int)((y1+y2)/2);
}
void main()
{
InitLcd1602();
Init_INT0();
Init_INT1();
InitTimer0();
InitTimer1();
TH2=0; //定時(shí)器2裝初值
TL2=0;
x=0;y=0;
while(1)
{
if(flag==1) //第一次外部中斷發(fā)生后打開(kāi)T2
{
InitTimer2();
}
if(flag==4) //第四個(gè)外部中斷發(fā)生后關(guān)掉所有中斷
{
EA=0; //關(guān)總中斷
ET2=0; //關(guān)定時(shí)器2中斷
}
date( Ta,Tb,Tc,Td);
// date( 300,250,300,250);
LcdWriteCmd(0x80); //在1602的第一行上顯示X
for(num=0;num<2;num++)
{
LcdWriteDat(table[num]);
delay(5);
}
//write_data(48);
printc(x); //顯示X的值
delay(5);
LcdWriteCmd(0x80+0x40); //在1602的第二行上顯示Y
for(num=0;num<2;num++)
{
LcdWriteDat(table1[num]);
delay(5);
}
printc(y); //顯示Y的值
delay(5);
}
}
void ex_int0() interrupt 0 //外部中斷0的中斷服務(wù)程序
{
EX0=0; //關(guān)閉外部中斷0
flag++;
Ta=TH2*256+TL2; //讀取定時(shí)器2中的值
}
void ex_int1() interrupt 2 //外部中斷1的中斷服務(wù)程序
{
EX1=0;
flag++;
Tb=TH2*256+TL2; //讀取定時(shí)器2中的值
}
void timer0() interrupt 1 //定時(shí)/計(jì)數(shù)器0中斷服務(wù)程序
{
ET0=0; //關(guān)定時(shí)器0中斷
flag++;
Tc=TH2*256+TL2; //讀取定時(shí)器2中的值
}
void timer1() interrupt 3 //定時(shí)/計(jì)數(shù)器1中斷服務(wù)程序
{
ET1=0; //關(guān)定時(shí)器1中斷
flag++;
Td=TH2*256+TL2;
} |
|