這個是超聲波測距的程序,用了兩個超聲波測距模塊,分別用了兩個定時器測距,然后用液晶顯示屏顯示。
問題時現在這兩個模塊顯示的數據永遠是一樣的,而且過一段時間就死機了,需要刷新才能重新正常顯示距離。
大神幫看看問題出資按哪。
/*****************************************************************************/
#include<reg52.h>
#include<intrins.h>
#define nops {_nop_();_nop_();_nop_();_nop_();}
/******************************引腳及變量的定義****************************/
sbit RS = P2^6; //寄存器選擇位
sbit RW = P2^5; //讀取選擇位
sbit E = P2^7; //使能信號位
sbit BF = P0^7; //忙碌信號位
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; //定義測試成功標志位
long distance,dista;
void delay(unsigned char i)//延時 0.5MS
{
unsigned char k;
for(i;i>0;i--)
for(k=112;k>0;k--);
}
/*********************************************************/
/*********函數名稱:delay1ms(void) ******************/
/*********函數功能:延時1毫秒 ******************/
/*********函數參數:void ******************/
/*********************************************************/
void delay1ms(void) //誤差 -0.651041666667us
{
char a,b;
for(b=102;b>0;b--)
for(a=3;a>0;a--);
}
/*********************************************************/
/*********函數名稱:delaynms(char n) ******************/
/*********函數功能:延時n個1毫秒 ******************/
/*********函數參數:n ******************/
/*********************************************************/
void delaynms(char n)
{
char a;
for(a = 0;a > n;a--)
delay1ms();
}
/*********************************************************/
/*********函數名稱:BusyTest(void) ******************/
/*********函數功能:判斷液晶模塊忙碌狀態******************/
/*********函數參數:返回值:result ******************/
/*********************************************************/
unsigned char BusyTest()
{
bit result;
RS = 0;
RW = 1; //RS為低電平,RW為高電平時,可以讀狀態
E = 1; //使能為高電平時可讀取信息
nops; //延時40us,給硬件反應時間
result = BF; //將忙碌標志位電平賦給result
E = 0; //使能1到0:執行指令
return result;
}
/*********************************************************/
/*********函數名稱:WriteInstruction(char dictate)*******/
/*********函數功能:將模式設置指令或顯示地址寫入液晶模塊**/
/*********函數參數:dictate ******************/
/*********************************************************/
void WriteInstruction(char dictate)
{
while(BusyTest() == 1); //如果忙碌標志位忙碌則等待 ?
RS = 0;
RW = 0; //RS/RW位同時為低電平時可寫入指令
E = 0; //使能0到1:寫入指令
nops;
P0 = dictate; //將數據送入P0口,寫入數據或地址
nops;
E = 1; //使能0到1:寫入指令
nops;
E = 0; //使能1到0:執行指令
}
/*********************************************************/
/*********函數名稱:WriteAddress(char x) *******/
/*********函數功能:指定字符顯示的實際地址 ***********/
/*********函數參數:x ******************/
/*********************************************************/
void WriteAddress(char x)
{
WriteInstruction(x|0x80); //80H+地址碼
}
/*********************************************************/
/*********函數名稱:WriteData(char y) *******/
/*********函數功能:將數據(字符的標準ASCII碼)寫入液晶模塊*/
/*********函數參數:y ******************/
/*********************************************************/
void WriteData(char y)
{
while(BusyTest() == 1); //如果忙碌標志位忙碌則等待
RS = 1;
RW = 0; //RS為高電平,RW為低電平時,可以寫入數據
E = 0;
P0 = y;
nops;
E = 1;
nops;
E = 0;
}
/*********************************************************/
/*********函數名稱:LCDInit(void) *******/
/*********函數功能:液晶模塊初始化 ****************/
/*********函數參數:void ******************/
/*********************************************************/
void LCDInit(void)
{
delaynms(15); //延時15毫秒,首次寫入液晶指令應給反應時間
WriteInstruction(0x38); //顯示模式設置:16×2顯示,5×7點陣,8位數據接口
delaynms(5); //延時5秒,反應時間
WriteInstruction(0x38);
delaynms(5); //延時5秒,反應時間
WriteInstruction(0x38);
delaynms(5); //連續三次,確保初始化成功
WriteInstruction(0x0c); //顯示模式設置:顯示開,無光標,光標不閃爍
delaynms(5);
WriteInstruction(0x06); //顯示模式設置:顯示光標右移,屏幕不移動
delaynms(5);
WriteInstruction(0x01); //清屏
delaynms(5);
}
/*********************************************************/
/*********函數名稱:UART_Send(char dat) *******/
/*********函數功能:串口發送函數 ****************/
/*********函數參數: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;
}
/*********************************************************/
/*********函數名稱:UART_Init() ***************/
/*********函數功能:串口初始化函數 ****************/
/*********函數參數:無 ******************/
/*********************************************************/
void UART_Init()
{
//將TMOD的低4位定時器0控制部分清零
TMOD=0x11; //設置定時器0為方式1
EA=1;
TL0=0x47; //設置定時器0初值低8位
TH0=0xFF; //設置定時器0初值高8位
TR0=0; //啟動定時器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;
}
/*********函數名稱:conversion(int8 temp_data) *******/
/*********函數功能:數據轉換 ****************/
/*********函數參數: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;
}
/*********************************************************/
/*********函數名稱:main(void) *******/
/*********函數功能:主函數 ****************/
/*********函數參數:void ******************/
/*********************************************************/
void main(void)
{
int k;
LCDInit(); //調用液晶初始化函數
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列開始顯示
if(0<dista<1000)
WriteData(Tab[bai2]); //將特定的字符常量寫入LCD
WriteData(Tab[shi2]);
WriteData(Tab[ge2]);
WriteData('&');
WriteData('&');
if(distance <= 1000 && distance >= 0)
{
WriteData(Tab[bai]); //將百位數字的字符常量寫入LCD
WriteData(Tab[shi]); //將十位數字的字符常量寫入LCD
WriteData(Tab[ge]); //將個位數字的字符常量寫入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);
}
}
}
|