c语言AT源码,51单片机读写AT24C02源代码(详细注释)

在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);

}

}

}

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值