作品功能
1.时钟的时,分,秒的自走
2.闹钟的设定,闹铃时出现流水灯和蜂鸣器滴滴,按S2键停止闹钟,时钟继续工作
3.使用独立按键S2切换时钟和闹钟调节模式,用一杆和两杠区分时钟和闹钟模式
4.使用S3,S4,S5可分别调节闹钟和时钟的时,分,秒位
5.掉电存储当前时间和闹钟设定时间,通电时再读取上一次掉电时的数据
#include<reg52.h>
#include<intrins.h>
#include<stdlib.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit wx = P2^7; //数码管位选
sbit dx = P2^6; //数码管段选
sbit key_s2 = P3^0;//S2按键位定义
uchar code smg[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40,0x41};
uchar second=0,minute=0,hour=0,count=0;
uchar nsecond=10,nminute=0,nhour=0;
uchar o=0;
sbit xiang= P2^3;
sbit Key1 = P3^0; //时钟的停止与开始
sbit Key2 = P3^1; //小时的调节
sbit Key3 = P3^2; //分钟的调节
sbit Key4 = P3^3; //秒数的调节
sbit sda=P2^0; //IO口
sbit scl=P2^1;
int music[40] = {1,2,3,1,1,2,3,1,3,4,5,5,3,4,5,5,5,6,5,4,3,1,5,6,5,4,3,1,1,5,1,1,1,5,1,1,};//想实现两只老虎的闹钟蜂鸣器,中断方式1冲突
unsigned char High,Low;
unsigned char code freq[][2] =
{
0xD8,0xF7,//00440HZ 1
0xBD,0xF8,//00494HZ 2
0x87,0xF9,//00554HZ 3
0xE4,0xF9,//00587HZ 4
0x90,0xFA,//00659HZ 5
0x29,0xFB,//00740HZ 6
0xB1,0xFB,//00831HZ 7
0xEF,0xFB,//00880HZ `1
}; //闹钟的音阶
//延时函数
void delay(uint x)
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<110;j++);
}
//数码管显示数据
void dispw(uchar i,j)
{
dx=0;
wx=1;
P0= _cror_(0x7f,j);
wx=0;
dx=1;
P0=smg[i];
delay(1);
wx=1;
P0=0xff;
wx=0;
}
//定时器初始化
void timeint()
{
TR0 = 1; //启动定时器0
TMOD = 0X01; //定时器工作模式1
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;//时间设置为10ms
ET0 = 1;
EA = 1;
}
//时钟的中断
void time_int(void) interrupt 1
{
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
count++;
if(count==100)//时间度过1s,秒数显示加1
{
count=0;
second++;
if(second==60)
{
second=0;
minute++;
if(minute==60)
{
minute=0;
hour++;
if(hour==24)
{
hour=0;
}
}
}
}
//整点报时
if(second==00&&minute==00)
xiang=0;
else
xiang=1;
//当前时间为闹钟设置时间时,流水灯和蜂鸣器
if(second==nsecond&&minute==nminute&&hour==nhour)
{
uchar a=0;
//按键关闭流水灯和蜂鸣器
while(Key1==1)
{
xiang=~xiang;
P1=_crol_(0xfe,a);
delay(50);
a++;
}
}
//LED灯全部置为熄灭状态
P1=0xff;
}
void nop()
{
_nop_();
_nop_();
}
//24c02初始化
void init()
{
scl=1;
nop();
sda=1;
nop();
}
//启动I2C总线
void start()
{
sda=1;
nop();
scl=1;
nop();
sda=0;
nop();
scl=0;
nop();
}
//停止I2C总线
void stop()
{
sda=0;
nop();
scl=1;
nop();
sda=1;
nop();
}
//写一个字节的数据
void writebyte(unsigned char j)
{
unsigned char i,temp;
temp=j;
for (i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
nop();
sda=CY; //temp左移时,移出的值放入了CY中
nop();
scl=1; //待sda线上的数据稳定后,将scl拉高
nop();
}
scl=0;
nop();
sda=1;
nop();
}
//读一个字节的数据
unsigned char readbyte()
{
unsigned char i,j,k=0;
scl=0; nop(); sda=1;
for (i=0;i<8;i++)
{
nop(); scl=1; nop();
if(sda==1)
j=1;
else
j=0;
k=(k<<1)|j;
scl=0;
}
nop();
return(k);
}
//I2C总线时钟
void clock()
{
unsigned char i=0;
scl=1;
nop();
while((sda==1)&&(i<255))
i++;
scl=0;
nop();
}
//从24c02的地址address中读取一个字节数据
unsigned char read24c02(unsigned char address)
{
unsigned char i;
start();
writebyte(0xa0);
clock();
writebyte(address);
clock();
start();
writebyte(0xa1);
clock();
i=readbyte();
stop();
delay(1);
return(i);
}
//向24c02的address地址中写入一字节数据info
void write24c02(unsigned char address,unsigned char info)
{
EA=0;
start();
writebyte(0xa0);
clock();
writebyte(address);
clock();
writebyte(info);
clock();
stop();
EA=1;
delay(1);
}
//监视按键的读入
void Keyscan()
{ //调节当前时间
if(o%2==0)
{
if(Key4==0)
{
delay(10);
if(Key4==0)
while(!Key4);
second++;
if(second==60)
second=0;
}
if(Key3==0)
{
delay(10);
if(Key3==0)
while(!Key3);
minute++;
if(minute==60)
minute=0;
}
if(Key2==0)
{
delay(10);
if(Key2==0)
while(!Key2);
hour++;
if(hour==24)
hour=0;
}
}
//调节闹钟设定时间
if(o%2==1)
{
if(Key4==0)
{
delay(10);
if(Key4==0)
while(!Key4);
nsecond++;
if(nsecond==60)
nsecond=0;
}
if(Key3==0)
{
delay(10);
if(Key3==0)
while(!Key3);
nminute++;
if(nminute==60)
nminute=0;
}
if(Key2==0)
{
delay(10);
if(Key2==0)
while(!Key2);
nhour++;
if(nhour==24)
nhour=0;
}
}
}
void main()
{ //定时器初始化
timeint();
//读出存入24C02的数据
second=read24c02(1);
minute=read24c02(2);
hour=read24c02(3);
nsecond=read24c02(4);
nminute=read24c02(5);
nhour=read24c02(6);
while(1)
{
//判断按键s2的按压次数
if(Key1==0)
{
delay(10);
if(Key1==0)
while(!Key1);
o++;
}
//按压为偶数次时显示当前时间
if(o%2==0)
{
dispw(second%10,0);
dispw(second/10,1);
dispw(minute%10,3);
dispw(minute/10,4);
dispw(hour%10,6);
dispw(hour/10,7);
dispw(10,2);
dispw(10,5);
}
//按压为奇数次时显示设置的闹钟时间
if(o%2==1)
{
dispw(nsecond%10,0);
dispw(nsecond/10,1);
dispw(nminute%10,3);
dispw(nminute/10,4);
dispw(nhour%10,6);
dispw(nhour/10,7);
dispw(11,2);
dispw(11,5);
}
//监视按键的读入分别调节时间和闹钟
Keyscan();
//断电时存入数据到24CO2中
write24c02(1,second);
write24c02(2,minute);
write24c02(3,hour);
write24c02(4,nsecond);
write24c02(5,nminute);
write24c02(6,nhour);
}
}