资讯详情

C51学习笔记 10.AT24C02

C51 10.AT24C02

前言

AT24C存储介质为02E2PROM,通讯接口为I2C总线的存储器

祝愉快

1.原理图

在这里插入图片描述

A0、A1、A2为I2C地址

SCL、SDA为I2C接口

2.I2C总线结构

两根通信线SCL(Serial Clock)和SDA(Serial Data)。

  • 所有I2C设备的SCL连在一起,SDA连在一起
  • 设备的SCL和SDA均应配置开漏输出模式
  • SCL和SDA每增加一个上拉电阻,电阻值一般为4.7K欧
  • 泄漏输出和上拉电阻的共同作用实现了线与的功能,主要是解决多机通信相互干扰的问题

3.I2C时序结构

4.I2C数据帧

我们将上述时序结构结合起来

发送的第一步是发送发送地址和读写标志字(写)字。

收到响应后,一个BIT接一个BIT发送。

接收的第一步是发送接收地址和读写标志字(读)字

收到响应后,一个BIT接一个BIT接收。

组合上面的数据帧,以完成向谁收指定的数据的任务

以复合格式改写AT24C02数据帧格式

5.C代码

用代码实现I2C数据帧

#include <REGX52.H>  sbit I2C_SCL=P2^1; sbit I2C_SDA=P2^0;  /** * @brief I2C开始 * @param 无 * @retval 无 */ void I2C_Start(void) { 
          I2C_SDA=1;  I2C_SCL=1;  I2C_SDA=0;  I2C_SCL=0; }  /** * @brief I2C停止 * @param 无 * @retval 无 */ void I2C_Stop(void) { 
          I2C_SDA=0;  I2C_SCL=1;  I2C_SDA=1; }  /** * @brief I2C发送字节 * @param Byte 要发送的字节 * @retval 无 */ void I2C_SendByte(unsigned char Byte) { 
          unsigned char i;  for(i=0;i<8;i )  { 
           I2C_SDA=Byte&(0x80>>i);=1;
		I2C_SCL=0;
	}
}

/** * @brief I2C接收一个字节 * @param 无 * @retval 接收到的一个字节数据 */
unsigned char I2C_ReceiveByte(void)
{ 
        
	unsigned char i,Byte=0x00;
	I2C_SDA=1;
	for(i=0;i<8;i++)
	{ 
        
		I2C_SCL=1;
		if(I2C_SDA){ 
        Byte|=(0x80>>i);}
		I2C_SCL=0;
	}
	return Byte;
}

/** * @brief I2C发送应答 * @param AckBit 应答位,0为应答,1为非应答 * @retval 无 */
void I2C_SendAck(unsigned char AckBit)
{ 
        
	I2C_SDA=AckBit;
	I2C_SCL=1;
	I2C_SCL=0;
}

/** * @brief I2C接收应答位 * @param 无 * @retval 接收到的应答位,0为应答,1为非应答 */
unsigned char I2C_ReceiveAck(void)
{ 
        
	unsigned char AckBit;
	I2C_SDA=1;
	I2C_SCL=1;
	AckBit=I2C_SDA;
	I2C_SCL=0;
	return AckBit;
}

AT24C02数据帧

#include <REGX52.H>
#include "I2C.h"

#define AT24C02_ADDRESS 0xA0

/** * @brief AT24C02写入一个字节 * @param WordAddress 要写入字节的地址 * @param Data 要写入的数据 * @retval 无 */
void AT24C02_WriteByte(unsigned char WordAddress,Data)
{ 
        
	I2C_Start();
	I2C_SendByte(AT24C02_ADDRESS);
	I2C_ReceiveAck();
	I2C_SendByte(WordAddress);
	I2C_ReceiveAck();
	I2C_SendByte(Data);
	I2C_ReceiveAck();
	I2C_Stop();
}

/** * @brief AT24C02读取一个字节 * @param WordAddress 要读出字节的地址 * @retval 读出的数据 */
unsigned char AT24C02_ReadByte(unsigned char WordAddress)
{ 
        
	unsigned char Data;
	I2C_Start();
	I2C_SendByte(AT24C02_ADDRESS);
	I2C_ReceiveAck();
	I2C_SendByte(WordAddress);
	I2C_ReceiveAck();
	I2C_Start();
	I2C_SendByte(AT24C02_ADDRESS|0x01);
	I2C_ReceiveAck();
	Data=I2C_ReceiveByte();
	I2C_SendAck(1);
	I2C_Stop();
	return Data;
}

main

#include <REGX52.H>
#include "LCD1602.h"
#include "Key.h"
#include "AT24C02.h"
#include "Delay.h"

unsigned char KeyNum;
unsigned int Num;

void main()
{ 
        
	LCD_Init();
	LCD_ShowNum(1,1,Num,5);
	while(1)
	{ 
        
		KeyNum=Key();
		if(KeyNum==1)	//K1按键,Num自增
		{ 
        
			Num++;
			LCD_ShowNum(1,1,Num,5);
		}
		if(KeyNum==2)	//K2按键,Num自减
		{ 
        
			Num--;
			LCD_ShowNum(1,1,Num,5);
		}
		if(KeyNum==3)	//K3按键,向AT24C02写入数据
		{ 
        
			AT24C02_WriteByte(0,Num%256);
			Delay(5);
			AT24C02_WriteByte(1,Num/256);
			Delay(5);
			LCD_ShowString(2,1,"Write OK");
			Delay(1000);
			LCD_ShowString(2,1," ");
		}
		if(KeyNum==4)	//K4按键,从AT24C02读取数据
		{ 
        
			Num=AT24C02_ReadByte(0);
			Num|=AT24C02_ReadByte(1)<<8;
			LCD_ShowNum(1,1,Num,5);
			LCD_ShowString(2,1,"Read OK ");
			Delay(1000);
			LCD_ShowString(2,1," ");
		}
	}
}

总结

  • 表示出I2C的每一种数据帧。
  • 用I2C数据帧拼凑出AT24C02的数据帧

标签: 26k1电阻电阻9k1

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台