#include<reg52.h>
#include<iic.h>
#include<onewire.h>
#include<ds1302.h>
#define uchar unsigned
//sfr P4 = 0xC0;//矩阵按键
sfr AUXR=0X8E;//定时器
/************需要的函数*************/
void WS();
void Scan();
void HC573(uchar t);
void SMG2(uchar z,uchar x,uchar c,uchar v,uchar b,uchar n,uchar m,uchar a);
void SMG(uchar addr,uchar value); //第(addr-1)个数码管显示的内容
void Delay(int t); //延迟
void all_SMG(); //消隐功能
//定时器0为测频率
void Timer1Init(void);
/**************下面为功能的选择一般选其中的部分****************/
//读温度
void Read_T();
//时钟的写和读
void DS1302_Config();
void Read_DS1302();
/***********初始化值****************/
uchar shuzi[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,0x00,0x40};//0~9正常的数字 10~19带小数的数 20为熄灭
//21为-提示符,22以后可以自己加
uchar yi,er,san,si,wu,lu,qi,ba;
//数码管显示的内容
uchar T_wendu[9];
uchar state=1,T_jiange=1,flag_led=1,u=0,flag_t=0;
//控制的页面
uchar led=0xff;
//led的显示
int temp,t1=0;
//定时器一的计数;temp为温度
//时钟这里先不用时钟
uchar Write_DS1302_add[8]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
uchar Read_DS1302_add[8]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
uchar Timer[8]={0x50,0x59,0x23,0x00,0x00,0x00,0x00};
//独立按键
sbit S4=P3^3;
sbit S5=P3^2;
sbit S6=P3^1;
sbit S7=P3^0;
bit flag4=1;
bit flag5=1;
bit flag6=1;
bit flag7=1;
/**********************按键扫描***************************/
void Scan()
{
/*4 */ if(S4==0) //按下时候扫描
{
Delay(10); //消抖
if(S4==0) //消抖
{
if(flag4!=0) //flag4不按下时候为1按下一瞬间进入下面程序
{
flag4=0; //flag4为0
switch(state) //看是在什么模式的情况下按下的S4
{
case 1:
if(T_jiange==1) {T_jiange=5;}
else if(T_jiange==5) {T_jiange=30;}
else if(T_jiange==30){T_jiange=60;}
else if(T_jiange==60){T_jiange=1;}
break;
}
}
}
}
else
{
flag4=1; //不按时候归1
}//4
/*5 */ if(S5==0)
{
Delay(10);
if(S5==0)
{
if(flag5!=0)
{
flag5=0;
switch(state)
{
case 1:EA=1;ET1=1;state=2; break;//进入2状态并打开中断
case 2: break;
case 3: break;
}
}
}
}
else
{
flag5=1;
}//5
/*6 */ if(S6==0)
{
Delay(10);
if(S6==0)
{
if(flag6!=0)
{
flag6=0;
switch(state)
{
case 1: break;
case 2: break;
case 3: if(flag_led==1) flag_led=0;
else if(flag_led==0) u++;
if(u==10) { u=0;} break;
}
}
}
}
else
{
flag6=1;
}//6
/*7 */ if(S7==0)
{
Delay(10);
if(S7==0)
{
if(flag7!=0)
{
flag7=0;
switch(state)
{
case 1: break;
case 2: break;
case 3: state=1;u=0;break;
}
}
}
}
else
{
flag7=1;
}//7
}
/***************主函数*******************/
void main()
{
WS(); //关闭外设
Timer1Init(); //定时器初始,定时器0频率看情况
//上面那个是复制软件的补充缺少部分
DS1302_Config();
//时钟初始化看情况
while(1)
{
Scan(); //按键的功能
Read_DS1302();
Read_T();
switch(state)//选择模式显示内容
{
case 1:yi=20;er=20;san=20;si=20;wu=20;lu=21;qi=T_jiange/10%10;ba=T_jiange%10;break;
case 2:yi=Timer[2]/16%16;er=Timer[2]%16;
if(Timer[0]%2==0)san=21;
else san=20;
si=Timer[1]/16%16;wu=Timer[1]%16;
if(Timer[0]%2==0)lu=21;
else lu=20;
qi=Timer[0]/16%16;ba=Timer[0]%16;break;
case 3:if(flag_led==1)
{
if(Timer[0]%2==0) led=0xfe;
else led=0xff;
}
else {led=0xff;}
yi=21;er=u/10%10;san=u%10;si=20;wu=20;lu=21;qi=T_wendu[u]/10%10;ba=T_wendu[u]%10;break;
}
P0=led;HC573(4);HC573(0); //led部分
SMG2(yi,er,san,si,wu,lu,qi,ba);//数码管显示
}
}
/************定时器*************/
void Timer1Init(void) //2毫秒@11.0592MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x9A; //设置定时初值
TH1 = 0xA9; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
}
void Time1() interrupt 3
{
t1++;
if(t1==T_jiange*500&&u<=9&&state==2) //2*500 1s
{
T_wendu[u]=temp;
u++; t1=0;
}
else if(u==10)
{state=3;ET1=0;u=0;t1=0;flag_led=1;}
}
/********必备基本的功能设置**********/
void HC573(uchar t)
{
switch(t)
{
case 0:P2=0X00;break; //关
case 4:P2=P2&0X1F|0X80;break;//led
case 5:P2=P2&0X1F|0XA0;break;//蜂鸣器继电器
case 6:P2=P2&0X1F|0XC0;break;//位选
case 7:P2=P2&0X1F|0XE0;break;//段选
}
}
void SMG(uchar addr,uchar value)
{
P0=0xff;HC573(7);HC573(0); //消隐
P0=0x01<<addr;HC573(6);HC573(0); //位选
P0=~value;HC573(7);HC573(0);//段选
}
void SMG2(uchar z,uchar x,uchar c,uchar v,uchar b,uchar n,uchar m,uchar a)
{
SMG(0,shuzi[z]);Delay(200);
SMG(1,shuzi[x]);Delay(200);
SMG(2,shuzi[c]);Delay(200);
SMG(3,shuzi[v]);Delay(200);
SMG(4,shuzi[b]);Delay(200);
SMG(5,shuzi[n]);Delay(200);
SMG(6,shuzi[m]);Delay(200);
SMG(7,shuzi[a]);Delay(200);
all_SMG();Delay(100);
}
void all_SMG()
{
P0=0xff;HC573(7);HC573(0);
P0=0xff;HC573(6);HC573(0);
P0=0xff;HC573(7);HC573(0);
}
void WS()
{
P0=0xff;HC573(4);HC573(0);
P0=0x00;HC573(5);HC573(0);
P0=0xff;HC573(6);HC573(0);
P0=0xff;HC573(7);HC573(0);
}
void Delay(int t)
{
while(t--);
}
/*************功能的选择选其中的部分************/
/*************温度**************/
void Read_T()//读取
{
unsigned char LSB,MSB;
Init_DS18B20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
Delay(1000);
Init_DS18B20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
LSB=Read_DS18B20();
MSB=Read_DS18B20();
Init_DS18B20();
temp=MSB;
temp=temp<<8;
temp=temp|LSB;
if((temp&0xf800)==0x0000)
{
temp=temp>>4;
}
}
void DS1302_Config()
{
char i;
Write_Ds1302_Byte(0x8e,0x00);
for(i=0;i<7;i++)
{
Write_Ds1302_Byte(Write_DS1302_add[i],Timer[i]);
}
Write_Ds1302_Byte(0x8e,0x80);
}
void Read_DS1302()
{
char i;
for(i=0;i<7;i++)
{
Timer[i]=Read_Ds1302_Byte(Read_DS1302_add[i]);
}
}
思路展示:朋友问的就详细的写了思路:个人写法,可以有错误,仅供参考
第一步:看有几个显示页面(定state的有几个) :
然后发下有一个参数页面(1),一个时钟页面(2),一个温度采集(3)
即state=1;state=2;state=3;
然后输入状态的内容
然后下一步看按键部分:在state=1时候按S4切换时间间隔
然后按下S5时候时间间隔不在变化,而且进入时钟页面(state=2);并开始采集温度
因为温度采集是使用的定时器,即打开定时器;state=2;
然后他要求时钟界面时候提示符闪烁1S因此可以看Timer[0]即秒的时间实现
然后看定时器部分
然后看题;读10个数据之后还需要L1闪烁;而且按下S6后还会熄灭;所以使用了一个flag_led来判断用不用闪烁;flag_led=1时候闪烁0时候不闪烁;所以在进入state=3时候让flag_led=1;(即刚刚上面那个不用看的flag_led=1);然后之后按S6会让显示的数据变化
按键部分:然后显示部分和L1闪烁部分
然后接下继续看题:按S7进入参数页面;即按键设置
U=0;数据初始化