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

📄 lyd.c

📁 基于测距式的超声波测距仪
💻 C
字号:
   
            /*===========================================================================
            
                                    KS0070(44780) 16x2 字符液晶屏驱动演示程序总线方式         晓奇
            =============================================================================
            连接线图:       LCM-------51    LCM-------51    LCM--------51
                            DB0-----P0.0    DB4-----P0.4    RW-------P2.0
                           DB1-----P0.1    DB5-----P0.5    RC-------P2.1
                            DB2-----P0.2    DB6-----P0.6    E--------P2.7 =>74ls00+wr+rd
                          DB3-----P0.3    DB7-----P0.7    VLCD接1K2电阻到GND
           
            [注]:AT89C51的晶振频率为12MHz
            ============================================================================*/
                                                                // 产生汇编文件
           #include <reg51.h>
           #include<intrins.h> //#pragma src      
           
           //========= 变量类型标识的宏定义,大家都喜欢这么做 ==============
            #define Uchar unsigned char
            #define Uint unsigned int
           
            // ================= LCM1602A端口地址定义 =======================
           char xdata Lcd1602CmdPort _at_ 0x8cff;          //E=1 RS=0 RW=0
           char xdata Lcd1602WdataPort _at_ 0x8dff;        //E =1 RS=1 RW=0
           char xdata Lcd1602StatusPort _at_ 0x8eff;       //CS=1 RS=0 RW=1
           
		   
           unsigned long temp1=0;
		   unsigned int dis=0,i;																					 
		   unsigned int counter=0;	  /*等待1ms的计数位										*/
           bit disable_flag; 		  /*距离太远无法测量标志,    1:太远不可测; 0:可测   */
           bit receive_flag;		  /*接收标志位                1:收到;       0:没收到 */
           sbit transmit=P1^1;		  /*发送控制                  1:发;         0:停     */
           sbit reset=P1^2;	          /*接收触发器复位,0复位,下一个1时允许中断,后又必须复位*/

		   
            #define Busy    0x80                                            // 忙判别位
           
            code char exampl[]= "No success!                 ";
			code char examp2[]= "Dis is:       cm";
			code char examp3[]= "Waiting.....";

            void Delay400Ms(void);
            void Delay5Ms(void);
            void LcdWriteData( char dataW );
            void LcdWriteCommand( Uchar CMD,Uchar AttribC );
            void LcdReset( void );
            void Display( Uchar dd );
            void DispOneChar(Uchar x,Uchar y,Uchar Wdata);
            void ePutstr(Uchar x,Uchar y, Uchar code *ptr);
			void DispNumber(Uint Num);
           
            /*=======================================================
             显示字符串
            =======================================================*/
           void ePutstr(Uchar x,Uchar y, Uchar code *ptr) {
           Uchar i,l=0;
                while (ptr[l] >31){l++;};
                for (i=0;i<l;i++) {
                        DispOneChar(x++,y,ptr[i]);
                        if ( x == 16 ){
                                x = 0; y ^= 1;
                        }
                }
        }
           
            /*=======================================================
            演示一行连续字符串,配合上位程序演示移动字串
            =======================================================*/
         void Display( Uchar dd ) {
        
        Uchar i;
                
                for (i=0;i<16;i++) {
        
                        DispOneChar(i,1,dd++);
                        
                        dd &= 0x7f;
                        if (dd<32) dd=32;
                }
        }
           
          /*=======================================================
            显示光标定位
           =======================================================*/
          void LocateXY( char posx,char posy) {
       
       Uchar temp;
      
               temp = posx & 0x0f;//取底四位
               posy &= 0x1;//取最后一位
               if ( posy )temp |= 0x40;
               temp |= 0x80;
               LcdWriteCommand(temp,0);      
       }
           
          /*=======================================================
            按指定位置显示数出一个字符
                                                         

          =======================================================*/
         void DispOneChar(Uchar x,Uchar y,Uchar Wdata) {
       
               LocateXY( x, y );                               // 定位显示地址
               LcdWriteData( Wdata );                  // 写字符
      }
           
           /*=======================================================
           初始化程序, 必须按照产品资料介绍的初始化过程进行
          =======================================================*/
          void LcdReset( void ) {
      
              LcdWriteCommand( 0x38, 0);                      // 显示模式设置(不检测忙信号)
                       Delay5Ms();
               LcdWriteCommand( 0x38, 0);                      // 共三次
                       Delay5Ms();
               LcdWriteCommand( 0x38, 0);
                       Delay5Ms();
       
              LcdWriteCommand( 0x38, 1);                      // 显示模式设置(以后均检测忙信号)
           LcdWriteCommand( 0x08, 1);                  // 显示关闭
               LcdWriteCommand( 0x01, 1);                      // 显示清屏
               LcdWriteCommand( 0x06, 1);                      // 显示光标移动设置
               LcdWriteCommand( 0x0c, 1);                      // 显示开及光标设置
       }
           
          /*=======================================================
           写控制字符子程序: E=1 RS=0 RW=0
           =======================================================*/
           void LcdWriteCommand( Uchar CMD,Uchar AttribC ) {
      
               if (AttribC)  while( Lcd1602StatusPort & Busy );         // 检测忙信号?
               Lcd1602CmdPort = CMD;
       }
                  
           /*=======================================================
           当前位置写字符子程序: E =1 RS=1 RW=0
           =======================================================*/
           void LcdWriteData( char dataW ) {
      
               while( Lcd1602StatusPort & Busy );                                      // 检测忙信号
                Lcd1602WdataPort = dataW;
       }//  
           
           // 短延时
           void Delay5Ms(void)
           {
               Uint i = 5552;
               while(i--);
       }
          
           //长延时
           void Delay400Ms(void)                       
           {
               Uchar i = 5;
               Uint j;
               while(i--)
               {
                       j=7269;
                       while(j--);
               };
      } 

 /*_________________________________________________________________________
 _________________________以下的为自己写的程序______________________________
 ___________________________________________________________________________*/
 //***************************** 延时程序*******************************//			                                                  
void delay(d)//延时d微秒
      {
       while(d--);
      }
 
/*===============================*/
/*系统初始化*/
void system_init(void)               	 
{
  TMOD=0x20;              /* 定时器0工作在方式二,用作自动从装的8位定时器        */
  EA=1;                   /* 开中断允许总开关                                    */
  EX1=1;                  /* 允许外部中断1                                       */
  IT1=1;                  /* 外部中断源1位负条变触发方式                         */

  ET0=1;                  /* 允许定时器T0中断产生                                */
  TR0=0;                  /* 定时器0没开始工作                                   */
  TH0=0x9c;               /* 12M晶振,定时0.1ms,用来控制发波时间,并计算时间间隔*/
  TL0=0x9c;

  ET1=1;                  /* 允许定时器T1中断0产生                               */
  TH1 = 0x00;      				
  TL1 = 0x00;

  transmit=0;	          /*不发波												 */
  for(i=0;i<40000;i++);	  /*延时,使余震停止									 */
  reset=0;	              /*外部电路不能产生中断								 */
}
 
 /*=================================*/
/* 定时器中断0处理程序,用于计算传波时间(等待1ms)*/
void timer0(void) interrupt 1 using 1
{
	counter++;

}

 /*=================================*/
 /* 定时器中断1处理程序,用于计算传波时间(等待1ms)*/
void timer1(void) interrupt 3 
{
    disable_flag=1;

}
 /*===================================*/
/*外部中断1处理程序,接收到回波*/
void int0(void) interrupt 0 using 1 
{
	TR1=0;					 //停止计数器T1计数
	receive_flag=1;			 //接收回波标志置位:收到回波

if(TH1>3)
{
	temp1=TH1*256+TL1;		    //读出计数值,	
	temp1=(temp1*172)/25;			//换算成距离 cm
}

else temp1=0;
	 	
	    
	    TH1 = 0x00;      		
	    TL1 = 0x00;
	    TR1 = 1;	    				//启动T1计数
}

 /*===================================*/
/*显示距离*/
void showdate(unsigned int t)
 {
 
  unsigned int count,play;
  count=t;
  i=10;
  
     while(count&&i>0)
	  { play=count%10;
	    DispOneChar(i,1,play+'0');
	    count=count/10;
		i--;
	   }   
}
/*====================================*/
/*主程序处理*/
void main(void)
{ 
      Delay400Ms();                   // 启动时必须的延时,等待lcm进入工作状态
      LcdReset();					  // 这也是必需的....初始化
      system_init();
	  ePutstr(0,0,exampl);            // 上面一行显示一个预定字符串


  while(1)
  {
        transmit=0;	            //不发波
        for(i=0;i<4000;i++);	//延时,使余震停止
        reset=0;                //外部电路不能产生中断
		TL0=0x9c;	            // 从设定时器初值
		TH0=0x9c;
		counter=0;	 
		TR0=1;
		TR1=1;		            //开始计数
		transmit=1;	            //发波
		while(counter<4);	    //等待0.5ms到来,
		transmit=0;             //停止发波
		while(counter<10);     // 等待1ms到来
		reset=1;		        //外部电路可以产生中断


	if(disable_flag==0)				   /*在测量范围之内*/
	{  
	   if(receive_flag==1)
	      { receive_flag=0;
      		    

		    for(i=0;i<16;i++)	   DispOneChar(i,0,examp2[i]);
	        for(i=0;i<16;i++)	   DispOneChar(i,1,' ');
	        dis=temp1;
            showdate(dis); 
	        delay(60000);
		  }
		else
		{          for(i=0;i<16;i++)	  DispOneChar(i,0,examp3[i]);
		       	   for(i=0;i<16;i++)	   DispOneChar(i,1,' ');
		}
	 }  
									   
	
	  else 		  /*不在测量范围之内*/
			    {  
				   for(i=0;i<16;i++)	  DispOneChar(i,0,exampl[i]);
		       	   for(i=0;i<16;i++)	   DispOneChar(i,1,' ');
				   disable_flag=0;
		        }                     
    }
}

⌨️ 快捷键说明

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