|
這個(gè)是超聲波測(cè)距的程序,用了兩個(gè)超聲波測(cè)距模塊,分別用了兩個(gè)定時(shí)器測(cè)距,然后用液晶顯示屏顯示。
問(wèn)題時(shí)現(xiàn)在這兩個(gè)模塊顯示的數(shù)據(jù)永遠(yuǎn)是一樣的,而且過(guò)一段時(shí)間就死機(jī)了,需要刷新才能重新正常顯示距離。
大神幫看看問(wèn)題出資按哪。
/*****************************************************************************/
#include<reg52.h>
#include<intrins.h>
#define nops {_nop_();_nop_();_nop_();_nop_();}
/******************************引腳及變量的定義****************************/
sbit RS = P2^6; //寄存器選擇位
sbit RW = P2^5; //讀取選擇位
sbit E = P2^7; //使能信號(hào)位
sbit BF = P0^7; //忙碌信號(hào)位
sbit TRIG=P1^7;
sbit ECHO=P3^2;
sbit pmw1=P1^0;
sbit rbq1=P1^1;
sbit pmw2=P1^2;
sbit rbq2=P1^3;
sbit trig=P1^6;
sbit echo=P3^3;
unsigned char code Tab[] = {"0123456789ABCDEF"};
unsigned char code string[] = {"range:2cm--4.5m"};
char ge2,shi2,bai2,ge,shi,bai;
unsigned char x=0;
bit success_flag; //定義測(cè)試成功標(biāo)志位
long distance,dista;
void delay(unsigned char i)//延時(shí) 0.5MS
{
unsigned char k;
for(i;i>0;i--)
for(k=112;k>0;k--);
}
/*********************************************************/
/*********函數(shù)名稱:delay1ms(void) ******************/
/*********函數(shù)功能:延時(shí)1毫秒 ******************/
/*********函數(shù)參數(shù):void ******************/
/*********************************************************/
void delay1ms(void) //誤差 -0.651041666667us
{
char a,b;
for(b=102;b>0;b--)
for(a=3;a>0;a--);
}
/*********************************************************/
/*********函數(shù)名稱:delaynms(char n) ******************/
/*********函數(shù)功能:延時(shí)n個(gè)1毫秒 ******************/
/*********函數(shù)參數(shù):n ******************/
/*********************************************************/
void delaynms(char n)
{
char a;
for(a = 0;a > n;a--)
delay1ms();
}
/*********************************************************/
/*********函數(shù)名稱:BusyTest(void) ******************/
/*********函數(shù)功能:判斷液晶模塊忙碌狀態(tài)******************/
/*********函數(shù)參數(shù):返回值:result ******************/
/*********************************************************/
unsigned char BusyTest()
{
bit result;
RS = 0;
RW = 1; //RS為低電平,RW為高電平時(shí),可以讀狀態(tài)
E = 1; //使能為高電平時(shí)可讀取信息
nops; //延時(shí)40us,給硬件反應(yīng)時(shí)間
result = BF; //將忙碌標(biāo)志位電平賦給result
E = 0; //使能1到0:執(zhí)行指令
return result;
}
/*********************************************************/
/*********函數(shù)名稱:WriteInstruction(char dictate)*******/
/*********函數(shù)功能:將模式設(shè)置指令或顯示地址寫(xiě)入液晶模塊**/
/*********函數(shù)參數(shù):dictate ******************/
/*********************************************************/
void WriteInstruction(char dictate)
{
while(BusyTest() == 1); //如果忙碌標(biāo)志位忙碌則等待 ?
RS = 0;
RW = 0; //RS/RW位同時(shí)為低電平時(shí)可寫(xiě)入指令
E = 0; //使能0到1:寫(xiě)入指令
nops;
P0 = dictate; //將數(shù)據(jù)送入P0口,寫(xiě)入數(shù)據(jù)或地址
nops;
E = 1; //使能0到1:寫(xiě)入指令
nops;
E = 0; //使能1到0:執(zhí)行指令
}
/*********************************************************/
/*********函數(shù)名稱:WriteAddress(char x) *******/
/*********函數(shù)功能:指定字符顯示的實(shí)際地址 ***********/
/*********函數(shù)參數(shù):x ******************/
/*********************************************************/
void WriteAddress(char x)
{
WriteInstruction(x|0x80); //80H+地址碼
}
/*********************************************************/
/*********函數(shù)名稱:WriteData(char y) *******/
/*********函數(shù)功能:將數(shù)據(jù)(字符的標(biāo)準(zhǔn)ASCII碼)寫(xiě)入液晶模塊*/
/*********函數(shù)參數(shù):y ******************/
/*********************************************************/
void WriteData(char y)
{
while(BusyTest() == 1); //如果忙碌標(biāo)志位忙碌則等待
RS = 1;
RW = 0; //RS為高電平,RW為低電平時(shí),可以寫(xiě)入數(shù)據(jù)
E = 0;
P0 = y;
nops;
E = 1;
nops;
E = 0;
}
/*********************************************************/
/*********函數(shù)名稱:LCDInit(void) *******/
/*********函數(shù)功能:液晶模塊初始化 ****************/
/*********函數(shù)參數(shù):void ******************/
/*********************************************************/
void LCDInit(void)
{
delaynms(15); //延時(shí)15毫秒,首次寫(xiě)入液晶指令應(yīng)給反應(yīng)時(shí)間
WriteInstruction(0x38); //顯示模式設(shè)置:16×2顯示,5×7點(diǎn)陣,8位數(shù)據(jù)接口
delaynms(5); //延時(shí)5秒,反應(yīng)時(shí)間
WriteInstruction(0x38);
delaynms(5); //延時(shí)5秒,反應(yīng)時(shí)間
WriteInstruction(0x38);
delaynms(5); //連續(xù)三次,確保初始化成功
WriteInstruction(0x0c); //顯示模式設(shè)置:顯示開(kāi),無(wú)光標(biāo),光標(biāo)不閃爍
delaynms(5);
WriteInstruction(0x06); //顯示模式設(shè)置:顯示光標(biāo)右移,屏幕不移動(dòng)
delaynms(5);
WriteInstruction(0x01); //清屏
delaynms(5);
}
/*********************************************************/
/*********函數(shù)名稱:UART_Send(char dat) *******/
/*********函數(shù)功能:串口發(fā)送函數(shù) ****************/
/*********函數(shù)參數(shù):dat ******************/
/*********************************************************/
void UART_Send()
{
unsigned int i;
TRIG=1;
for(i=3;i>0;i--);
TRIG=0;
TR0=0;
TL0=0;
TH0=0;
while(ECHO==0);
TR0=1;
while(ECHO==1);
TR0=0;
distance=((TH0*256+TL0*12/11.0592))/58;
}
/*********************************************************/
/*********函數(shù)名稱:UART_Init() ***************/
/*********函數(shù)功能:串口初始化函數(shù) ****************/
/*********函數(shù)參數(shù):無(wú) ******************/
/*********************************************************/
void UART_Init()
{
//將TMOD的低4位定時(shí)器0控制部分清零
TMOD=0x11; //設(shè)置定時(shí)器0為方式1
EA=1;
TL0=0x47; //設(shè)置定時(shí)器0初值低8位
TH0=0xFF; //設(shè)置定時(shí)器0初值高8位
TR0=0; //啟動(dòng)定時(shí)器0
ET0=0; //Timer0中斷禁止
TL1=0x47;
TH1=0xFF;
TR1=0;
ET1=0;
PT1=1;
PT0=0;
}
/*********************************************************/
void csb2_Send()
{
unsigned int i;
TRIG=1;
for(i=3;i>0;i--);
TRIG=0;
TR1=0;
TL1=0;
TH1=0;
while(ECHO==0);
TR1=1;
while(ECHO==1);
TR1=0;
dista=((TH0*256+TL0*12/11.0592))/58;
}
/*********函數(shù)名稱:conversion(int8 temp_data) *******/
/*********函數(shù)功能:數(shù)據(jù)轉(zhuǎn)換 ****************/
/*********函數(shù)參數(shù):temp_data ******************/
/*********************************************************/
void conversion(long data1,data2)
{
char ge_data,shi_data,bai_data,GEE,SHII,BAII;
bai_data = data1 / 100; //?
shi_data = (data1 % 100) / 10;
ge_data = (data1 % 10) ;
BAII = data2 / 100; //?
SHII = (data2 % 100) / 10;
GEE = (data2 % 10) ;
EA = 0;
bai = bai_data;
shi = shi_data;
ge = ge_data;
ge2 = GEE;
shi2=SHII;
bai2=BAII;
EA = 1;
}
/*********************************************************/
/*********函數(shù)名稱:main(void) *******/
/*********函數(shù)功能:主函數(shù) ****************/
/*********函數(shù)參數(shù):void ******************/
/*********************************************************/
void main(void)
{
int k;
LCDInit(); //調(diào)用液晶初始化函數(shù)
delaynms(10);
UART_Init();
k = 0;
while(1)
{
pmw1=1;
rbq1=0;
pmw2=1;
rbq2=0;
WriteAddress(0x01);
while(string[k] != '\0')
{
WriteData(string[k]);
k++;
}
UART_Send();
csb2_Send();
conversion(distance,dista);
WriteAddress(0x41); //從第2行第6列開(kāi)始顯示
if(0<dista<1000)
WriteData(Tab[bai2]); //將特定的字符常量寫(xiě)入LCD
WriteData(Tab[shi2]);
WriteData(Tab[ge2]);
WriteData('&');
WriteData('&');
if(distance <= 1000 && distance >= 0)
{
WriteData(Tab[bai]); //將百位數(shù)字的字符常量寫(xiě)入LCD
WriteData(Tab[shi]); //將十位數(shù)字的字符常量寫(xiě)入LCD
WriteData(Tab[ge]); //將個(gè)位數(shù)字的字符常量寫(xiě)入LCD
WriteData('.');
}
else
{
WriteData('-');
WriteData('-');
WriteData('-');
WriteData('-');
WriteData('-');
}
WriteData(' ');
WriteData('c');
WriteData('m');
delaynms(65);
if(30<distance<50)
{
x=(50-distance);
delay(20-x);
pmw1 =0;
rbq1 =0;
delay(x);
}
}
}
|
|