⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 checkdistance.c

📁 本压缩文件主要介绍一获奖的电子设计作品
💻 C
字号:
/*  
**  设计者:蒙林通 ***
**  华信通电子公司  **
**  广东工业大学 *****
** 设计时间:2008/08/15 *
**   ***历时:2天半 ****
*/
#include "reg52.h"
#include "intrins.h"
#include "main.h"
#define uchar unsigned char
#define uint unsigned int
#define sd=0.334
unsigned int distance,tem;
uchar data tdisdata[4];
uchar data disdata[5];
uint tvalue,tempkey;//温度值
uchar tflag;//温度正负标志
sbit en=P2^5;
sbit rs=P2^7;
sbit rw=P2^6;
sbit D0=P1^0;
sbit D1=P1^1;
sbit D2=P1^2;
sbit D3=P1^3;
sbit D4=P1^4;
sbit deep=P3^6;
sbit DQ=P3^5;
sbit LED1=P1^5;
sbit LED2=P1^6;
sbit  move=P1^7;
sbit mode_button=P3^4;
sbit operation_button=P3^5;
uchar code table[]=">>温度: 0000 C";
uchar code table2[]="=>距离:00000mm";
uchar code warn1[7][14]={"->请注意左方!!","->请注意右方!!","->请注意后方!!","->左后轮泥坑!!","->右后轮泥坑!!","->左后轮石头!!","->右后轮石头!!"};
uchar code warn2[]="->车距匀安全!!";
uchar code welcome[]="    提示系统  ";
uchar code direction[5][4]={"左距","右距","后距","左轮","右轮"}	;
uint time,t,kk;
uchar bai,shi,ge,flag,i,j,temp;
unsigned long int shu=0,v; 
 unsigned int back=0;							
/******************************
*延时子程序
******************************/
void delay(uint z)
{
	uint x,y;
	for(y=110;y>0;y--)
	for(x=z;x>0;x--);
}

/****************************
*写指令
****************************/
void write_com(uchar com)
{
	rs=0;
	rw=0;
	P0=com;
	delay(5);
	en=1;
	delay(5);
	en=0;

}
/************************
*写数据
************************/
void write_date(uchar date)
{
	rs=1;
	rw=0;
	P0=date;
	delay(5);
	en=1;
	delay(5);
	en=0;
}

//******************************18B20温度传感程序***************************//

void delay1ms(unsigned int ms)//延时1毫秒(不够精确的)
{unsigned int i,j;
   for(i=0;i<ms;i++)
    for(j=0;j<100;j++);
}


/******************************ds1820程序***************************************/
void delay_18B20(unsigned int i)//延时1微秒
{
   while(i--);
}
void ds1820rst()/*ds1820复位*/
{ unsigned char x=0;
DQ = 1;          //DQ复位
delay_18B20(4); //延时
DQ = 0;          //DQ拉低
delay_18B20(100); //精确延时大于480us
DQ = 1;          //拉高
delay_18B20(40); 
   } 

   uchar ds1820rd()/*读数据*/
{ unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{   DQ = 0; //给脉冲信号
    dat>>=1;
    DQ = 1; //给脉冲信号
    if(DQ)
    dat|=0x80;
    delay_18B20(10);
}
   return(dat);
}
void ds1820wr(uchar wdata)/*写数据*/
{unsigned char i=0;
    for (i=8; i>0; i--)
   { DQ = 0;
     DQ = wdata&0x01;
     delay_18B20(10);
     DQ = 1;
     wdata>>=1;
   }
}
//******************读温度*********************/

 read_temp()/*读取温度值并转换*/
 {
 uchar a,b;
ds1820rst();    
ds1820wr(0xcc);//*跳过读序列号*/
ds1820wr(0x44);//*启动温度转换*/
ds1820rst();    
ds1820wr(0xcc);//*跳过读序列号*/ 
ds1820wr(0xbe);//*读取温度*/ 
a=ds1820rd();
b=ds1820rd();
tvalue=b;
tvalue<<=8;
tvalue=tvalue|a;
    if(tvalue<0x0fff)
   tflag=0;
    else
   {tvalue=~tvalue+1;
tflag=1;
   }
tvalue=tvalue*(0.625);//温度值扩大10倍,精确到1位小数
return(tvalue);
}
/*********************温度显示函数**********************/

 void ds1820disp()//温度值显示

{ uchar flagdat;
     disdata[0]=tvalue/1000+0x30;//百位数
     disdata[1]=tvalue%1000/100+0x30;//十位数
     disdata[2]=tvalue%100/10+0x30;//个位数
     disdata[3]=tvalue%10+0x30;//小数位
    
     if(tflag==0)
     flagdat=0x20;//正温度不显示符号
     else
       flagdat=0x2d;//负温度显示负号:-
     if(disdata[0]==0x30)
    {disdata[0]=0x20;//如果百位为0,不显示
   if(disdata[1]==0x30)
    {disdata[1]=0x20;//如果百位为0,十位为0也不显示
    }
   }

    write_com(0x90+4);
    //write_date(flagdat);//显示符号位
    write_date(disdata[0]);//显示百位
    write_date(disdata[1]);//显示十位 
    write_date(disdata[2]);//显示个位 
    write_date(0x2e);//显示小数点 
    write_date(disdata[3]);//显示小数位
   }

  /////////////////**********************超声波程序**********/////////////
/************************
      *距离数值动态显示
*************************/
void dis_distance(uint add,uint date)
{
	uchar mi,fen,li,bai,shi,ge;
	mi=date/100000;
	fen=date%100000/10000;
	li=date%10000/1000;
	bai=date%1000/100;
	shi=date%100/10;
	ge=date%10;
	write_com(0x88+add);
	write_date(0x30+mi);
	write_date(0x30+fen);
	write_date(0x30+li);
	write_date(0x30+bai);
	write_date(0x30+shi);
	write_date(0x30+ge);
	date=0;	
}

//**************提示注意函娄**************//
dis_warn(char num[])
{  int k;
  write_com(0x98);
   for(k=0;k<14;k++)
    { 
	  write_date(num[k]);
	  }
  }
///////////////////////////////////////////
 dis_direction(char num[])
{  int k;
  write_com(0x88+1);
   for(k=0;k<4;k++)
    { 
	  write_date(num[k]);
	  }
  }
/***************************
*初始化程
***************************/
void init(void)
{

	write_com(0x01);		//清除显示
	write_com(0x02);	    //地址归零
	write_com(0x06);		//进入设定点
	write_com(0x0c);		//显示开关设置
	write_com(0x30);		//功能设定
	write_com(0x80);		//在第一行开始输入
	for(i=0;i<14;i++)		//显示初始化
	{
		write_date(welcome[i]);
	
	}

	write_com(0x90);		//在第一行开始输入
	for(i=0;i<14;i++)		//显示初始化
	{
		write_date(table[i]);
	
	}
    write_com(0x88);		//在第一行开始输入
   	for(i=0;i<14;i++)		//显示初始化
	{
		write_date(table2[i]);
	
	}
	TMOD=0X01;				 //设定定时器为工作方式1
	TH0=0X00;
	TL0=0X00;				 //装初始值
	EA=1;					 //开总中断
	IT1=1;					 //设定外部中断为下降沿触发方式
}
/********************************
*延时方法发送方波
********************************/

void send(unsigned int number)         //左方发送函数
{  if(number==1)
   {
	j=100;
	TH0=0X00;
	TL0=0X00;				  
 	EX1=1;
	TR0=1;						   //开计数器						 
	while(j--)					  //发送2个方波
	{
		D0=!D0;
	    _nop_();	
 		_nop_();
	    _nop_();			
	}						   //开外部中断1
	delay(20);
	}
 else
   if(number==2)
   {
	j=100;
	TH0=0X00;
	TL0=0X00;				  
 	EX1=1;
	TR0=1;						   //开计数器						 
	while(j--)					  //发送2个方波
	{
		D1=!D1;
	    _nop_();	
 		_nop_();
	    _nop_();			
	}						   //开外部中断1
	delay(20);
	}  
 else
   if(number==3)
   {
	j=100;
	TH0=0X00;
	TL0=0X00;				  
 	EX1=1;
	TR0=1;						   //开计数器						 
	while(j--)					  //发送2个方波
	{
		D2=!D2;
	    _nop_();	
 		_nop_();
	    _nop_();			
	}						     //开外部中断1
	delay(20);
	}	
    else
   if(number==4)
   {
	j=100;
	TH0=0X00;
	TL0=0X00;				  
 	EX1=1;
	TR0=1;						   //开计数器						 
	while(j--)					  //发送2个方波
	{
		D3=!D3;
	    _nop_();	
 		_nop_();
	    _nop_();			
	}						   //开外部中断1
	delay(20);
	}
	 else
   if(number==5)
   {
	j=100;
	TH0=0X00;
	TL0=0X00;				  
 	EX1=1;
	TR0=1;						   //开计数器						 
	while(j--)					  //发送2个方波
	{
		D4=!D4;
	    _nop_();	
 		_nop_();
	    _nop_();			
	}						   //开外部中断1
	delay(10);
	}
	IE1=0;					  //延时10ms,等待发送完毕
	if(flag==0)
	{	
		TR0=0;					
		EX1=0;
		TH0=0X00;
		TL0=0X00;
	}							//超过10ms或接收到中断后关外部中断1,防止干扰
	if(TF0==1)						//如果计数器溢出则清0
 {
	 	TF0=0;
	 	TR0=0;
	 	TH0=0X00;
		TL0=0X00;			
 	} 		 
}
   ////// 开机声//////
 void  beep()
 {
  deep=0;
  delay1ms(400);
  deep=1;
  }
// **************	外部中断.驱动小车  ********************//
 void in0() interrupt 1 using 0 
{	
	tem++;
if(tem%2==0)
 move=0;
else
  move=1;


}

/****************************
*外部中断1;处理数据,测出距离 
******************************/	  

void in1() interrupt 2 using 1
{
	IE1=0;
	TR0=0;
	EX1=0; 
	flag=1;
//	T=read_temp();
//	v=331.5+0.607*T;
    time=TH0*256+TL0;
   	shu=(time/100)*17-20;
	TH0=0X00;
	TL0=0X00;
}

 void gotkey(void) {
        if (mode_button==0) {
                delay(5);
                if (mode_button==0) 
				{ 
				 tempkey=1;
				 LED1=0;
				 LED2=1;
				 beep();
				}
        }
        if (operation_button==0) {
                delay(5);
                if (operation_button==0) 
				{tempkey=2;
			    	LED1=1;
				   LED2=0;
				   beep();
				 }
        }
		else tempkey=tempkey;
}
/*****************************
*主程序
******************************/
void main()
{   
	 tem=1;
	tempkey=1;
    LED1=0;
	kk=1;
	beep();
	init();
	seek_play(1);              //播入欢迎语音
     play();
	delay(2000);  
	EX0=1;
	PX0=1;  
while(1)
   { gotkey();
     	read_temp();
       ds1820disp();
     if(tempkey==1)
  {
 
     for(kk=1;kk<4;kk++)
     	{	if(kk==4)
	      kk=0;
		  else
	     	send(kk);
           if(flag==1)						 //如果接收到回波,则进行处理
	    	{	
			dis_direction(&direction[kk-1][0]);	
			dis_distance(3,shu);
		 	delay(100);
			flag=0;	
			if(shu<1000)
			{
			 dis_warn(&warn1[kk-1][0]);
			 seek_play(kk+1);
			 play();
			}
			else
            dis_warn(warn2);
		}
		} 					
	} 
	else if(tempkey==2)

	{	send(3);
	  if(flag==1)
	  {
	    dis_direction(&direction[2][0]);
     	dis_distance(3,shu);
		delay(100);
			flag=0;	
	    if(shu<500)                          //满足条件提示注意后方车辆
		{   
    	
		     dis_warn(&warn1[2][0]);
			 seek_play(4);
			  play();
		  }
			  else
			dis_warn(warn2);
	   }
	    for(kk=4;kk<6;kk++)
     	{	if(kk==6)
	      kk=0;
		  else
	     	send(kk);
           if(flag==1)						 //如果接收到回波,则进行处理
	    	{
          
			dis_direction(&direction[kk-1][0]);	
			dis_distance(3,shu);
				delay(100);
			flag=0;	
			if(shu<100)
			{
			 dis_warn(&warn1[kk+1][0]);
			 seek_play(kk+3);
			 play();
			}
			else 
			   if(shu>200)                   // 满足条件就提示有泥坑
			{  
			 dis_warn(&warn1[kk-1][0]);
			 seek_play(kk+1);
			 play();
			} 
			else
            dis_warn(warn2);
		}
		}
}
}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -