链接:https://pan.baidu.com/s/1ab56vyanN9NLMR3jvzaWCg
提取码:85go
复制这段内容后打开百度网盘手机App,操作更方便哦
main.c
#include "main.h"
extern unsigned int key_number;//按键键值
extern unsigned char key_flag;//按键按下标志
extern unsigned char hour,minute;//DS1302的小时和分钟
unsigned char shidu;//湿度
unsigned int shidu_temp;//湿度转换后的
unsigned char yuzhi=50;//阈值
unsigned char code wei[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//位码
unsigned char code duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0xc7,0xc8,0x8c,0xc1,0xbf,0xff,0x7f,0x00};//段码
unsigned char duan_buff[]={0,0,0,0,0,0,0,0};
unsigned int key_s6_flag=0;//按键s6的专属标志
unsigned char mode=1;//模式定义
void main(void)
{
Timer1Init();
Timer0Init();
DS1302_init(0x08,0x30);
close();
while(1)
{
// if(key_s6_flag==0)
// {
// duan_buff_change(key_number);
// led_segment_display();
// }
// else
// {
// if(key_number==8)
// {
// yuzhi+=1;
// duan_buff_change(yuzhi);
// led_segment_display();
// key_flag=0;
// key_number=999;
// }
// if(key_number==12)
// {
// yuzhi-=1;
// duan_buff_change(yuzhi);
// led_segment_display();
// key_flag=0;
// key_number=9999;
// }
// }
//
/********************************************************
对于自动状态
********************************************************/
if(mode==1)
{
shidu=PCF8591(0x03);
shidu_temp=((shidu*1.0)/255*1000+0.5)/10;
DS1302_read();
// if(key_number==4)
// {
// if(key_s6_flag==1)
// {
// key_s6_flag=0;
// }
// key_s6_flag=1;
//
// }
//
if(key_s6_flag==0)
{
duan_buff_change2(shidu_temp%10,shidu_temp/10%10,22,minute%16,minute/16,21,hour%16,hour/16);
}
else
{
/********************************************************
对于自动状态下的阈值调整
********************************************************/
if(key_number==8)
{
yuzhi+=1;
duan_buff_change(yuzhi);
eeprom_write(0x00,yuzhi);
led_segment_display();
key_flag=0;
key_number=999;
}
if(key_number==12)
{
yuzhi-=1;
eeprom_write(0x00,yuzhi);
duan_buff_change(yuzhi);
led_segment_display();
key_flag=0;
key_number=9999;
}
duan_buff_change2(yuzhi%10,yuzhi/10%10,22,22,22,22,21,21);
}
led_segment_display();
/********************************************************
对于自动状态下的自动状态灌溉
********************************************************/
if(shidu_temp<yuzhi)
{
Y5;
P0=0X10;
Y4;
P0=0xfe;
P2&=0X1F;
}
else
{
Y5;
P0=0X00;
Y4;
P0=0xff;
P2&=0X1F;
}
}
/********************************************************
对于手动状态
********************************************************/
if(mode==0)
{
shidu=PCF8591(0x03);//ad采样
shidu_temp=((shidu*1.0)/255*1000+0.5)/10;//转换为湿度值(0-255)对应(0-100)的湿度
DS1302_read();//读DS1302芯片
duan_buff_change2(shidu_temp%10,shidu_temp/10%10,22,minute%16,minute/16,21,hour%16,hour/16);//段码缓存
led_segment_display();
/********************************************************
对于手动状态的s6按键的蜂鸣器控制
********************************************************/
if((key_s6_flag==1)||(shidu_temp<yuzhi))
{
Y5;
P0=0X40;
P2&=0X1F;
key_flag=0;
}
else
{
Y5;
P0=0X00;
P2&=0X1F;
key_flag=0;
}
/********************************************************
对于手动状态的s5按键的继电器控制
********************************************************/
if(key_number==8)
{
Y5;
P0=0X10;
Y4;
P0=0xfd;
P2&=0X1F;
key_flag=0;
}
/********************************************************
对于手动状态的s4按键的继电器控制
********************************************************/
if(key_number==12)
{
Y5;
P0=0X00;
Y4;
P0=0xff;
P2&=0X1F;
key_flag=0;
}
}
}
}
/********************************************************
数码管显示函数
********************************************************/
void led_segment_display()
{
unsigned int num=0;
for(num=0;num<8;num++)
{
Y6;
P0=wei[7-num];
P2&=0X1F;
Y7;
P0=duan[duan_buff[num]];
Delay1ms();
P2&=0X1F;
P0=0XFF;
}
num=0;
}
/********************************************************
数码管段码的缓存区
处理数据方式2
********************************************************/
void duan_buff_change(unsigned int number)
{
duan_buff[0]=number%10;
duan_buff[1]=number/10%10;
duan_buff[2]=number/100%10;
duan_buff[3]=number/1000%10;
duan_buff[4]=number/10000%10;
duan_buff[5]=number/100000%10;
duan_buff[6]=number/1000000%10;
duan_buff[7]=number/10000000%10;
}
/********************************************************
数码管段码的缓存区
处理数据方式2
********************************************************/
void duan_buff_change2(unsigned char d0,d1,d2,d3,d4,d5,d6,d7)
{
duan_buff[0]=d0;
duan_buff[1]=d1;
duan_buff[2]=d2;
duan_buff[3]=d3;
duan_buff[4]=d4;
duan_buff[5]=d5;
duan_buff[6]=d6;
duan_buff[7]=d7;
}
/********************************************************
定时器中断初始化
********************************************************/
void Timer1Init(void) //5毫秒@11.0592MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x00; //设置定时初值
TH1 = 0x28; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
EA=1;
ET1=1;
}
/********************************************************
检测矩阵按键一个按键按两次,但是两次的功能不同
定时器中断服务函数
********************************************************/
void time1(void) interrupt 3
{
/********************************************************
对于按键s7的检测
注意消去key_number的值,避免影响下一次判断,因为这个key_number会一直存储着,
在下一次就又会进入这个判断程序,即使你并没有按下按键
********************************************************/
if(key_number==0)
{
if(mode==0)
{
mode=1;
key_number=9999;
key_flag=0;
}
else
{
mode=0;
key_number=9999;
key_flag=0;
}
}
/********************************************************
对于按键s6的检测
注意消去key_number的值,避免影响下一次判断,因为这个key_number会一直存储着,
在下一次就又会进入这个判断程序,即使你并没有按下按键
********************************************************/
if(key_number==4)
{
if(key_s6_flag==1)
{
key_number=999;
key_s6_flag=0;
key_flag=0;
}
else
{
key_number=999;
key_s6_flag=1;
key_flag=0;
}
}
}
main.h
#ifndef _MAIN_H
#define _MAIN_H
#include "common.h"
#include "ds1302.h"
#include "iic.h"
#include "inter.h"
void duan_buff_change(unsigned int number);
void led_segment_display();
void duan_buff_change2(unsigned char d0,d1,d2,d3,d4,d5,d6,d7);
void Timer1Init(void);
void time1(void);
#endif
common.c
#include "common.h"
/********************************************************
关闭外设
********************************************************/
void close(void)
{
Y4;P0=0XFF;
P2&=0X1F;
Y5;
P0=0X00;
P2&=0X1F;
}
/********************************************************
延时函数
********************************************************/
void Delay1ms() //@11.0592MHz
{
unsigned char i, j;
_nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
common.h
#ifndef _COMMON_H
#define _COMMON_H
#include "STC15F2K60S2.H"
#include "intrins.h"
/********************************************************
锁存器
********************************************************/
#define Y4 P2=(P2&0X1F)|0X80
#define Y5 P2=(P2&0X1F)|0Xa0
#define Y6 P2=(P2&0X1F)|0Xc0
#define Y7 P2=(P2&0X1F)|0Xe0
void close(void);
void Delay1ms() ;
#endif
iic.c
#include "iic.h"
#define somenop {_nop_();_nop_();_nop_();_nop_();_nop_();}
#define SlaveAddrW 0xA0
#define SlaveAddrR 0xA1
//总线引脚定义
sbit SDA = P2^1; /* 数据线 */
sbit SCL = P2^0; /* 时钟线 */
//总线启动条件
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(bit 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 address,unsigned char date)
{
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(address);
IIC_WaitAck();
IIC_SendByte(date);
IIC_WaitAck();
IIC_Stop();
}
/********************************************************
eeprom读出数据
********************************************************/
unsigned char eeprom_read(unsigned char address)
{
unsigned char date;
IIC_Start();
IIC_SendByte(0xa0);
IIC_WaitAck();
IIC_SendByte(address);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0xa1);
IIC_WaitAck();
date=IIC_RecByte();
IIC_Ack(0);
IIC_Stop();
return date;
}
/********************************************************
电位器
********************************************************/
unsigned char PCF8591(unsigned char address)
{
unsigned char date;
IIC_Start();
IIC_SendByte(0x90);
IIC_WaitAck();
IIC_SendByte(address);
IIC_WaitAck();
IIC_Stop();
IIC_Start();
IIC_SendByte(0x91);
IIC_WaitAck();
date=IIC_RecByte();
IIC_Ack(0);
IIC_Stop();
return date;
}
iic.h
#ifndef _IIC_H
#define _IIC_H
#include "common.h"
unsigned char eeprom_read(unsigned char address);
void eeprom_write(unsigned char address,unsigned char date);
unsigned char PCF8591(unsigned char address);
#endif
DS1302.C
#include "ds1302.h"
sbit SCK=P1^7;
sbit SDA=P2^3;
sbit RST = P1^3; // DS1302复位
void Write_Ds1302_Byte(unsigned char temp)
{
unsigned char i;
for (i=0;i<8;i++)
{
SCK=0;
SDA=temp&0x01;
temp>>=1;
SCK=1;
}
}
void Write_Ds1302( unsigned char address,unsigned char dat )
{
RST=0;
_nop_();
SCK=0;
_nop_();
RST=1;
_nop_();
Write_Ds1302_Byte(address);
Write_Ds1302_Byte(dat);
RST=0;
}
unsigned char Read_Ds1302 ( unsigned char address )
{
unsigned char i,temp=0x00;
RST=0;
_nop_();
SCK=0;
_nop_();
RST=1;
_nop_();
Write_Ds1302_Byte(address);
for (i=0;i<8;i++)
{
SCK=0;
temp>>=1;
if(SDA)
temp|=0x80;
SCK=1;
}
RST=0;
_nop_();
RST=0;
SCK=0;
_nop_();
SCK=1;
_nop_();
SDA=0;
_nop_();
SDA=1;
_nop_();
return (temp);
}
/********************************************************
DS1302初始化时间
********************************************************/
void DS1302_init(unsigned char hour,unsigned char minute)
{
Write_Ds1302(0x84,hour);
Write_Ds1302(0x82,minute);
}
unsigned char hour,minute;
/********************************************************
读DS1302
********************************************************/
void DS1302_read(void)
{
hour=Read_Ds1302(0x85);
minute=Read_Ds1302(0x83);
}
DS1302.H
#ifndef __DS1302_H
#define __DS1302_H
#include "common.h"
void DS1302_init(unsigned char hour,unsigned char minute);
void DS1302_read(void);
#endif
inter.c
#include "inter.h"
unsigned int key_number=9999;//按键键值
unsigned char key_flag=0;//按键按下标志
/********************************************************
初始化定时器中断0
********************************************************/
void Timer0Init(void) //5毫秒@11.0592MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x00; //设置定时初值
TH0 = 0x28; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
EA=1;
ET0=1;
}
/********************************************************
定时器0中断服务函数
********************************************************/
void time0(void) interrupt 1
{
key_scan();
}
/********************************************************
矩阵键盘扫描
********************************************************/
void key_scan(void)
{
unsigned char key_x=0;
unsigned char key_y=0;
if(key_flag==0)
{
P3=0x0f;P42=0;P44=0;
if(!P30|!P31|!P32|!P33)
{
if(P30==0) key_y=1;
if(P31==0) key_y=2;
if(P32==0) key_y=3;
if(P33==0) key_y=4;
}
P3=0XF0;P42=1;P44=1;
if(!P34|!P35|!P42|!P44)
{
if(P34==0) key_x=4;
if(P35==0) key_x=3;
if(P42==0) key_x=2;
if(P44==0) key_x=1;
}
if(key_x&&key_y)
{
key_number=4*key_y+key_x-5;
key_flag=1;
while(!P34|!P35|!P42|!P44);
}
else
key_flag=0;
}
}
inter.h
#ifndef _INTER_H
#define _INTER_H
#include "common.h"
void Timer0Init(void);
void time0(void) ;
void key_scan(void);
#endif