【Proteus仿真】基于SRF04超声波,LCD1602显示,距离检测

测试工具

软件:Proteus8.13

仿真器件:蜂鸣器警报,按键输入,SRF04超声波,LCD1602显示。

功能叙述

测量裂缝,短距离到达与否之类

利用SRF04超声波测量与目标距离,并实时显示到LCD1602上,并在下面显示测量到的距离与设置的距离是否符合的结果,测量到的距离>设置的距离,显示false,测量到的距离<设置的距离,显示true。并且在false时,红灯亮。在true时,绿灯亮。独立按键,可以进入设置模式,设置距离。

仿真图示

仿真运行原图

原理图在未运行仿真时,LCD1602有点显示不出,运行了就能显示了。

图中在SRF04超声波的时序中的双线引到,一个示波器上,是为稳定SRF04超声波读取时序时稳定,不加,数据读取可能会出问题。

仿真原图

原图中LCD1602显示数据解释

仿真标记图

设置模式数据解释

仿真设置模式

程序代码

代码预览

代码主体

#include<reg52.h>
#include<intrins.h>
#include <STDIO.H>
typedef unsigned int uint;
typedef unsigned char uchar;
#define lcd P1		  //液晶屏端口定义

/************引脚定义**********************/
sbit rs=P3^3;		 //LCD1602控制端
sbit en=P3^5;

sbit k1=P2^0;    //设置键
sbit k2=P2^1;    //增加键
sbit k3=P2^2;    //减少键

sbit LED1=P3^6;   //蜂鸣器引脚
sbit LED2=P3^7;   //蜂鸣器引脚

sbit  RX=P2^7;	//超声波接收引脚
sbit  TX=P2^6;	//超声波发送引脚


uint  time=0;   //超声波计时
uint  S=0;      //超声波测得的距离
uint  length=0,set_length=300; //缺陷直径,直径阈值
uint  tmp;      //脉冲计数
uchar flag,flag1;     //设置标志
uchar table0[]="  Depth=000cm   ";		//用于液晶显示
uchar table1[]="       XXX      ";
uchar table2[]="000";
uchar table3[]="000.0";

uchar table1_1[]="      true      ";
uchar table1_0[]="      false     ";

void keyscan();

void delay_ms(uint x)    //延时函数  1ms延时
{
	uint i;
	while(x--)for(i=0;i<120;i++);
}
/*************************液晶驱动程序*************************/
void w_cmd(uchar com)		  //lcd1602写命令
{
  rs=0;
  lcd=com;
  en=1;
  delay_ms(5);
  en=0;
}

void w_data(uchar dat)		  //lcd1602读数据
{
  rs=1;
  lcd=dat;
  en=1;
  delay_ms(5);
  en=0;
}

void w_str(uchar *s)       //lcd1602写字符串
{
    while(*s)  w_data(*s++);
}

void lcd_int()		     //lcd1602初始化
{
  en=0;
  w_cmd(0x38);
  w_cmd(0x0c);
  w_cmd(0x06);
  w_cmd(0x01);
  w_cmd(0x80+0x00);
  w_str(table0);
  w_cmd(0xc0+0x00);
  w_str(table1);
}


/*********************传感器识别函数******************/
void keyscan()
{
	
	if(k1==0)   //设置
	{
		delay_ms(5);  //延时
		if(k1==0)
		{
			while(!k1);
			flag=!flag;
			flag1=0;
		}
	}
	if(flag)
	{
		if(k2==0)    //增加
		{
			delay_ms(5);  //延时
			if(k2==0)
			{
				while(!k2);
				set_length=set_length+10;
				if(set_length>9990) set_length=9990;   //限幅
			}
		}
		if(k3==0)    //减少
		{
			delay_ms(5);  //延时
			if(k3==0)
			{
				while(!k3);
				set_length=set_length-10;
				if(set_length<10) set_length=10;     //限幅
			}
		}
	}
}
/**************************************************************
40KHZ方波
***************************************************************/
void  StartModule() 		         //T1中断用来扫描数码管和计800MS启动模块
  {
	  TX=1;			                 //800MS  启动一次模块
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_();
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  _nop_(); 
	  TX=0;
  }
	/**************************************************************
距离计算函数
***************************************************************/
void Conut(void)
{				  
	 time=TH0*256+TL0;
	 TH0=0;
	 TL0=0;
	 S=(time*1.7)/100;     //算出来是CM
   if(S>999) S=999;
}
/**************************************************************
定时器0初始化函数 
用来计算距离
***************************************************************/
void Time0_init(void)
{
	TMOD |=0x01;		   //设T0为方式1,GATE=1;
	TH0=0;
	TL0=0; 
	TR0=0;  
	ET0=1;             //允许T0中断
	EA=1;			   //开启总中断
}
/**************************************************************
中断用来检测是否超出测量距离
***************************************************************/
void zd0() interrupt 1 		 //T0中断用来计数器溢出,超过测距范围
{
   TH0=0;
	 TL0=0;
}

void Init_timer2()
{
 RCAP2H=(65535-50000)/256;//赋T2初始值
 RCAP2L=(65535-50000)%256;
 TR2=1;	     //启动定时器2
 ET2=1;		 //打开定时器2中断
 EA=1;		 //打开总中断
}
void Timer2() interrupt 5	  //定时器2是5号中断
{
  static uchar t;
   TF2=0;
	 t++;	  //d电机控制计数
	 if(t>=20)  //1s时间到
	 {
		 t=0;
		 length=tmp*10;   //计算缺陷直径
		 if(length>9999)  length=9999;
		 tmp=0;
	 }
	 keyscan();  //按键识别
	
}

/*********************液晶显示******************/
void display()
{
	 if(flag==0)   //正常模式
	 {
			if(flag1==0)
			{
			  w_cmd(0x80+0x00);
				w_str(table0);
				w_cmd(0xc0+0x00);
				w_str(table1);
				flag1=1;
			}
		 table2[0]=S%1000/100+48;      //深度
			table2[1]=S%100/10+48;
			table2[2]=S%10+48;
			w_cmd(0x80+0x08);
			w_str(table2);
			
//			table3[0]=length/1000+48;      //路程
//			table3[1]=length%1000/100+48;
//			table3[2]=length%100/10+48;
//			table3[4]=length%10+48;
//			w_cmd(0xc0+0x06);
//			w_str(table3);
			
			
			if(S<(set_length/10))
			{
				w_cmd(0xc0+0x00);
				w_str(table1_1);
				LED1=0;
				LED2=1;
			}
			else
			{
				w_cmd(0xc0+0x00);
				w_str(table1_0);
				LED1=1;
				LED2=0;
			}
			
	 }
	 else   //设置阈值模式
	 {
		  if(flag1==0)
			{
				w_cmd(0x80+0x00);
				w_str("     SET...     ");
				w_cmd(0xc0+0x00);
				w_str(table1);
				flag1=1;
			}
			table3[0]=set_length/1000+48;      //路程
			table3[1]=set_length%1000/100+48;
			table3[2]=set_length%100/10+48;
			table3[4]=set_length%10+48;
			w_cmd(0xc0+0x06);
			w_str(table3);
	 }
	
}

void handle()   //数据处理函数
{
	StartModule(); //启动超声波
	while(!RX);		//当RX为零时等待
	TR0=1;			    //开启计数
	while(RX);			//当RX为1计数并等待
	TR0=0;				//关闭计数
	Conut();			//计算 
	
//	if(length>set_length)   //大于阈值是缺陷
//	{
//		spk=!spk;   //报警
//		delay_ms(300);  //延时
//	}
//	else
//	 spk=1;    //停止报警
	
}


void main(void)//主函数
{
	Time0_init();   //定时器0初始化
	Init_timer2(); 	//定时器2初始化
	lcd_int();     //液晶初始化
	
	while(1)
	{
	
		
		display();//液晶显示
		handle();
		

			
	}
}

工程源码

链接:https://pan.baidu.com/s/1odytlA38YKHagei0ZIxPyA
提取码:1234

  • 7
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 15
    评论
### 回答1: 如果 Proteus 仿真LCD1602 显示不正常,可能是以下几种情况造成的: 1. LCD1602 模型配置错误,请检查模型的设置是否正确。 2. 代码中 LCD1602 初始化部分存在错误,请检查初始化代码。 3. 代码中 LCD1602 控制部分存在错误,请检查控制代码。 4. 代码中 LCD1602 数据部分存在错误,请检查数据代码。 如果您无法找到问题所在,您可以尝试重新检查您的代码,或者在网上查找其他人遇到类似问题的解决方案。 ### 回答2: 在进行 Proteus 仿真过程中,可能会遇到 LCD1602显示的问题,有几个原因可能导致该问题发生。 首先,可能是 Proteus 软件本身存在问题。在这种情况下,可以尝试更新 Proteus 软件版本,也可以尝试重新安装软件。 其次,可能是电路连接出现了问题。 确认电路中的所有元件和线路都正确连接,没有错误的接线或者短路等情况。 特别是确保LCD 的VSS 引脚,对接地引脚,VDD 引脚,对 + 电源引脚的连接正确无误。 第三种情况,可能是代码中存在问题。LCD1602仿真需要正确的代码来初始化并控制它。例如,确保程序中使用的库文件和指令集正确无误。这包括对延时功能的要求,正确的数据指令等。尽可能保证和实际硬件的接口一致,避免错误的操作。 如果以上方法都没能解决问题,建议使用实际硬件测试,确保硬件工作正常,然后再进行仿真过程,排除其他可能的因素。确保上电、启动项是正常的。此后再进行代码的测试,调试问题。最终实现正确的 LCD1602 显示。 总之,Proteus 仿真LCD1602显示,应该从电路连接、Proteus 软件版本、硬件工作、代码等多个方面进行排查,及早发现和解决问题,最终实现正常的 LCD1602 显示。 ### 回答3: 首先,Proteus是一款常用于电子电路仿真的软件,而LCD1602是一种常用的字符型液晶显示屏。在仿真过程中,有可能遇到LCD1602显示的问题。以下是可能的原因和解决方法: 1. 电路连接错误:检查电路板上LCD1602的引脚是否正确连接到单片机或其他驱动器。确认是否存在接触不良或焊接问题。 2. 缺少初始化:在程序开始时,需要对LCD1602进行初始化,以确保它能够正确地显示字符。检查代码中是否正确添加了初始化代码,且参数设置是否正确。 3. 电压不稳定:检查电源电压是否稳定。如果电源电压不稳定,将影响LCD1602的正常工作,导致不显示字符或显示异常。需要检查电源电压是否满足工作要求,或加入脉冲滤波电路。 4. 软件问题:可能存在程序中的逻辑或语法错误。检查代码中是否有语法错误,或是否写入正确的逻辑,确保程序运行正常。 5. 频率错误:使用的驱动器需要特定的时钟频率。检查时钟频率是否正确,以及时钟信号是否符合驱动器的需求。如果频率错误,将导致不显示显示异常。 6. 背光电路问题:对于背光型液晶显示屏,需要在电路板上接入背光电源。检查背光电路是否正确连接,或背光电源是否稳定。 总之,如果遇到LCD1602显示的问题,需要仔细检查连接、初始化、软件、电压、频率以及背光电路等多个方面,寻找可能的原因,逐一排除,确保电路能够正常运行。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值