蓝桥杯第四届省赛模拟智能灌溉

第四届省赛主要涉及到IIC和DS1302,在官方驱动基础上进行改动。

#include <STC15F2K60S2.h>
#include "ds1302.h"
#include "iic.h"
#define uchar unsigned char
#define uint unsigned int

uchar code tab[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0XBF,0XFF};
uchar code dottab[]={0X40,0X79,0X24,0X30,0X19,0X12,0X02,0X78,0X00,0X10};
uchar yi,er,san,si,wu,liu,qi,ba;

uchar shidu;
uchar yuzhi=50;
uchar jia=0,jian=0;//用作标志位
uchar s7=0,s6=0,s5=0,s4=0;//用作标志位

void Delay1ms(uchar ms);
void display1(uchar yi,uchar er);
void display2(uchar san,uchar si);
void display3(uchar wu,uchar liu);
void display4(uchar qi,uchar ba);
void allinit();
void keyscan();
	
void allinit()
{
	P2=0X80;
	P0=0XFE;//LED L1点亮 自动工作
	
	P2=0XC0;
	P0=0XFF;
	P2=0XE0;
	P0=0XFF;//关闭数码管
	
	P2=0XA0;
	P0=0X00;//关闭继电器 蜂鸣器
}

void main()
{
	allinit();//上电初始化
	DS1302_init();//时间初始化
//  EEPROM_write(0x00,yuzhi);
//	Delay1ms(5);
	yuzhi=EEPROM_read(0x00);
	yi=11,er=11,san=11,si=11,wu=11,liu=0,qi=0,ba=0;
	while(1)
	{
		keyscan();
		DS1302_gettime();
		shidu=AD_read(0x03);//Rb2
//		if(shidu<yuzhi)
//		{
//			P2=0XA0;
//	    P0=0X10;
//		}
//		else
//		{
//		P2=0XA0;
//	  P0=0X00;
//		}
		
	   if(s7==0)
		{
			if(s6==1)
			{
						if(jia==1)
						{
							jia=0;
							yuzhi+=1;
						}
						if(jian==1)
						{
						jian=0;
						yuzhi-=1;
						 }
						
			yi=10,er=10,san=11,si=11,wu=11,liu=11;
			qi=yuzhi/10;ba=yuzhi%10;	
			}
						else if(s6==0)
						{
								yi=time[2]/10;er=time[2]%10;san=10;
								si=time[1]/10;wu=time[1]%10;liu=11;
								qi=shidu%100/10;
								ba=shidu%10;	
										if(shidu<yuzhi)//放在此处阈值调整界面不判断
										{
											P2=0XA0;
											P0=0X10;
										}
										else
										{
										P2=0XA0;
										P0=0X00;
										}
						}
		
		}
		
		else if(s7==1)
		{
//			P2=0X80;
//	    P0=0XFD;
			if((s6==0)&&(shidu<yuzhi))//默认带有提醒功能  s6初始化为0
			{
//			P2=0xa0;
//			P0=0x40;//开蜂鸣器
				if(s5==1)
								{
								P2=0xa0;
								P0=0x50;//开灌溉系统以及蜂鸣器
								}
				else if(s5==0)
								{
									P2=0xa0;
									P0=0x40;//只开蜂鸣器
								}
			}
			
			else if((s6==0)&&(shidu>=yuzhi))
					{
//							P2=0xa0;
//							P0=0x00;
						if(s5==1)
							{
								P2=0xa0;
								P0=0x10;		
							}
						else if(s5==0)
							{
								P2=0xa0;
								P0=0x00;
							}
					}
			if(s6==1)
							{
//								P2=0xa0;
//								P0=0x00;
								if(s5==1)
									{
										P2=0xa0;
										P0=0x10;			
									}
								else if(s5==0)
									{
										P2=0xa0;
										P0=0x00;
									}
							}
		
		
		}
	
		
		
		
		
	 display1( yi, er);
	 display2( san,si);
	 display3( wu, liu);
	 display4( qi, ba);
	}
}

void Delay1ms(uchar ms)		//@12.000MHz
{
	unsigned char i, j;
  uchar k;
	for(k=ms;k>0;k--)
	{
	i = 12;
	j = 169;
	do
	{
		while (--j);
	} while (--i);
	
	}

}


void display1(uchar yi,uchar er)
{
	P2=0XC0;
	P0=0X01;
	P2=0XE0;
	P0=tab[yi];
	Delay1ms(1);
	
	P2=0XC0;
	P0=0X02;
	P2=0XE0;
	P0=tab[er];
	Delay1ms(1);
}

void display2(uchar san,uchar si)
{
	P2=0XC0;
	P0=0X04;
	P2=0XE0;
	P0=tab[san];
	Delay1ms(1);
	
	P2=0XC0;
	P0=0X08;
	P2=0XE0;
	P0=tab[si];
	Delay1ms(1);

}

void display3(uchar wu,uchar liu)
{
	P2=0XC0;
	P0=0X10;
	P2=0XE0;
	P0=tab[wu];
	Delay1ms(1);
	
	P2=0XC0;
	P0=0X20;
	P2=0XE0;
	P0=tab[liu];
	Delay1ms(1);
}

void display4(uchar qi,uchar ba)
{
	P2=0XC0;
	P0=0X40;
	P2=0XE0;
	P0=tab[qi];
	Delay1ms(1);
	
	P2=0XC0;
	P0=0X80;
	P2=0XE0;
	P0=tab[ba];
	Delay1ms(1);

}

void keyscan()
{
	if(P30==0)//手动 自动切换 s7按键
	{
		Delay1ms(5);
		if(P30==0)//按键s7
		{
					if(s7==0)//标志位s7
					{
					s7=1;//切换为手动
					P2=0X80;
					P0=0XFD;
					}
					else if(s7==1)
					{
					s7=0;
					P2=0X80;
					P0=0XFE;
					}
		}
	 while(!P30);
	}
	
	
	if(P31==0)//s6按键
	{
				Delay1ms(5);
	       if(P31==0)
				 {
						  if(s6==0)
							{
							s6=1;
							}
							else if(s6==1)
							{
							s6=0;
							EEPROM_write(0x00,yuzhi);
							}
				 
				 }
				 while(!P31);	 
	}
	
	
		if(P32==0)//s5按键
	{
				Delay1ms(5);
	       if(P32==0)
				 {
					  s5=1;
						jia=1;
				 }
				 	while(!P32);
	}
	
		
	if(P33==0)//s4按键
		{
			Delay1ms(5);
			if(P33==0)
				{
					s5=0;
					jian=1;
				}
			while(!P33);
		}


}



DS1302部分

#include "ds1302.h"
unsigned char time[7];
unsigned char ds[7]={0,30,8,0,0,0,0};
/********************************************************************/ 
/*单字节写入一字节数据*/
void Write_Ds1302_Byte(unsigned char dat) 
{
	unsigned char i;
	SCK = 0;
	for (i=0;i<8;i++) 
	{ 
		if (dat & 0x01) 	// 等价于if((addr & 0x01) ==1) 
		{
			SDA_SET;		//#define SDA_SET SDA=1 /*电平置高*/
		}
		else 
		{
			SDA_CLR;		//#define SDA_CLR SDA=0 /*电平置低*/
		}		 
		SCK_SET;
		SCK_CLR;		
		dat = dat >> 1; 
	} 
}
/********************************************************************/ 
/*单字节读出一字节数据*/
unsigned char Read_Ds1302_Byte(void) 
{
	unsigned char i, dat=0;	
	for (i=0;i<8;i++)
	{	
		dat = dat >> 1;
		if (SDA_R) 	  //等价于if(SDA_R==1)    #define SDA_R SDA /*电平读取*/	
		{
			dat |= 0x80;
		}
		else 
		{
			dat &= 0x7F;
		}
		SCK_SET;
		SCK_CLR;
	}
	return dat;
}

/********************************************************************/ 
/*向DS1302 单字节写入一字节数据*/
void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat)
{ 

	RST_CLR;			/*RST脚置低,实现DS1302的初始化*/
	SCK_CLR;			/*SCK脚置低,实现DS1302的初始化*/

	RST_SET;			/*启动DS1302总线,RST=1电平置高 */
	addr = addr & 0xFE;	 
	Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是写操作,写之前将最低位置零*/	
	Write_Ds1302_Byte((dat/10<<4)|(dat%10));	 /*写入数据:dat*/
	RST_CLR;				 /*停止DS1302总线*/
}

/********************************************************************/ 
/*从DS1302单字节读出一字节数据*/
unsigned char Ds1302_Single_Byte_Read(unsigned char addr) 
{ 
	unsigned char temp,dat1,dat2;
	RST_CLR;			/*RST脚置低,实现DS1302的初始化*/
	SCK_CLR;			/*SCK脚置低,实现DS1302的初始化*/

	RST_SET;	/*启动DS1302总线,RST=1电平置高 */	
	addr = addr | 0x01;	 
	Write_Ds1302_Byte(addr); /*写入目标地址:addr,保证是读操作,写之前将最低位置高*/
	temp=Read_Ds1302_Byte(); /*从DS1302中读出一个字节的数据*/		
	RST_CLR;	/*停止DS1302总线*/
	
	//自己添加
	dat1=temp/16;
	dat2=temp%16;
	temp=dat1*10+dat2;
	
//	RST_CLR;	/*读取完一个字节必须停止DS1302总线,否则出错*/
//	SDA_CLR;
   SD=0;	//(即使IO口P2^3=0)
	
	return temp;
}



//DS1302初始化
void DS1302_init(void)
{
	unsigned char i,add;
	add=0x80;
	Ds1302_Single_Byte_Write(0x8e,0x00);
	for(i=0;i<7;i++)
	{
  Ds1302_Single_Byte_Write(add,ds[i]);
	add=add+2;
	}
  Ds1302_Single_Byte_Write(0x8e,0x80);
}


//获取初始化的时间
void DS1302_gettime(void)
{
	unsigned char i,add;
	add=0x81;
	Ds1302_Single_Byte_Write(0x8e,0x00);
	for(i=0;i<7;i++)
	{
  time[i]=Ds1302_Single_Byte_Read(add);
	add=add+2;
	}
	Ds1302_Single_Byte_Write(0x8e,0x80);
}



#ifndef  __DS1302_H__
#define  __DS1302_H__

#include <STC15F2K60S2.h>
#include<intrins.h>
/********************************************************************/ 
sbit SCK=P1^7;		
sbit SD=P2^3;		
sbit RST=P1^3;
/********************************************************************/ 
/*复位脚*/
#define RST_CLR	RST=0	/*电平置低*/
#define RST_SET	RST=1	/*电平置高*/
/*双向数据*/
#define SDA_CLR	SD=0	/*电平置低*/
#define SDA_SET	SD=1	/*电平置高*/
#define SDA_R	SD	/*电平读取*/	
/*时钟信号*/
#define SCK_CLR	SCK=0	/*时钟信号*/
#define SCK_SET	SCK=1	/*电平置高*/
/********************************************************************/ 
#define ds1302_sec_addr			0x80		//秒数据地址
#define ds1302_min_addr			0x82		//分数据地址
#define ds1302_hr_addr			0x84		//时数据地址
#define ds1302_date_addr		0x86		//日数据地址
#define ds1302_month_addr		0x88		//月数据地址
#define ds1302_day_addr			0x8A		//星期数据地址
#define ds1302_year_addr		0x8C		//年数据地址

#define ds1302_control_addr		0x8Ee		//写保护命令字单元地址
#define ds1302_charger_addr		0x90 		//涓电流充电命令字地址			 
#define ds1302_clkburst_addr	0xBE		//日历、时钟突发模式命令字地址
/********************************************************************/ 

/********************************************************************/ 
/*单字节写入一字节数据*/
extern void Write_Ds1302_Byte(unsigned char dat);
/********************************************************************/ 
/*单字节读出一字节数据*/
extern unsigned char Read_Ds1302_Byte(void);
  
/********************************************************************/ 
/********************************************************************/ 
/*向DS1302单字节写入一字节数据*/
extern void Ds1302_Single_Byte_Write(unsigned char addr, unsigned char dat);
/********************************************************************/ 
/*从DS1302单字节读出一字节数据*/
extern unsigned char Ds1302_Single_Byte_Read(unsigned char addr);

//自己添加函数
extern unsigned char time[7];
extern unsigned char ds[7];
extern void DS1302_init(void);
extern void DS1302_gettime(void);

#endif	 
/********************************************************************/
//		     	END FILE
/********************************************************************/

IIC通信模块,包括EEPROM和PCF8951

/*
  程序说明: IIC总线驱动程序
  软件环境: Keil uVision 4.10 
  硬件环境: CT107单片机综合实训平台(12MHz)
  日    期: 2011-8-9
*/

#include "iic.h"

//总线启动条件
void IIC_Start(void)
{
	SDA = 1;
	SCL = 1;
	somenop;
	SDA = 0;
	somenop;
	SCL = 0;	
}

//总线停止条件
void IIC_Stop(void)
{
	SDA = 0;
	SCL = 1;
	somenop;
	SDA = 1;
}

//应答位控制
void IIC_Ack(unsigned char ackbit)
{
	if(ackbit) 
	{	
		SDA = 0;
	}
	else 
	{
		SDA = 1;
	}
	somenop;
	SCL = 1;
	somenop;
	SCL = 0;
	SDA = 1; 
	somenop;
}

//等待应答
bit IIC_WaitAck(void)
{
	SDA = 1;
	somenop;
	SCL = 1;
	somenop;
	if(SDA)    
	{   
		SCL = 0;
		IIC_Stop();
		return 0;
	}
	else  
	{ 
		SCL = 0;
		return 1;
	}
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{   
		if(byt&0x80) 
		{	
			SDA = 1;
		}
		else 
		{
			SDA = 0;
		}
		somenop;
		SCL = 1;
		byt <<= 1;
		somenop;
		SCL = 0;
	}
}

//从I2C总线上接收数据
unsigned char IIC_RecByte(void)
{
	unsigned char da;
	unsigned char i;
	
	for(i=0;i<8;i++)
	{   
		SCL = 1;
		somenop;
		da <<= 1;
		if(SDA) 
		da |= 0x01;
		SCL = 0;
		somenop;
	}
	return da;
}

//EEPROM写入函数 
void EEPROM_write(unsigned char add,unsigned char dat)
{
		IIC_Start();
		IIC_SendByte(0xa0);
		IIC_WaitAck();
		IIC_SendByte(add);
		IIC_WaitAck();
  	IIC_SendByte(dat);
		IIC_WaitAck();
		IIC_Stop();

}
//EEPROM读取函数 
unsigned char EEPROM_read(unsigned char add)
{
		unsigned char temp;
		IIC_Start();
		IIC_SendByte(0xa0);
		IIC_WaitAck();
		IIC_SendByte(add);
		IIC_WaitAck();
		IIC_Stop();

		IIC_Start();
		IIC_SendByte(0xa1);
		IIC_WaitAck();
	  temp=IIC_RecByte();
		IIC_Stop();
	 
	  return temp;
	
}

//AD转换读取函数  PCF8951地址 0x90 0x91
unsigned char AD_read(unsigned char add)
{
		unsigned char temp;
		IIC_Start();
		IIC_SendByte(0x90);
		IIC_WaitAck();
		IIC_SendByte(add);
		IIC_WaitAck();
		IIC_Stop();

		IIC_Start();
		IIC_SendByte(0x91);
		IIC_WaitAck();
	  temp=IIC_RecByte();
		IIC_Stop();
	  temp=0.39*temp; //满足湿度最大为99%
	  return temp;
	
}


#ifndef _IIC_H
#define _IIC_H

#include <STC15F2K60S2.h>
#include "intrins.h"

#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

//总线引脚定义
sbit SDA = P2^1;  /* 数据线 */
sbit SCL = P2^0;  /* 时钟线 */

//函数声明
void IIC_Start(void); 
void IIC_Stop(void);  
void IIC_Ack(unsigned char ackbit); 
void IIC_SendByte(unsigned char byt); 
bit IIC_WaitAck(void);  
unsigned char IIC_RecByte(void); 
	
//以下为自己添加函数
unsigned char AD_read(unsigned char add);
void EEPROM_write(unsigned char add,unsigned char dat);
unsigned char EEPROM_read(unsigned char add);

#endif

猜你喜欢

转载自blog.csdn.net/weixin_42244181/article/details/87276934