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

基于51单片机的简易太阳能追踪系统_第1张图片

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

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

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

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

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

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

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

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

基于51单片机的简易太阳能追踪系统_第2张图片

        运行仿真后蜂鸣器会响一声,LCD显示器的第一行上会显示出4个通道采集到的电压值;第二行显示出2个舵机的初始角度。

基于51单片机的简易太阳能追踪系统_第3张图片

        仿真中利用电位器模拟光敏电阻,设定当光线变弱时光敏电阻的输出电压会降低。当对应光敏电阻输出电压低于4.5V时,系统会控制相应方向的舵机进行角度变换,直到该电位器电压恢复后系统停止舵机的角度变换,从而达到追踪阳光的目的。

基于51单片机的简易太阳能追踪系统_第4张图片

        每一次成功矫正位置后,系统都会将舵机当前的角度值存储到外部的EEPROM中,下一次重启运行时会从EEPROM中读取出该角度,并将舵机设置为该初始角度。

基于51单片机的简易太阳能追踪系统_第5张图片

        当系统的光敏电阻输出电压有两组以上小于设定值时,系统会通过蜂鸣器和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单片机的简易太阳能跟踪系统-单片机文档类资源-CSDN文库icon-default.png?t=M85Bhttps://download.csdn.net/download/xitianqu/86977414

你可能感兴趣的:(Proteus仿真,51单片机,DIY,51单片机,嵌入式硬件,单片机)