蓝桥杯——第四届省赛_模拟智能灌溉系统

一、使用到的模块

数码管、独立按键、LED、继电器、蜂鸣器、eeprom、AD、DS1302

题目要求

在这里插入图片描述
在这里插入图片描述

二、代码部分

实验平台:CT107D
实验芯片:stc15f2k60s2
实验现象:完成题目要求
代码如下

ds1302.c

#include <stc15f2k60s2.h>
#include <intrins.h>

sbit SCK=P1^7;		
sbit SDA=P2^3;		
sbit RST = P1^3;   // DS1302复位												

void Write_Ds1302(unsigned  char temp) 
{
	unsigned char i;
	for (i=0;i<8;i++)     	
	{ 
		SCK=0;
		SDA=temp&0x01;
		temp>>=1; 
		SCK=1;
	}
}   

void Write_Ds1302_Byte( unsigned char address,unsigned char dat )     
{
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1; 	_nop_();  
 	Write_Ds1302(address);	
 	Write_Ds1302(dat);		
 	RST=0; 
}

unsigned char Read_Ds1302_Byte ( unsigned char address )
{
 	unsigned char i,temp=0x00;
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
 	RST=1;	_nop_();
 	Write_Ds1302(address);
 	for (i=0;i<8;i++) 	
 	{		
		SCK=0;
		temp>>=1;	
 		if(SDA)
 		temp|=0x80;	
 		SCK=1;
	} 
 	RST=0;	_nop_();
 	SCK=0;	_nop_();
	SCK=1;	_nop_();
	SDA=0;	_nop_();
	SDA=1;	_nop_();
	return (temp);			
}

void set_sfm(unsigned char shi,unsigned char fen,unsigned char miao)
{
	Write_Ds1302_Byte(0x8e,0x00);//关闭保护位
	Write_Ds1302_Byte(0x80,(miao/10)*16+miao%10);//设置秒
	Write_Ds1302_Byte(0x82,(fen/10)*16+fen%10);//设置分
	Write_Ds1302_Byte(0x84,(shi/10)*16+shi%10);//设置小时
	Write_Ds1302_Byte(0x8e,0x80);//打开保护位
}

ds1302.h

#ifndef __DS1302_H
#define __DS1302_H

void Write_Ds1302(unsigned char temp);
void Write_Ds1302_Byte( unsigned char address,unsigned char dat );
unsigned char Read_Ds1302_Byte( unsigned char address );
void set_sfm(unsigned char shi,unsigned char fen,unsigned char miao);
#endif

iic.c

#include "stc15f2k60s2.h"
#include "intrins.h"

#define DELAY_TIME 5

#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1

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

void IIC_Delay(unsigned char i)
{
    do{_nop_();}
    while(i--);        
}
//总线启动条件
void IIC_Start(void)
{
    SDA = 1;
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SDA = 0;
    IIC_Delay(DELAY_TIME);
    SCL = 0;	
}

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

//发送应答
void IIC_SendAck(bit ackbit)
{
    SCL = 0;
    SDA = ackbit;  					// 0:应答,1:非应答
    IIC_Delay(DELAY_TIME);
    SCL = 1;
    IIC_Delay(DELAY_TIME);
    SCL = 0; 
    SDA = 1;
    IIC_Delay(DELAY_TIME);
}

//等待应答
bit IIC_WaitAck(void)
{
    bit ackbit;
	
    SCL  = 1;
    IIC_Delay(DELAY_TIME);
    ackbit = SDA;
    SCL = 0;
    IIC_Delay(DELAY_TIME);
    return ackbit;
}

//通过I2C总线发送数据
void IIC_SendByte(unsigned char byt)
{
    unsigned char i;

    for(i=0; i<8; i++)
    {
        SCL  = 0;
        IIC_Delay(DELAY_TIME);
        if(byt & 0x80) SDA  = 1;
        else SDA  = 0;
        IIC_Delay(DELAY_TIME);
        SCL = 1;
        byt <<= 1;
        IIC_Delay(DELAY_TIME);
    }
    SCL  = 0;  
}

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

void write_eeprom(unsigned char add,unsigned char date)
{
	IIC_Start();//启动总线
	IIC_SendByte(0xa0);//发送设备地址,第八位为0所以为写
	IIC_WaitAck();//等待应答
	IIC_SendByte(add);//发送数据地址
	IIC_WaitAck();//等待应答
	IIC_SendByte(date);//发送数据
	IIC_WaitAck();//等待应答
	IIC_Stop();//停止总线
}

unsigned char read_eeprom(unsigned char add)
{
	unsigned char temp;//定义变量temp用来获得eeprom中的数据
	EA = 0;//关闭中断,中断可能会影响总线时序
	IIC_Start();//开启总线
	IIC_SendByte(0xa0);
	//发送设备地址,第八位为0所以为写,因为读取的时候为读取现在的地址加一,所以要发送现在写的地址进去
	IIC_WaitAck();//等待应答
	IIC_SendByte(add);//发送数据地址
	IIC_WaitAck();//等待应答

	IIC_Start();//开启总线
	IIC_SendByte(0xa1);//发送设备地址,第八位为1所以为读,读取的地址为刚刚我们写入的地址
	IIC_WaitAck();//等待应答
	temp = IIC_RecByte();//读取数据
	IIC_WaitAck();//等待应答
	IIC_Stop();//停止总线
	EA = 1;//打开中断
	return temp;//返回temp
}

void init_adc(unsigned char add)
{
	IIC_Start();
	IIC_SendByte(0x90);
	IIC_WaitAck();
	IIC_SendByte(add);
	IIC_WaitAck();
	IIC_Stop();
}

unsigned char read_adc()
{
	unsigned char dat;
	EA = 0;
	IIC_Start();
	IIC_SendByte(0x91);
	IIC_WaitAck();
	dat = IIC_RecByte();
	IIC_WaitAck();
	IIC_Stop();
	EA = 1;
	return dat;
}

iic.h

#ifndef _IIC_H
#define _IIC_H

void IIC_Start(void); 
void IIC_Stop(void);  
bit IIC_WaitAck(void);  
void IIC_SendAck(bit ackbit); 
void IIC_SendByte(unsigned char byt); 
unsigned char IIC_RecByte(void); 

void write_eeprom(unsigned char add,unsigned char date);
unsigned char read_eeprom(unsigned char add);
void init_adc(unsigned char add);
unsigned char read_adc();

#endif

main.c

#include<stc15f2k60s2.h>
#include<ds1302.h>
#include<iic.h>

#define uchar unsigned char
#define uint  unsigned int

sbit buzz = P0^6;
sbit relay = P0^4;

bit mode = 1;//1为自动,0为手动
bit read_ad = 0;
bit buzz_open_flag = 1;
bit open_flag = 0;
bit set_flag = 0;
bit waring_flag = 0;

uchar duan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00,0x40};
uchar disbuff[8];

uchar trg,cont;
uchar shi_temp,fen_temp;
uchar shi,fen;
uchar shidu;
uchar sdyz=50;

void keyscan()
{
	uchar keydate = P3^0xff;
	trg = keydate&(keydate^cont);
	cont = keydate;
}

void keyfun()
{
	if(trg == 0x01)
	{
		mode = ~mode ;
	}

	//手动模式
	if((trg == 0x02)&&(mode == 0))
	{
		buzz_open_flag = ~buzz_open_flag;	
	}

	if((trg == 0x04)&&(mode == 0))
	{
		open_flag = 1;
	}
	
	if((trg == 0x08)&&(mode == 0))
	{
		open_flag = 0;
	}

	//自动模式
	if((trg == 0x02)&&(mode == 1))
	{
		set_flag = ~set_flag;
		
		if(set_flag == 0)
		{
			write_eeprom(0x01,sdyz);				
		}
		
		if(set_flag == 1)
		{
			sdyz = read_eeprom(0x01);
		}			
	}

	if((trg == 0x04)&&(mode == 1))
	{
		if(sdyz==99)
		sdyz=99;
		else
		sdyz++;
	}
	
	if((trg == 0x08)&&(mode == 1))
	{
		if(sdyz==0)
		sdyz=0;
		else
		sdyz--;
	}			
}

void shownum()
{
	if((set_flag == 1)&&(mode == 1))
	{
		disbuff[0] = 17;
		disbuff[1] = 17;
		disbuff[2] = 16;
		disbuff[3] = 16;
		disbuff[4] = 16;
		disbuff[5] = 16;
		disbuff[6] = sdyz/10;
		disbuff[7] = sdyz%10;		
	}

	else 
	{
	disbuff[0] = shi/10;
	disbuff[1] = shi%10;
	disbuff[2] = 17;
	disbuff[3] = fen/10;
	disbuff[4] = fen%10;
	disbuff[5] = 16;
	disbuff[6] = shidu/10;
	disbuff[7] = shidu%10;	
	}
}

void display()
{
	static uchar index;

	P2 = P2&0x1f|0xe0;
	P0 = ~0xff;
	P2 = P2&0x1f;
	
	P2 = P2&0x1f|0xc0;
	P0 = 1<<index;
	P2 = P2&0x1f;
	
	P2 = P2&0x1f|0xe0;
	P0 = ~duan[disbuff[index]];
	P2 = P2&0x1f;
	
	index++;
	index &= 0x07;	
}

void LED()
{
	if(mode == 0)
	{
	P2 = P2&0x1f|0x80;
	P0 = ~0x02;
	P2 = P2&0x1f;	
	}

	if(mode == 1)
	{
	P2 = P2&0x1f|0x80;
	P0 = ~0x01;
	P2 = P2&0x1f;	
	}
}

void set_fucker()
{
	if((buzz_open_flag == 0)&&(open_flag == 0))
	{
		P2 = P2&0x1f|0xa0;
		buzz = 0;
		relay = 0;
		P2 = P2&0x1f;
	}

	if((buzz_open_flag == 0)&&(open_flag == 1))
	{
		P2 = P2&0x1f|0xa0;
		buzz = 0;
		relay = 1;
		P2 = P2&0x1f;
	}

	if((buzz_open_flag == 1)&&(waring_flag == 1)&&(mode == 0)&&(open_flag == 0))
	{
		P2 = P2&0x1f|0xa0;
		buzz = 1;
		relay = 0;
		P2 = P2&0x1f;
	}

	if((buzz_open_flag == 1)&&(waring_flag == 1)&&(mode == 0)&&(open_flag == 1))
	{
		P2 = P2&0x1f|0xa0;
		buzz = 1;
		relay = 1;
		P2 = P2&0x1f;
	}

	if((buzz_open_flag == 1)&&(waring_flag == 0)&&(open_flag == 0))
	{
		P2 = P2&0x1f|0xa0;
		buzz = 0;
		relay = 0;
		P2 = P2&0x1f;
	}

	if((buzz_open_flag == 1)&&(waring_flag == 0)&&(open_flag == 1))
	{
		P2 = P2&0x1f|0xa0;
		buzz = 0;
		relay = 1;
		P2 = P2&0x1f;
	}
}

void drive()
{
		if(shidu<sdyz)	waring_flag = 1;	

		else waring_flag = 0;

		if((mode == 1)&&(shidu<sdyz))	open_flag = 1;

		if((mode == 1)&&(shidu>=sdyz))   open_flag = 0;	
}

void Timer0Init(void)		//1毫秒@11.0592MHz
{
	AUXR |= 0x80;		//定时器时钟1T模式
	TMOD &= 0xF0;		//设置定时器模式
	TL0 = 0xCD;		//设置定时初值
	TH0 = 0xD4;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;
	EA = 1;
}

void time1() interrupt 1
{
	static uint count;
	display();
	keyscan();
	keyfun();
		
	if(++count == 500)
	{
		read_ad = 1;
		count = 0;
		set_fucker();
		drive();
	}	
}

void main()
{	
	Timer0Init();
	set_sfm(8,30,0);
	init_adc(0x03);
	
	while(1)
	{
		shownum();
		LED();
		
		shi_temp = Read_Ds1302_Byte(0x85);
		fen_temp = Read_Ds1302_Byte(0x83);

		shi = shi_temp/16*10+shi_temp%16;
		fen = fen_temp/16*10+fen_temp%16;

		if(read_ad == 1)
		{
			shidu = read_adc();
			shidu = shidu/255.0f*99;
			read_ad = 0;
		}
	}
}

猜你喜欢

转载自blog.csdn.net/FuckerGod/article/details/104255530
今日推荐