24C08(存储芯片)

工具

1.Proteus 8 仿真器

2.keil 5 编辑器

原理图

讲解

特点:

  1. 宽范围的工作电压,1.8V~5.5V;
  2. 低电压技术,1mA典型工作电流,1μA典型待机电流;
  3. 存储器组织结构为1024 X 8(8K bits);
  4. 2线串行接口,完全兼容I2C总线,I2C时钟频率为1MHz(5V),400kHz(1.8V、2.5V、2.7V);
  5. 施密特触发输入噪声抑制;
  6. 硬件数据写保护;
  7. 内部写周期(最大5ms);
  8. 可按字节写,页写:16字节页;
  9. 可按字节、随机和序列读;
  10. 自动递增地址;
  11. ESD保护大于2.5kV;
  12. 高可靠性;
  13. 擦写寿命:100万次;
  14. 数据保持时间:100年。

引脚:

注意:此图与仿真器中有所差异但原理一致 仿真器中1,2,3,4接地,8接电源,7为写保护(高电平时禁止写入,低电平可以写入)接地,5数据,6时钟。

时序

开始:SDA与SCL高电平--(>4μs)--SDA拉为低电平--(>4μs)--SCL拉为低电平

    // 开始  SCL高电平状态下 SDA 由高电平变低电平
    void start()
    {
    	SDA=1;
	    SCL=1;
	    delay();    //5us
	    SDA=0;
	    delay();    //5us
	    SCL=0;
    }

结束:SDA低电平,SCL高电平--(>4μs)--SDA拉为高电平--(>4μs)--SDA,SCL拉为低电平

    // 结束  SCL高电平状态下 SDA 由低电平变高电平
    void end()
    {
	    SDA=0;
	    SCL=1;
	    delay();    //5us
	    SDA=1;
	    delay();    //5us
	    SCL=0;
	    SDA=0;
    }

写入:SDA(电平由单字节的每一位决定)--(>4μs)--SCL拉为高电平--(>4μs)--SCL拉为低电平

    // 发送
    void send(unsigned char byte)
    {
	    unsigned char i;
	    for(i=0;i<8;i++)               //字节拆分按位传递
	    {	                           //SCL为高电平 读取SDA稳定数据 所以SDA变化在前
	    	SDA=byte&(0x80>>i);        //从最高位依次传递给SDA 
	    	delay();    //5us
		    SCL=1;
		    delay();    //5us
		    SCL=0;
	    }
    }

读取:SDA高电平(开始接收前),SCL高电平--(>4μs)--SDA(电平由单字节的每一位决定)--(>4μs)--SCL拉为低电平

    // 接收
    unsigned char read()
    {
	    unsigned char i,byte=0x00;      //byte需要初始化0x00
	    SDA=1; 
	    for(i=0;i<8;i++)                 //字节拆分按位接收
	    {	
	    	SCL=1;
		    delay();    //5us
	    	if(SDA){byte|=(0x80>>i);}
		    delay();    //5us
		    SCL=0;
	    }
        return byte;
    }

接收应答:SDA高电平--(>4μs)--SCL拉为高电平--(>4μs)--SCL拉为低电平

    //接收应答
    bit read_sck()
    {
    	bit ACK;
    	SDA=1;
	    delay();    //5us
	    SCL=1;
	    delay();    //5us
	    ACK=SDA;
	    SCL=0;
	    return ACK;
    }

发送应答:SDA( 0 应答,1 非应答 )--(>4μs)--SCL拉为高电平--(>4μs)--SCL拉为低电平

    //发送应答
    void send_sck(bit ACK )
    {
    	SDA=ACK;
    	delay();    //5us
    	SCL=1;
    	delay();    //5us
    	SCL=0;
    }

代码

main.c 

#include <reg52.h>
#include <I2C.h>

unsigned char arr[]={0xa0,0xff,0xaa,0x90};
main(void) 
{ 
	
	unsigned char i;
	for(i=0;i<4;i++)
	{
		I2C_send(i,arr[i]);
	}
	
	//随机读 指定地址读取数据
	P1=	I2C_read(2);
	
  
} 
 
 
 

I2C.c

#include <REGX51.H>
#include <intrins.H>
#define delay();{_nop_();_nop_();_nop_();_nop_();_nop_();} //五个机器周期 5微妙 一周期多长时间与晶振有关

sbit SDA = P3^7;    //数据
sbit SCL = P3^6;	//时钟

void delay_ms(unsigned int ms) {  
    unsigned int i, j;  
    for (i = 0; i < ms; i++) {  
        for (j = 0; j < 1275; j++) { // 这里使用了大约1275个空循环,可以根据你的晶振频率进行调整  
            // 这里什么也不做,只是为了消耗一些时间  
        }  
    }  
}

// 开始  SCL高电平状态下 SDA 由高电平变低电平
void start()
{
	SDA=1;
	SCL=1;
	delay();
	SDA=0;
	delay();
	SCL=0;
}

// 结束  SCL高电平状态下 SDA 由低电平变高电平
void end()
{
	SDA=0;	
	SCL=1;
	delay();
	SDA=1;
	delay_ms(10);
}

// 发送
void send(unsigned char byte)
{
	unsigned char i;
	for(i=0;i<8;i++) //字节拆分按位传递
	{	//SCL为高电平 读取SDA稳定数据 所以SDA变化在前
		SDA=byte&(0x80>>i); //从最高位依次传递给SDA 
		delay();
		SCL=1;
		delay();
		SCL=0;
	}
}

// 接收
unsigned char read()
{
	unsigned char i,byte=0x00;
	SDA=1; 
	for(i=0;i<8;i++) //字节拆分按位接收
	{	
		SCL=1;
		delay();
		if(SDA){byte|=(0x80>>i);}
		delay();
		SCL=0;
	}
	return byte;
}

void send_sck(bit ACK) { 
    // 根据ACK的值设置数据线SDA  
    SDA = ACK; // 注意:通常ACK是低电平,NACK是高电平
    delay();   // 保持SDA状态,等待从机读取 
    SCL = 1;   // 将时钟线SCL拉高 
    delay();   // 等待时钟线稳定 
    SCL = 0;   // 将时钟线SCL拉低,结束应答  
    delay();   // 等待时钟线稳定  
	  SDA = 1;   //释放数据线 线权交给从机
}
//接收应答
bit read_sck()
{
	bit ACK;
	SDA=1;
	delay();    //5us
	SCL=1;
	delay();    //5us
	ACK=SDA;
	delay();    //5us
	SCL=0;
	return ACK;
}

void I2C_send(unsigned char address,unsigned char byte)
{
	start();
	send(0xa0);
	read_sck();
	send(address);
	read_sck();
	send(byte);
	read_sck();
	end();
	delay_ms(5);
}
unsigned char I2C_read(unsigned char address)
{
	unsigned char read_data;
	start();
	send(0xa0);
	read_sck();
	send(address);
	read_sck();
	start();
	send(0xa1);
	read_sck();
	read_data=read();
	send_sck(1);
	end();
	return read_data;
}

实现

  • 18
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

欧的曼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值