基于15单片机模拟智能灌溉系统——蓝桥杯

              这个是第五届模拟题,难度较大!这个是我做了好久调试到最后开始怀疑硬件的一套题。里面使用了DS1302和IIC总线这两个模块。这两个模块本身不太难,但是它最后涉及蜂鸣器和继电器的控制,会产生各种各样的冲突,调试到最后也会有小问题的存在。冲突的解决最后使用了一个比较明智的做法,我用“与”运算将其整合到了一块。调试程序过程中,还有一个需要注意到的地方,在使用iic总线读取数据时,一定要将定时器关闭再读取,不然读取的数据是有限的,不够精确,不会有实时数据。

              iic的使用也是比较全面,先是使用PCF8591来进行ADC采样,然后的设置过程中,又是用到了EEPROM存储单元,将设置的数值存放进去然后再读取出来进行比较,所以这套试卷的覆盖范围比较广,而且对各方面掌握程度要求较高,难度可想而知。

             我在调试程序过程中对AT24C02有了更深的认识,它的存储的信息可以实现掉电后不丢失,上电后继续使用!这个特性可以用于检测上电次数。例如,将其加入某产品中,来检测产品上电次数,以此来判断商品是否首次打开使用,以防调包!所以我觉得这个功能的特殊功能挺强大!

             闲话不多说,一起来看看实物和程序吧!

 上电后,RTC显示8时30分,当前湿度74

用手旋转电阻,改变湿度大小,继电器工作!

 

利用独立按键对湿度阈值进行设置!

#include "STC15F2K60S2.h"	 //
#include "ds1302.h"
#include "iic.h"
#define  u8 unsigned char

u8 code smg_du[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00}; //0-9 
u8 code smg_wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

#define KEY P3
#define NO_KEY  0xff  //?????????
#define KEY_STATE0  0   //?ж????????
#define KEY_STATE1  1  //??????????
#define KEY_STATE2  2  //???
unsigned char Key_Scan()
{
 static unsigned char key_state=KEY_STATE0; 
 u8 key_value=0,key_temp;
 u8 key1,key2;
 
 P30=0;P31=0;P32=0;P33=0;P34=1;P35=1;P42=1;P44=1;
 if(P44==0)	key1=0x70;
 if(P42==0)	key1=0xb0;
 if(P35==0)	key1=0xd0;
 if(P34==0)	key1=0xe0;
 if((P34==1)&&(P35==1)&&(P42==1)&&(P44==1))	key1=0xf0;
 
 P30=1;P31=1;P32=1;P33=1;P34=0;P35=0;P42=0;P44=0;
 if(P30==0)	key2=0x0e;
 if(P31==0)	key2=0x0d;
 if(P32==0)	key2=0x0b;
 if(P33==0)	key2=0x07;
 if((P30==1)&&(P31==1)&&(P32==1)&&(P33==1))	key2=0x0f;
 key_temp=key1|key2;
 
 switch(key_state)                                
 {
  case KEY_STATE0:
   if(key_temp!=NO_KEY)
   {
    key_state=KEY_STATE1;               
   }
   break;

  case KEY_STATE1:
   if(key_temp==NO_KEY)
   {
    key_state=KEY_STATE0;
   }
   else
   {
   switch(key_temp)                             
    {
		 case 0x77: key_value=4;break;
		 case 0x7b: key_value=5;break;
		 case 0x7d: key_value=6;break;
     case 0x7e: key_value=7;break;
			
		 case 0xb7: key_value=8;break;
		 case 0xbb: key_value=9;break;
		 case 0xbd: key_value=10;break;
     case 0xbe: key_value=11;break;
			
     case 0xd7: key_value=12;break;
		 case 0xdb: key_value=13;break;
		 case 0xdd: key_value=14;break;
		 case 0xde: key_value=15;break;
			
     case 0xe7: key_value=16;break;
		 case 0xeb: key_value=17;break;
		 case 0xed: key_value=18;break;
		 case 0xee: key_value=19;break;	
    }
    key_state=KEY_STATE2;
   }
   break;
	 
   case KEY_STATE2:
   if(key_temp==NO_KEY)
   {
    key_state=KEY_STATE0;
   }
   break;
 }
 return key_value;
}

void Timer_Init(void) //1ms
{
		AUXR |= 0x80;	//1T timer	
		TMOD &= 0xF0;	// 16bit 
		TL0 = 0xCD;		
		TH0 = 0xD4;		
		TF0 = 0;		
		TR0 = 1;		
		ET0 = 1;
		EA=1; 
}

bit key_flag;
bit set_flag;
u8 time_display[8];
u8 set_display[8];
u8 shi,fen,miao;
u8 humidity;
u8 volt;
u8 mode;
u8 humidity_th=50;
bit buzzer_flag,relay_flag;
bit buzzer_beep;

void main(void)
{
		u8 key_val=NO_KEY;
		P2=0xa0;P0=0x00;P2=0x00; // close buzzer and relay
		humidity_th=read_24c02(0xaa);
		set_sfm(8,30,50);
		Timer_Init(); //1ms
		set_display[0]=0x40;set_display[1]=0x40;
		set_display[2]=0x00;set_display[3]=0x00;
		set_display[4]=0x00;set_display[5]=0x00;
		while(1)
		{
		
		 shi=Read_Ds1302(0x85);
		 fen=Read_Ds1302(0x83);
		 miao=Read_Ds1302(0x81);
		 
		time_display[0]=smg_du[shi/16];
		time_display[1]=smg_du[shi%16];	
		time_display[2]=0x40;
		time_display[3]=smg_du[fen/16];
		time_display[4]=smg_du[fen%16];
		time_display[5]=0x00;
		ET0=0;
		humidity=(u8)(read_adc(0x03)/255.0f*99);
	    ET0=1;
		time_display[6]=smg_du[humidity/10];
		time_display[7]=smg_du[humidity%10];

		set_display[6]=smg_du[humidity_th/10];
		set_display[7]=smg_du[humidity_th%10];
		if(mode==1)
		{
		    P2=0X80;P0=~0X02;P2=0X00;
			if(humidity<humidity_th)
			{
			   if(buzzer_beep)
			   buzzer_flag=1;
			}
			else
			{
			   if(buzzer_beep==0)
			   buzzer_flag=0;
			}
		}
		else 
		{
		     P2=0X80;P0=~0X01;P2=0X00;
			 buzzer_flag=0;
			 if(humidity<humidity_th)
			 {
			     relay_flag=1;

			 }
			 else
			 {
			     relay_flag=0;
			 }
		}  
			  if(key_flag) 	//10ms
				{
					 key_flag=0;
					 key_val=Key_Scan();
					 switch(key_val)                       
					 {                                              
							case 4:
							    if(mode==1)
								{
								    relay_flag=0;
								}
								else
								{   
								    if(set_flag);
								    humidity_th--;
								}
							    break;
							case 5:
							     if(mode==1)
								{
								    relay_flag=1;
								}
								else
								{
								     if(set_flag);
								     humidity_th++;
								}
							    break;
							case 6:
							      if(mode==1)
								  {
								      buzzer_beep=~buzzer_beep;
								  }
								  else
								  {
								      set_flag=~set_flag;
									  write_24c02(0xaa,humidity_th);
								  }
							  break;
							case 7:
							  mode++;
							  if(mode==2)
							  {
							      mode=0;
								  buzzer_flag=1;
							  }
							   break;
					 } 
				}
		      if(buzzer_flag==0 && relay_flag==0)
			  {
			       P2=0XA0;P06=0;P04=0;P2=0X00;
			  }
			   if(buzzer_flag==1 && relay_flag==0)
			  {
			       P2=0XA0;P06=1;P04=0;P2=0X00;
			  }
			   if(buzzer_flag==0 && relay_flag==1)
			  {
			       P2=0XA0;P06=0;P04=1;P2=0X00;
			  }
			   if(buzzer_flag==1 && relay_flag==1)
			  {
			       P2=0XA0;P06=1;P04=1;P2=0X00;
			  }
		 }
}

void timer0() interrupt 1  using 1                   
{
	static int key_count=0,smg_count=0,i=0;
	key_count++;smg_count++;
	if(key_count==10)			//10ms
	{
	 key_count=0;
	 key_flag=1;
	}
	
	if(smg_count==3)		//3ms
	{
			smg_count=0;
			P2=0xc0;P0=0;P2=0;				//???
			if(set_flag)
			{
			   P2=0xe0;P0=~set_display[i];P2=0; 
			}
			else
			{
			   P2=0xe0;P0=~time_display[i];P2=0;
			}
			
			P2=0xc0;P0=smg_wei[i];P2=0;
			i++;
			if(i==8) i=0;
	}
}

 

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值