在P1口上接八个led灯,成果就显现在这八个灯上面。AT24C02的接线方法见程序的顶部的界说。以下是源代码:
#include
typedef unsigned char uchar;
typedef unsigned int uint;
#define write_c02 0xa0
#define read_c02 0xa1
sbit sda = P2^0;
sbit scl = P2^1;
void delay()
{ //delay:5us
;;
}
//i2c:init
void i2c_init()
{
sda = 1;
delay();
scl = 1;
delay();
}
//delayms:
void delayms(uint xms)
{
uchar x, y;
for(x = xms; x > 0; x–)
for(y = 110; y > 0; y–);
}
//start:
void start() //发动i2c
{
sda = 1;
scl = 1;
delay();//延时有必要大于4.7us,此约为五微秒
sda = 0; //在scl为高电平时,sda一个下降沿为发动信号
delay();
}
//stop:
void stop() //中止i2c
{
sda = 0;
scl = 1;
delay();
sda = 1; //在scl为高电平时,sdasda一个上升沿为中止信号
delay();
}
//ack:
void ack() //应对信号0
{
uchar i = 0; //等候变量
scl = 1;//在scl为高电平期间等候应对
delay();
while((sda == 1) && i < 250)//若为应对0即退出,从机向主机发送应对信号
i++;//等候一段时间
scl = 0; //应对之后将scl拉低
delay();
}
//nack:
void nack() //非应对
{
scl = 1;//在scl为高电平期间,由主机向从机发送一个1,非应对信号
delay();
sda = 1;
scl = 0; //应对之后将scl拉低
delay();
}
//send byte:
void send_byte(uchar date)//写一个字节
{
uchar i, temp;
temp = date; //存入要写入的数据,即要发送到sda上的数据
for(i = 0; i < 8; i++)
{ //发送8位
temp <<= 1; //to CY 将数据的最高位移入到PSW中的CY位中
scl = 0;//只要在scl为低电平时,才答应sda上的数据改变
delay();
sda = CY; //将CY里的数据发送到sda数据线上
delay(); //能够延时
scl = 1; //在scl为高电平时,不答应sda上的数据改变,使数据安稳
delay();
scl = 0;//答应sda数据线的数据改变,等候下一个数据的传输
delay();
}
//wait ack:发送完一个字节数据后要主机要等候从机的应对,第九位
scl = 0;//答应sda改变
delay();
sda = 1;//wait:ack,sda拉高等候应对,当sda=0时,表明从机的应对
delay();
}
//read: byte
uchar read_byte() //读一个字节数据
{
uchar i, j, k;
scl = 0; //读之前先答应sda改变
delay(); //等候数据
for(i = 0; i < 8; i++)
{
scl = 1; //不答应sda改变
delay(); //使sda数据安稳后开端读数据
j = sda; //读出sda上的数据
k = (k << 1)| j; //将数据经过|运算存入k中
scl = 0;//答应sda改变等候下一位数据的到来
delay();
}
//delay();//可不必延时
return k;//回来读出的数据
}
//write:at24c02 在at24c02中的指定地址写入数据
void write_at24c02(uchar address, uchar date)
{
start(); //发动i2c
send_byte(write_c02);//写入期间地址和写操作
ack(); //从机应对0
send_byte(address); //写入写数据的单元地址
ack(); //ack0
send_byte(date); //在指定地址中写入数据
ack(); //从机应对0
stop(); //中止i2c
}
//read: at24c02 在at24c02的指定地址中读出写入的数据
uchar read_at24c02(address)
{
uchar dat;//用来存储读出的数据
start(); //发动i2c
send_byte(write_c02); //写入at24c02器材地址和写操作
ack(); //从机应对0
send_byte(address); //写入要读取AT24C02的数据的单元地址
ack(); //从机应对0
start(); //再次发动i2c
send_byte(read_c02); //写入AT24C02器材地址和读操作
ack();//从机应对‘0’
dat = read_byte();//读出指定地址中的数据
nack(); //主机宣布非应对‘1’
stop(); //中止i2c
return dat; //回来读出的数据
}
//main:
void main()
{
uchar i;
i2c_init();
start();
while(1)
{
for(i = 0x00; i < 0xff; i++)
{
write_at24c02(10, i);
delayms(10);//需等候十毫秒
P1 = read_at24c02(10);//1010 1010
delayms(2000);
}
}
}