📄 clk.c
字号:
#include<reg51.h>
#define IIC_WRITE 0xa0 //24C04 EEPROM 写命令和读命令
#define IIC_READ 0xa1
sbit P10=P1^0;
sbit P11=P1^1;
sbit P12=P1^2;
sbit P13=P1^3;
sbit P14=P1^4;
sbit P15=P1^5;
sbit SCL=P1^6;
sbit SDA=P1^7;
sbit key0=P0^0;
sbit key1=P0^1;
sbit key2=P0^2;
sbit key3=P0^3;
sbit key4=P0^4;
unsigned char led_mask=0xff,mask_temp,led_num=0;
//led_mask 用低六位作led标志位//led_num 闪烁间隔的中断次数
unsigned char key0_mark=0,key1_mark=0,key2_mark=0,key3_mark=0; //每个按键的标识
unsigned int key0_count=0,key1_count=0,key2_count=0,key3_count=0; //每键按下 间隔的中断数
unsigned int temp_count0=0,music_count=0;
bit ph=1,flash=0,clk_begin=0,clk_off=0,agenda_begin=0;
bit wr_mark=0,clk_save=0;
unsigned char error=0;
unsigned int n=0;
unsigned char sec=0,min=0,h=0,year=06,mon=05,day=24;
unsigned char idata led=0,led_buf[6],buf[6];
unsigned char idata clk1_h=12,clk1_m=00,clk1_num=1,clk1_music=1, //闹钟和议程
clk2_h=24,clk2_m=30,clk2_num=2,clk2_music=2,
agenda_year=06,agenda_mon=01,agenda_day=0,agenda_h=8,agenda_num=3;
unsigned char music=0;
code unsigned char led_map[]={0x3F,0x06,0x5B,0x4F,0x66,
0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x76,0x73 };
code unsigned char mon_day[13]={0,31,28,31,30,31,30,31,31,30,31,30,31}; //闰年与非闰年
code unsigned char mon_day1[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};
//延时,主要用于IIC程序
void delay(unsigned int n)
{
unsigned int i;
for (i=n;i>0;i--) {}
}
time0() interrupt 1 using 0
{ //T0计时器中断程序 //对时分秒针计数
n++;
if(n>=5002) //5000次为1秒,5002为矫误差
{
sec++;
n=0;
}
if(sec>=60)
{
min++;
sec=0;
clk_begin=0; //闹铃最长1 分钟
clk_off=0;
wr_mark=1;
}
if(min>=60)
{
h++;
min=0;
agenda_begin=0; //隔一小时查agenda;
}
if(h>=24)
{
h=0;
day++;
if(year%4==0)
{
if(day>mon_day1[mon])
{
day=1;
mon++;
if(mon>12)
{
mon=1;
year++;
}
}
}
else if (day>mon_day[mon])
{
day=1;
mon++;
if(mon>12)
{
mon=1;
year++;
}
}
}
}
t1display() interrupt 3 using 1 //显示数码管
{
TH1=0xf0; // 1/24显示 4ms中断
TL1=0X5f;
if((key3==0)&&(key0_mark!=0)&&(key0_mark!=1))
{
P2=led_buf[led]|0x80;
}
else P2=led_buf[led];
led_num++;
switch (led)
{
case 0:
P15=0;
P10=1;
break;
case 1:
P10=0;
P11=1;
break;
case 2:
P11=0;
P12=1;
break;
case 3:
P12=0;
P13=1;
break;
case 4:
P13=0;
P14=1;
break;
case 5:
P14=0;
P15=1;
break;
default:
break;
}
if(led_num<=125&&flash) //闪烁once each 1s
P1=P1&led_mask;
if(led_num>125)
{
led_num=0;
flash=~flash;
}
//-----------------------------------查询闹钟
if(clk1_h==h&&clk1_m==min&&clk_off==0)
clk_begin=1;
if(clk2_h==h&&clk2_m==min&&clk_off==0)
clk_begin=1;
if(agenda_year==year&&agenda_mon==mon&&agenda_day==day&&agenda_h==h&&agenda_begin==0&&clk_off==0) //隔一个小时再查
{
agenda_begin=1;
clk_begin=1;
}
if(clk_begin&&clk_off==0)
{
music_count++;
if(clk1_h==h&&clk1_m==min) music=clk1_music;
else if(clk2_h==h&&clk2_m==min) music=clk2_music;
else music=3;
switch (music)
{
case 1:
if(music_count%5==0)
{
ph=~ph;
music_count=0;
}
break;
case 2:
if(music_count%50==0)
{
ph=~ph;
music_count=0;
}
break;
case 3:
ph=~ph;
break;
default:
ph=1;
break;
}
}
key4=ph; //clock
//------------------------------------------------------
led++; //led 片选清零
if(led>=6) led=0;
if(key0==1) key0_count=0; //对延时计数清零
if(key1==1) key1_count=0;
if(key2==1) key2_count=0;
if(key3==1) key3_count=0;
if(key3==0)
{
key3_count++;
if(key3_count==20)
{
if(clk_off==0) clk_off=1;
if((key0_mark!=0)&&(key0_mark!=1)) clk_save=1;
}
}
if(key0==0)
{
key0_count++;
if(key0_count==20) key0_mark+=1;
if(key0_mark==6) key0_mark=0;
}
if(key1==0)
{
key1_count++; //agenda 只闪烁 1,2;
if(key1_count==20) key1_mark+=1; //clk 只闪烁1,2,4
if ((key0_mark==4||key0_mark==5)&&key1_mark==3) key1_mark=0;
if ((key0_mark==2||key0_mark==3)&&key1_mark==3) key1_mark=4;
if ((key0_mark==0||key0_mark==1||key0_mark==4||key0_mark==5)&&key1_mark==4) key1_mark=0;
if(key1_mark==5) key1_mark=0;
}
if ((key0_mark==4||key0_mark==5)&&key1_mark==4) key1_mark=0; //除bug agenda 闪4
//调整加一或连加
if(key2==0)
{
key2_count++;
if(((key2_count==20)||((key2_count>=450)&&(key2_count%150==0)))&&(key0_mark==0))
{
switch (key1_mark)
{
case 1:
sec=0;
break;
case 2:
{min++;
if(min>=60) min=0; }
break;
case 3:
{h++;
if(h>=24) h=0; }
break;
default:
break;
}
}
if(((key2_count==20)||((key2_count>=450)&&(key2_count%150==0)))&&(key0_mark==1))
{
switch (key1_mark)
{
case 1:
day++;
if(year%4==0)
{
if(day>mon_day1[mon]) day=1;
}
else if (day>mon_day[mon]) day=1;
break;
case 2:
mon++;
if(mon>12) mon=1;
break;
case 3:
year++;
break;
default:
break;
}
if(key2_count>=450) year=06;
}
if(((key2_count==20)||((key2_count>=450)&&(key2_count%150==0)))&&(key0_mark==2))
{
switch (key1_mark)
{
case 1:
clk1_m++;
if(clk1_m>=60) clk1_m=0;
break;
case 2:
clk1_h++;
if(clk1_h>=24) clk1_h=0;
break;
case 4:
clk1_music++;
if(clk1_music>=3) clk1_music=0;
break;
default:
break;
}
}
if(((key2_count==20)||((key2_count>=450)&&(key2_count%150==0)))&&(key0_mark==3))
{
switch (key1_mark)
{
case 1:
clk2_m++;
if(clk2_m>=60) clk2_m=0;
break;
case 2:
clk2_h++;
if(clk2_h>=24) clk2_h=0;
break;
case 4:
clk2_music++;
if(clk2_music>=3) clk2_music=0;
break;
default:
break;
}
}
if(((key2_count==20)||((key2_count>=500)&&(key2_count%125==0)))&&(key0_mark==4))
{
//agenda 不调整music
switch (key1_mark)
{
case 1:
agenda_mon++;
if(agenda_mon>12) agenda_mon=1;
break;
case 2:
agenda_year++;
if((key2_count>=450)&&(key2_count%150==0)) agenda_year=06;
break;
default:
break;
}
}
if(((key2_count==20)||((key2_count>=500)&&(key2_count%125==0)))&&(key0_mark==5))
{
//agenda 不调整music
switch (key1_mark)
{
case 1:
agenda_h++;
if(agenda_h>=24) agenda_h=0;
break;
case 2:
agenda_day++;
if(agenda_year%4==0)
{
if(agenda_day>mon_day1[agenda_mon]) agenda_day=1;
}
else if (agenda_day>mon_day[agenda_mon]) agenda_day=1;
break;
default:
break;
}
}
}
if(((key0==0)||(key1==0)||(key2==0)||(key3==0))==1) temp_count0=0; //只要有键按下,则不启动回复
if(((key0==1)&&(key1==1)&&(key2==1)&&(key3==1))==1) temp_count0++; //没有键按下,则启动回复
if(temp_count0>=2500)
{ //10s 以后回到显示时间
temp_count0=0;
key0_mark=0;
key1_mark=0;
key2_mark=0;
key3_mark=0;
}
}
//------------------------------------------------------------------------------
void start()
{
SDA=1;
SCL=1;
delay(2);
SDA=0;
delay(2);
SCL=0;
}
void stop()
{
SDA=0;
SCL=1;
delay(1);
SDA=1;
delay(2);
SDA=0;
}
unsigned char outbyte(unsigned char value) //MCU 输出一个字节到2404
{
unsigned char i;
unsigned char ack=0;
for(i=0x80;i>0;i>>=1)
{
if(i&value)
{
SDA=1;
SCL=1;
delay(2);
SCL=0;
//SDA=0;
} //********
else
{
SDA=0;
SCL=1;
delay(2);
SCL=0;
}
}
SDA=1;
SCL=1;
delay(2);
ack=SDA;
SCL=0;
delay(1);
return ack;
}
unsigned char inbyte(unsigned char ack) //2404输入一个字节到MCU
{
unsigned char i,val=0;
SDA=1;
for (i=0x80;i>0;i>>=1)
{
SCL=1;
if(SDA==1) val=val|i;
delay(1);
SCL=0;
}
if(!ack) //mack();
{
SCL=0;
SDA=0; //MCU 把SDA拉低
SCL=1;
delay(2);
SCL=0;
}
else //muack();
{
SCL=0;
SDA=1;
SCL=1;
delay(2);
SCL=0;
}
return val;
}
//连写函数
//add为读起始地址,ptr数据保存指针,writelen为写入数据长度
unsigned char writebyteseq(unsigned int add,unsigned char *ptr,unsigned int writelen)
{
unsigned char ack=0;
unsigned char templ;
unsigned int i;
templ=(unsigned char)(add%256);
start();
ack+=outbyte(IIC_WRITE);
ack+=outbyte(templ);
for(i=0;i<writelen;i++)
{
ack+=outbyte(*(ptr+i));
delay(10);
}
error=ack;
stop();
return ack;
}
void readbyteseq(unsigned int add,unsigned char *ptr,unsigned int readlen )
{
unsigned char ack=0;
unsigned char temph,templ;
unsigned int i;
temph=(unsigned char)(add/256);
templ=(unsigned char)(add%256);
for (i=0;i<readlen;i++)
{
start();
ack+=outbyte(IIC_WRITE);
ack+=outbyte(templ+i);
start();
ack+=outbyte(IIC_READ);
*(ptr+i)=inbyte(1);
stop();
}
}
//------------------------------------------------------------------------------
main()
{
unsigned char idata time_date[5],time_temp[5],clk_data[10],clk_temp[10];
unsigned char ack=0;
TMOD=0x12;
TH0=0x38;
TL0=0x38;
TH1=0xf0;
TL1=0X5f;
// IE=0X8A;
IP=0x02;
EA=1;
ET0=1;
ET1=1;
TR0=1;
TR1=1;
readbyteseq(0x10,time_temp,5); //从EEPBROM读出已存的时间日期
delay(40);
min=time_temp[0];
h=time_temp[1];
day=time_temp[2];
mon=time_temp[3];
year=time_temp[4];
readbyteseq(0x40,clk_data,10); //从EEPBROM读出已存的闹钟设置
delay(40);
clk1_music=clk_data[0];
clk1_m=clk_data[1];
clk1_h=clk_data[2];
clk2_music=clk_data[3];
clk2_m=clk_data[4];
clk2_h=clk_data[5];
agenda_year=clk_data[6];
agenda_mon=clk_data[7];
agenda_day=clk_data[8];
agenda_h=clk_data[9];
while(1)
{
if((min+1)%5==0&&wr_mark==1) //每隔一段时间就存时间
{
time_date[0]=min;
time_date[1]=h;
time_date[2]=day;
time_date[3]=mon;
time_date[4]=year;
ack=writebyteseq(0x10,time_date,5);
delay(40);
wr_mark=0;
}
if(clk_save==1) //按key3之后若无闹铃响则存闹铃设置
{
clk_temp[0]=clk1_music;
clk_temp[1]=clk1_m;
clk_temp[2]=clk1_h;
clk_temp[3]=clk2_music;
clk_temp[4]=clk2_m;
clk_temp[5]=clk2_h;
clk_temp[6]=agenda_year;
clk_temp[7]=agenda_mon;
clk_temp[8]=agenda_day;
clk_temp[9]=agenda_h;
ack=writebyteseq(0x40,clk_temp,10);
delay(40);
clk_save=0;
}
//---------------------------------------------------------------------
if(key0_mark==0)
{ //将时间值赋给数码管
buf[0]=h/10;
buf[1]=h%10;
buf[2]=min/10;
buf[3]=min%10;
buf[4]=sec/10;
buf[5]=sec%10;
}
if(key0_mark==1) //将日期值赋给数码管
{
buf[0]=year/10;
buf[1]=year%10;
buf[2]=mon/10;
buf[3]=mon%10;
buf[4]=day/10;
buf[5]=day%10;
}
if(key0_mark==2) //将第一组闹钟值赋给数码管
{
buf[0]=clk1_num;
buf[1]=clk1_music;
buf[2]=clk1_h/10;
buf[3]=clk1_h%10;
buf[4]=clk1_m/10;
buf[5]=clk1_m%10;
}
if(key0_mark==3) //将第二组闹钟值赋给数码管
{
buf[0]=clk2_num;
buf[1]=clk2_music;
buf[2]=clk2_h/10;
buf[3]=clk2_h%10;
buf[4]=clk2_m/10;
buf[5]=clk2_m%10;
}
if(key0_mark==4)
{
buf[0]=agenda_num;
buf[1]=3;
buf[2]=agenda_year/10;
buf[3]=agenda_year%10;
buf[4]=agenda_mon/10;
buf[5]=agenda_mon%10;
}
if(key0_mark==5)
{
buf[0]=agenda_num+1;
buf[1]=3;
buf[2]=agenda_day/10;
buf[3]=agenda_day%10;
buf[4]=agenda_h/10;
buf[5]=agenda_h%10;
}
//------------------------------------------------------------------
if(key1_mark==1) led_mask=0xcf; //选择闪烁数码管
if(key1_mark==2) led_mask=0xf3;
if(key1_mark==3) led_mask=0xfc;
if(key1_mark==4) led_mask=0xfd;
if(key1_mark==0) led_mask=0xff;
//-----------------------------------------调整在中断子程序,判断在主函数
if(key0_mark==1)
{
if(year%4==0) ///4月31日!!
{
if(day>mon_day1[mon]) day=mon_day1[mon];
}
else if (day>mon_day[mon]) day=mon_day[mon];
}
if((key0_mark==4)||(key0_mark==5))
{
if(agenda_year%4==0) ///4月31日!!
{
if(agenda_day>mon_day1[agenda_mon]) agenda_day=mon_day1[agenda_mon];
}
else if (agenda_day>mon_day[agenda_mon]) agenda_day=mon_day[agenda_mon];
}
//------------------------------------------------------------------
led_buf[0]=led_map[buf[0]]; //将显示值赋给数码管
led_buf[1]=led_map[buf[1]];
led_buf[2]=led_map[buf[2]];
led_buf[3]=led_map[buf[3]];
led_buf[4]=led_map[buf[4]];
led_buf[5]=led_map[buf[5]];
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -