#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
uint tent,sec;
bit write=0;
sbit sda=P1^2;
sbit scl=P1^7;
sbit dula=P2^6;
sbit wela=P2^7;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delay()
{;;}
void delay1ms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=0;y<110;y++);
}
void start()
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
}
void stop()
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
void response()
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<250))i++;//当从机出现问题,无法产生应答信号(sda=0)时,满足该循环条件进行循环等待从机应答信号,计数满后跳出循环进行下面程序,不会被卡死
scl=0;
delay();
}
void init()//I2C总线初始化释放总线,均为高电平即总有检测到总线空闲才开始发送启动信号
{
sda=1;
delay();
scl=1;
delay();
}
void write_byte(uchar date)//写一个字节函数,这里由于data为关键词会产生错误故换成date
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
delay();
sda=CY;
delay();
scl=1;//拉高SCL,此时SDA上的数据稳定
dealy();
}
scl=0;//只有当时钟信号为低电平时,数据线上的数据才允许变化,该段程序为使总线进入准备状态
delay();
sda=1;//释放数据线,接下来有从机控制该总线
delay();
}
uchar read_byte()//读一个字节函数
{
uchar i,k;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda;
scl=0;
delay();
}
return k;
}
void write_add(uchar address,uchar date)//向24c02任意地址写入数据
{
start();
write_byte(0xa0);/*发送从机(EEROM AT24C02)地址,写操作,
其地址控制格式为1010A2A1A0R/W,其中A2 A1 A0为可编程地址选择位与1010构成7位编码,RW位为1时读操作,0时写操作*/
response();//等待从设备的响应
write_byte(address);//发送芯片内地址
response();
write_byte(date);//发送数据
response();
stop();
}
uchar read_add(uchar address)//指定位置读取一个字节
{
uchar date;
start();
write_byte(0xa0);//发送从机地址
response();
write_byte(address);
response();
start();
write_byte(0xa1);//读操作
response();
date=read_byte();//把读取的数据给date
stop();
return date;
}
void display(uchar bai,uchar shi)//显示程序
{
dula=0;
P0=table[bai];//显示第1位
dula=1;
dula=0;
wela=0;
P0=0X7e;
wela=1;
wela=0;
delay1ms(5);
dula=0;
P0=table[shi];//显示第2位
dula=1;
dula=0;
wela=0;
P0=0x7d;
wela=1;
wela=0;
delay1ms(5);
}
void main()
{
init();
sec=read_add(2);//读出保存的数据给sec
if(sec>100)//防止首次读取错误数据,由于之前EERPM储存的数据未知,此次实验要求从0计数到99一旦超出100就出现错误
sec=0;
TMOD=0x01;
ET0=1;
EA=1;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
TR0=1;
while(1)
{
display(sec/10,sec%10);
if(write==1)
{
write=0;
write_add(2,sec);
}
}
}
void qwe()interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
tent++;
if(tent==20)
{
tent=0;
sec++;
write=1;
if(sec==100)
sec=0;
}
}
#define uint unsigned int
#define uchar unsigned char
uint tent,sec;
bit write=0;
sbit sda=P1^2;
sbit scl=P1^7;
sbit dula=P2^6;
sbit wela=P2^7;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
void delay()
{;;}
void delay1ms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=0;y<110;y++);
}
void start()
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
}
void stop()
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
void response()
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<250))i++;//当从机出现问题,无法产生应答信号(sda=0)时,满足该循环条件进行循环等待从机应答信号,计数满后跳出循环进行下面程序,不会被卡死
scl=0;
delay();
}
void init()//I2C总线初始化释放总线,均为高电平即总有检测到总线空闲才开始发送启动信号
{
sda=1;
delay();
scl=1;
delay();
}
void write_byte(uchar date)//写一个字节函数,这里由于data为关键词会产生错误故换成date
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
delay();
sda=CY;
delay();
scl=1;//拉高SCL,此时SDA上的数据稳定
dealy();
}
scl=0;//只有当时钟信号为低电平时,数据线上的数据才允许变化,该段程序为使总线进入准备状态
delay();
sda=1;//释放数据线,接下来有从机控制该总线
delay();
}
uchar read_byte()//读一个字节函数
{
uchar i,k;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda;
scl=0;
delay();
}
return k;
}
void write_add(uchar address,uchar date)//向24c02任意地址写入数据
{
start();
write_byte(0xa0);/*发送从机(EEROM AT24C02)地址,写操作,
其地址控制格式为1010A2A1A0R/W,其中A2 A1 A0为可编程地址选择位与1010构成7位编码,RW位为1时读操作,0时写操作*/
response();//等待从设备的响应
write_byte(address);//发送芯片内地址
response();
write_byte(date);//发送数据
response();
stop();
}
uchar read_add(uchar address)//指定位置读取一个字节
{
uchar date;
start();
write_byte(0xa0);//发送从机地址
response();
write_byte(address);
response();
start();
write_byte(0xa1);//读操作
response();
date=read_byte();//把读取的数据给date
stop();
return date;
}
void display(uchar bai,uchar shi)//显示程序
{
dula=0;
P0=table[bai];//显示第1位
dula=1;
dula=0;
wela=0;
P0=0X7e;
wela=1;
wela=0;
delay1ms(5);
dula=0;
P0=table[shi];//显示第2位
dula=1;
dula=0;
wela=0;
P0=0x7d;
wela=1;
wela=0;
delay1ms(5);
}
void main()
{
init();
sec=read_add(2);//读出保存的数据给sec
if(sec>100)//防止首次读取错误数据,由于之前EERPM储存的数据未知,此次实验要求从0计数到99一旦超出100就出现错误
sec=0;
TMOD=0x01;
ET0=1;
EA=1;
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
TR0=1;
while(1)
{
display(sec/10,sec%10);
if(write==1)
{
write=0;
write_add(2,sec);
}
}
}
void qwe()interrupt 1
{
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
tent++;
if(tent==20)
{
tent=0;
sec++;
write=1;
if(sec==100)
sec=0;
}
}