Advertisement

基于51单片机的简易太阳能追踪系统

阅读量:

基于51单片机的简易太阳能追踪系统Proteus仿真如图所示。

系统主控核心为AT89C51单片机;

动作执行部分为两个0-360度舵机;

4个电位器模拟光敏电阻检测阵列;

模拟电压采集部分使用74HC4051+ADC0804组成多通道模式转换器;

采用蜂鸣器+LED组成声光报警电路;

采用外部EEPROM存储器实现掉电存储数据的功能;

显示部分采用LCD1602显示实时的角度信息和电压信息。

运行仿真后蜂鸣器发出蜂鸣声,并在LCD显示器第一行显示4个通道采集到的电压值数据;第二行则显示了2个舵机当前的角度信息

在仿真过程中使用电位器来模拟光敏电阻的行为,在外界光照强度减弱的情况下,则会导致光敏电阻的输出电压发生下降趋势。一旦相应的光敏电阻输出电压降至4.5V以下水平,则会启动对该方向上的舵机执行角度调整操作;这一过程将持续至该电位器电压恢复正常水平之后,则会停止舵机的角度调整操作以完成对太阳光线的有效追踪

每次成功完成位置修正操作后,系统会将当前舵机角码值记录到独立于主控制器的EEPROM模块中,在设备重启运行周期间,系统会从EEPROM模块提取当前设置值,并将其作为基准角码重新配置舵机至指定初始方位

一旦系统的光敏电阻工作状态参数低于预期值且有两组以上的指示,则系统将通过蜂鸣器以及LED指示灯的方式进行报警提示。

部分代码如下:

复制代码
 int main(void)

    
 {
    
 	uchar num[15]={0},n,i;
    
 	
    
 	LCD_Init();							//lcd显示初始化	
    
 	DelayMs(5);							//延时5ms
    
 	LCD_Clear();						//清空显示
    
 	DelayMs(5);							//延时5ms
    
 	ADCOUTPUT=0xff;					//P0口置高电平,准备读数据
    
 	Switch_1 = 0 ;
    
 	Switch_2 = 0 ;					//设置转换通道0
    
 	timer0_init();					//定时器初始化
    
 	error = 0 ;
    
 	error1 = 0 ;						//故障变量清0
    
 	Init_IIC();							//初始化IIC
    
 	angle = read_add(1)<<8|read_add(0);	//读取角度1
    
 	if(angle<0)
    
 		angle= 180;
    
 	if(angle>360)
    
 		angle=180;
    
 	angle1 = read_add(3)<<8|read_add(2);	//读取角度2
    
 	if(angle1<0)
    
 		angle1=180;
    
 	if(angle1>360)
    
 		angle1=180;
    
 	DelayMs(500);					//延时500毫秒
    
 	scnt = 0 ;
    
 	ADC0804Start();				//启动ADC,进行数据转换
    
 	BEE_LED = 0 ;
    
 	Set_DutyCycle_To((angle*D+1)*5);			//控制舵机去指定角度
    
 	Set_DutyCycle_To1((angle1*D+1)*5);		//控制舵机去指定角度
    
 	while(1)
    
 	{	
    
 		if(scnt<1000)				//采样周期计数值
    
 		{
    
 			scnt++;
    
 		}else
    
 		{
    
 			scnt = 0 ;
    
 		}
    
 		if(scnt==0)					//周期开始
    
 		{
    
 			switch(range_temp)
    
 			{
    
 				case 0 : Switch_1 = 0 ; Switch_2 = 0 ; break ;	//切换对应通道
    
 				case 1 : Switch_1 = 1 ; Switch_2 = 0 ; break ;
    
 				case 2 : Switch_1 = 0 ; Switch_2 = 1 ; break ;
    
 				case 3 : Switch_1 = 1 ; Switch_2 = 1 ; break ;
    
 			}	
    
 		}else if(scnt==200)
    
 		{
    
 			ADC0804Start();				//启动ADC,进行数据转换
    
 		}else if(scnt==400)
    
 		{
    
 			_nop_();
    
 			_nop_();
    
 			ADRD=1;								//读数据控制端拉高,准备读取数据
    
 			_nop_();
    
 			ADRD=0;								//读数据控制端拉低,读取数据
    
 			_nop_();
    
 			n=ADCOUTPUT;					//读取转换数据
    
 		}else if(scnt==800)
    
 		{
    
 			switch(range_temp)		//读取对应通道转换结果。并计算实际电压
    
 			{
    
 				case 0 : v1 = BD*n ; range_temp = 1 ; break ;
    
 				case 1 : v2 = BD*n ; range_temp = 2 ; break ;
    
 				case 2 : v3 = BD*n ; range_temp = 3 ; break ;
    
 				case 3 : v4 = BD*n ; range_temp = 0 ; break ;
    
 			}
    
 		}else if(scnt==900)			//对电压进行显示
    
 		{
    
 			num[0]=v1/100%10;				
    
 			num[1]=v1/10%10;
    
 			num[2]=v2/100%10;				
    
 			num[3]=v2/10%10;	
    
 			num[4]=v3/100%10;				
    
 			num[5]=v3/10%10;	
    
 			num[6]=v4/100%10;				
    
 			num[7]=v4/10%10;				
    
 			sprintf(temp,"%d.%d %d.%d %d.%d %d.%d",(int)num[0],(int)num[1],(int)num[2],(int)num[3],(int)num[4],(int)num[5],(int)num[6],(int)num[7]);
    
 			LCD_Write_String(0,0,temp);	//刷新显示数据
    
 			ADRD=1;								//读取数据完毕
    
 			if(buff<10)
    
 			buff ++ ;
    
 		}else if(scnt==950&&buff>8)	
    
 		{
    
 			if(v1<450&&v2>450)		//如果1一侧光线弱
    
 			{
    
 				if(angle<360)				//角度增大
    
 				{
    
 					angle = angle+1 ;
    
 				}
    
 				Set_DutyCycle_To((angle*D+1)*5);	
    
 				error = 0 ;
    
 				ast =0 ;
    
 			}else if(v1>450&&v2<450)	//另外一侧弱。
    
 			{
    
 				if(angle>0)							//角度减小
    
 				{
    
 					angle = angle-1 ;
    
 				}
    
 				Set_DutyCycle_To((angle*D+1)*5);	
    
 				error = 0 ;
    
 				ast =0 ;
    
 			}else if(v1<450&&v2<450)	//如果两侧光线都弱,进行报警,另外一路舵机控制原理类似
    
 			{
    
 				error = 1 ;
    
 			}else 
    
 			{
    
 				if(ast==0)
    
 				{
    
 						ast =1 ;
    
 						write_add(0x00,angle);	 					//将报警阈值写入到EEPROM中,其中低位写入到地址0,高位写入到地址1
    
 						DelayMs(5);
    
 						write_add(0x01,angle>>8);
    
 						DelayMs(5);
    
 				}
    
 			}
    
 			
    
 			if(v3<450&&v4>450)
    
 			{
    
 				if(angle1<360)
    
 				{
    
 					angle1 = angle1+1 ;
    
 				}
    
 				Set_DutyCycle_To1((angle1*D+1)*5);
    
 				error1 = 0 ;			
    
 				ast1 =0 ;				
    
 			}else if(v3>450&&v4<450)
    
 			{
    
 				if(angle1>0)
    
 				{
    
 					angle1 = angle1-1 ;
    
 				}
    
 				Set_DutyCycle_To1((angle1*D+1)*5);	
    
 				error1 = 0 ;	
    
 				ast1 =0 ;	
    
 			}else if(v3<450&&v4<450)
    
 			{
    
 				error1 = 1 ;
    
 			}else 
    
 			{
    
 				if(ast1==0)
    
 				{
    
 						ast1 =1 ;
    
 						write_add(0x02,angle1);	 					//将报警阈值写入到EEPROM中,其中低位写入到地址0,高位写入到地址1
    
 						DelayMs(5);
    
 						write_add(0x03,angle1>>8);
    
 						DelayMs(5);
    
 				}
    
 			}
    
 			num[0]=angle/100%10;				
    
 			num[1]=angle/10%10;
    
 			num[2]=angle%10;
    
 			num[3]=angle1/100%10;				
    
 			num[4]=angle1/10%10;
    
 			num[5]=angle1%10;
    
 			sprintf(temp,"deg1:%d%d%ddeg2:%d%d%d",(int)num[0],(int)num[1],(int)num[2],(int)num[3],(int)num[4],(int)num[5]);
    
 			LCD_Write_String(0,1,temp);	//刷新显示数据
    
 		}
    
 		if(error==1||error1==1)
    
 		{
    
 			BEE_LED = 1 ;
    
 		}else
    
 		{
    
 			BEE_LED = 0 ;
    
 		}
    
 		
    
 		
    
  
    
 		
    
 	}
    
  
    
 }

[基于51单片机的简易太阳能跟踪系统-单片机文档类资源-文库

icon-default.png?t=M85B

以51系列单片机为基础开发的简单太阳能追踪装置-相关资源-文库

全部评论 (0)

还没有任何评论哟~