这个是超声波测距的程序,用了两个超声波测距模块,分别用了两个定时器测距,然后用液晶显示屏显示。
问题时现在这两个模块显示的数据永远是一样的,而且过一段时间就死机了,需要刷新才能重新正常显示距离。
大神帮看看问题出资按哪。
/*****************************************************************************/
#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);
}
}
}
|