说明:进行I2C传输,时候在读和写时1个字节需要start write/read stop
start在保持SCL为高,变化SDA为低
stop相反。
在write时,先置SCL为0,然后变化sda然后置SCL为1,另外一端感知到电压变化即存了1bit,连续传8位。
在read时,先设置为读操作,然后将SCL置为0,读取1个bit,然后将SCL置1,对方发送第2bit,如此连续8位。
- #include <REG52.h>
-
#include <intrins.h>
-
-
#define uchar unsigned char
-
#define uint unsigned int
-
-
sbit scl=P1^5; //24c08 SCL
-
sbit sda=P3^6; //24c08 SDA
-
-
uchar code table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
-
uchar sec; //定义计数值,每过1秒,sec加1
-
uint write; //写标志位
-
void flash(void)
-
{
-
_nop_();
-
_nop_();
-
}//延迟2us
-
-
void x24c02_init(void)
-
{
-
scl = 1;
-
flash();
-
sda = 1;
-
flash();
-
}
-
-
void start(void)
-
{
-
scl = 1;
-
flash();
-
sda = 1;
-
flash();
-
sda = 0;
-
flash();
-
scl = 0;
-
flash();
-
}
-
-
void stop()
-
{
-
scl = 0;
-
flash();
-
sda = 0;
-
flash();
-
scl = 1;
-
flash();
-
sda = 1;
-
flash();
-
}
-
-
void writex(uchar j)
-
{
-
uchar i,temp;
-
temp = j;
-
for(i=0; i<8; i++)
-
{
-
scl = 0;
-
flash();
-
sda = (bit)(temp & 0x80);
-
flash();
-
scl = 1;
-
flash();
-
temp = temp << 1;
-
}
-
scl = 0;
-
flash();
-
}
-
-
uchar readx(void)
-
{
-
uchar i, j, k = 0;
-
for(i=0; i<8; i++)
-
{
-
scl = 0;
-
flash();
-
if(sda == 1)
-
{
-
j = 1;
-
}
-
else j = 0;
-
k = (k << 1) | j;
-
scl = 1;
-
flash();
-
}
-
return(k);
-
}
-
-
void ack(void)
-
{
-
uchar i = 0;
-
scl = 1;
-
flash();
-
while((sda == 1) && (i < 255))//保持scl高电平,等待如果高电平一直等,知道sda低电平或超时
-
{
-
i++;
-
}
-
scl = 0;
-
flash();
-
}
-
-
uchar x24c02_read(uchar address)//先写从设备地址,然后写读写byte地址
-
{
-
uchar i;
-
start();
-
writex(0xa0);
-
ack();
-
writex(address);
-
ack();
-
start();
-
writex(0xa1);
-
ack();
-
i = readx();
-
stop();
-
return(i);
-
}
-
-
void x24c02_write(uchar address, uchar info)
-
{
-
start();
-
writex(0xa0);
-
ack();
-
writex(address);
-
ack();
-
writex(info);
-
ack();
-
stop();
-
}
-
void Delay_1ms(uint i)
-
{
-
uchar x, j;
-
for(j=0; j<i; j++)
-
for(x=0; x<=148; x++)
-
;
-
}
-
-
void LED() //LED显示函数
-
{
-
P2 = 6;
-
P0 = table[sec / 10];
-
Delay_1ms(5);
-
P2 = 7;
-
P0 = table[sec % 10];
-
Delay_1ms(5);
-
}
-
void time0(void) interrupt 1 using 3 //定时中断服务函数
-
{
-
static uchar Count = 0;
-
TH0 = 0x4c; //对TH0 TL0赋值
-
TL0 = 0x00; //重装计数初值
-
Count++;
-
if(Count == 20) //计满20次(1秒)时
-
{
-
Count = 0; //重新再计
-
sec++;
-
write = 1; //1秒写一次24C08
-
if(sec == 100) //定时100秒,在从零开始计时
-
{
-
sec = 0;
-
}
-
}
-
}
-
-
void Time0_Init(void)
-
{
-
TMOD = 0x01; //定时器工作在方式1
-
ET0 = 1;
-
EA = 1;
-
TH0 = 0x4c; //对TH0 TL0赋值
-
TL0 = 0x00; //使定时器0.05秒中断一次
-
TR0 = 1; //开始计时
-
}
-
-
void Main(void)
-
{
-
x24c02_init(); //初始化24C02
-
sec = x24c02_read(2); //读出保存的数据赋于sec
-
Time0_Init();
-
while(1)
-
{
-
LED();
-
if(write == 1) //判断计时器是否计时一秒
-
{
-
write =0; //清零
-
x24c02_write(2,sec); //在24c08的地址2中写入数据sec
-
}
-
}
-
}