野棠雪枝 2021-01-23 20:17 采纳率: 0%
浏览 607

求大佬看看Proteus仿真单片机电路为啥对输入没反应

编译软件keil4,仿真软件Proteus7.8。keil4编译好的hex写入Proteus中的单片机ADC0808,程序编译无问题。

程序是一个智能光照控制的实现,初始化为自动模式,单片机获取外界光照数值进行计算,控制LED灯的亮度和光照强度保持一致,周围无人时自动关闭。手动模式时,通过加减按键调整LED亮度,无人时也自动关灯。

但在Proteus的仿真中,无论怎样调整加、减、模式切换三个按键单片机都无反应,因为Proteus模拟人体感应很麻烦所以我直接在P3.6接了一个开关控制高低电平,也就是模拟有人/无人状况,但无人时单片机也并不反应,LED灯仍然不关闭。现在觉得可能是输入哪里写错了?但是检查了很多遍也不知道错在哪里……

程序和仿真电路图如下。

/**********智能调光系统
					1.自动模式:根据环境光变化LED灯亮度
					2.手动模式:通过加减按键调整LED亮度
					3.两种模式下均需要通过热释电控制灯的亮灭
*********************/
#include <reg51.h>
#include <ADC0808.H>

#define uchar unsigned char       
#define uint  unsigned  int
#define DUAN P0

code uchar seg7code[10]= { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //????

uchar pdata tt[51];		    //定义空数组用于AD0808取平均值

uchar scale=20,rsd_sec;		//定义占空比比例,热释电计时秒变量
char min,sec;				//定义计时分秒
uchar lum;					//ad0808读出值

bit bdata flag_auto,		//自动切换标志位
          ss,				//闪烁标志位
		  flag_bs,			//报警位标志位
		  flag_rsd;			//热释电动作标志位

sbit ST=P3^0;
sbit OE=P3^1;   
sbit EOC=P3^2; 
sbit ALE=P3^3; 


sbit  LED = P3^4;	//PWM输出
sbit  change= P2^3;	//自动模式切换按键
sbit  add = P2^1;	//加按键
sbit  sub = P2^0;	//减按键
sbit  rsd = P3^6; //热释电
sbit  buzz=P3^7;

void delay(uchar i);

uint read_ADC0808(void)
{
    uint ADC_Value;
    OE=0;   
    ST=0;
    ALE=0;
    ALE=1;
    ST=1;
    ALE=0;
    ST=0;               
    delay(10);
    while(!EOC);        
    OE=1;               
    ADC_Value=P1;           
    OE=0;               
    return ADC_Value;
}
void KEY()
{
	uint lum_mean,lum_all;
	uchar b,c;
	if(change==0)				  //自动切换按键按下
	{
		delay(10);				  //去抖
		if(change==0)			  //再次判断按键按下
		{
			buzz=0;				  //蜂鸣器鸣响
			flag_auto=!flag_auto; //自动模式标志位取反
			if(flag_auto==1)	  //当切换到手动模式时  首先将LED发光比例PWM设置在50%
			scale=20;	
		}
		while(!change) 
			{
			buzz=1; //等待按键释放  松开按键后关闭蜂鸣器、刷新显示
			}
	}
		
	if(flag_auto==0)					//自动模式
	{
			if(flag_rsd==1)					//且有人在范围内时	环境发光强度控制灯光变化
		{
			for(b=0;b<49;b++) 			//将空数组tt[]内数值整体左移一位
			{
				tt[b]=tt[b+1];			//将后一数值放到前一位置
			}
			tt[49]=read_ADC0808();			//将读出的ad0808数值放入tt[49]
			for(c=0;c<50;c++)			//将tt[]内数值相加
			{
				lum_all=lum_all+tt[c];
			}
			lum_mean=lum_all/50;		//将总数/50取出平均值
			lum_all=0;					//将总数清零
			if(lum_mean<=30) 
				scale=1;			   //判断取出平均值大小  小于30  发光强度0%
			else if(lum_mean>=150) 
				scale=41;	   //大于150  发光强度100%
			else 
				scale=((lum_mean-30)/3)+1;		   //其他值时将其计算得到发光强度 (计算目的是为了得到一个1-41之间的数值 控制灯光变化)
		}
		else
		scale=1;					 //没有人在范围内时 将灯光亮度调至0%
	}
	else						  	 //手动模式下
	{
		if(flag_rsd==1)					//且有人在范围内时
		{
			if(add==0)				 //加键按下
			{
				delay(10);
				if(add==0)
				{
					scale++;		  //灯光比例++
					if(scale >= 41)
					scale = 41;
				}
			}
			if(sub==0)				  //减键按下时
			{
				delay(10);
				if(sub==0)
				{
				//	buzz=0;			   //蜂鸣器响
					scale--;		   //灯光比例--
					if(scale < 1)
					scale = 1;
				}
		  }
		}
		else
		scale=1;					 //没有人在范围内时 将灯光亮度调至0%
	}
	
}
	/**********************************************************************
* 名称 : init();
* 功能 : 初始化定时器
* 输入 : 无
* 输出 : 无
***********************************************************************/

void init()
{
	TMOD=0x11;	   //工作方式1
	TH1=0x3c;
	TL1=0xb0;	   //T1赋初值50ms
	TH0=0xff;
	TL0=0xe7;	   //T0赋初值25us	  
	ET0=1;
	ET1=1;		   //打开中断允许开关
	EA=1;		   //中断总开关
	TR0=1;		   //开定时器0 开关
	TR1=0;		   //关定时器0 开关
}

/**********************************************************************
* 名称 : main();
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void main()
{
	init();		  //调用初始化函数
	flag_auto=0;  //初始化自动模式
	rsd=0;		  //热释电引脚置低(有信号时时高电平)
	delay(500);	  //延时500ms后开机

	while(1)	  //大循环
	{
		KEY();		 //调用包函数
			}
}


/**********************************************************************
* 名称 : void time0() interrupt 1
* 功能 : 定时器T0 中断服务函数:PWM脉冲发生函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void time0() interrupt 1
{
	uchar n;
	TH0=0xff;
	TL0=0xe7;		 //重新赋初值
	n++;			 //每25us  n++
	if(n>1)		 //n<设置比例时,打开灯
	{
		LED=1;
	}
	else if(n<=scale)//n大于等于设置比例时 关闭灯
	{
		LED=0;
	}
	if(n==scale)		 //n==40  :25us*40=1ms   1kHZ
	{
		n=0;		 //n=0
	}
	else ;	
	
}


/**********************************************************************
* 名称 : void time1() interrupt 3
* 功能 : 定时器T1 中断服务函数:计时和闪烁控制	  红外热释
* 输入 : 无
* 输出 : 无
***********************************************************************/
void time1() interrupt 3
{
	uchar m;
	TH1=0x3c;
	TL1=0xb0;		 //重新赋初值
	m++;			 //50ms  m++
	if((m==10||m==20)&&0)	  //每过500ms  并且 在设置状态时 
	{
		ss=!ss;						  //闪烁变量取反
	}
	if(m==20)						  //到达1s时
	{
		m=0;						  //m=0
		if(rsd==0)					  //热释电无信号时
		rsd_sec++;					  //热释电计时秒++
		if(rsd_sec<=30&&rsd==1)		  //热释电计时秒小于等于30 并且 热释电有信号时
		{
			rsd_sec=0;				  //将热释电秒清零
			flag_rsd=1;				  //标志位置1 控制AD0808采集数值 调节灯光亮度
		}
		else if(rsd_sec>30&&rsd==0)	  //热释电计时秒大于30 并且 热释电无信号时
		{
			flag_rsd=0;				  //标志位置0 停止ad0808转换 关闭灯光
			rsd_sec=0;				  //热释电计时秒清零
		}		
	}	
}

 

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2022-09-07 16:41
    关注
    不知道你这个问题是否已经解决, 如果还没有解决的话:

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 以帮助更多的人 ^-^
    评论

报告相同问题?

悬赏问题

  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误