IIC实现E2PROM的数据写入与擦除

main函数

#include "reg52.h"
#include "intrins.h"
#include "smg_ca.h"
#include "initial.h"
#include "absacc.h"

#define AT24C02_ADDR 0XA0
#define AT24C02_ADDR_Read 1
#define AT24C02_ADDR_Write 0

sbit SCL = P2^0;
sbit SDA = P2^1;

bit ACK_Flag;

void delay(int t)
{
	while(t--);
	while(t--);
	while(t--);
	while(t--);
}
//延时5us
void Delay_I2c_5us()    //debug 后发现延时5.43us。
{
	_nop_();
}
//
//
//起始信号
void I2cStart()
{
	SCL = 1;
	SDA = 1;
	Delay_I2c_5us();			//保持总线高电平多于4.7us
	SDA = 0;								
	Delay_I2c_5us();				//保持SCL为高,SDA为低多于4.7us
}
//停止信号
void I2cStop()
{
	SCL = 0;
	SDA = 0;
	SCL = 1;
	Delay_I2c_5us();
	SDA = 1;
	Delay_I2c_5us();
}

//
//
//主机读从机的应答,即向从机发送数据
bit ReadACK()
{
	SCL = 0;
	//读取SCL为高时,从机的SDA应答状况,根据收到的SDA信号来确定从机是否应答//
	if(SDA) // NO
	{
		SCL = 1;
		Delay_I2c_5us();
		return(1);
	}
	else   // YES
	{
		SCL = 1;
		Delay_I2c_5us();
		return(0);
	}
}
//主机发送应答信号,接受从及数据
void SendACK(bit i)
{
	SCL = 0;
	if(i)
		SDA = 1;
	else
		SDA = 0;
	SCL = 1;
	Delay_I2c_5us();
	SCL = 0;

	SDA = 1;			//释放SDA,为主机软件应答后,从机发送数据做准备,若不拉高,则从机无法发送数据,因为从既不具备
	              //操控SDA线的能力
	
}
//
//******************************发送数据************************************//
//
//主机发送一字节的 地址/数据 ,取决于给 I2c_dat 赋的值
void I2cSend_Byte(unsigned char I2c_dat)
{
	unsigned char i ;
	for(i=0;i<8;i++)
	{
		SCL = 0;
	if(I2c_dat & 0x80)//选择最高位,最高位为1,则给SDA赋值1
		SDA = 1;
	else 							//否则,给SDA赋值0
		SDA = 0;
	SCL = 1;
	Delay_I2c_5us();
	I2c_dat = I2c_dat << 1; // 把低1位的值转移到最高位上,对最高位进行传输
	}
	SCL = 0;
	SDA = 1;
}
//主机向E2PROM写数据全过程:
//start-addr-ack-write-ack-stop
void AT24C02_Write(unsigned char addr_e2prom,unsigned char e2prom_dat)
{
	I2cStart();
	
	I2cSend_Byte(AT24C02_ADDR + AT24C02_ADDR_Write);//地址 1010 xxx(000) + 0
	delay(500);
	
	if(ReadACK())					//从机拒绝接收数据
		ACK_Flag = 1;
	else
		ACK_Flag = 0;
	I2cSend_Byte(addr_e2prom);
	
	if(ReadACK())					//从机拒绝接收数据
		ACK_Flag = 1;
	else
		ACK_Flag = 0;
	I2cSend_Byte(e2prom_dat);
	
	if(ReadACK())					//从机拒绝接收数据
		ACK_Flag = 1;
	else
		ACK_Flag = 0;
	
	I2cStop();
}
//
//*******************************接收数据***********************************//
//
//主机接收从机数据
unsigned char I2cRead_Byte()
{
	unsigned char i,read_dat;
		for(i=0;i<8;i++)
	{
		read_dat <<= 1;
		SCL = 0;
			if(SDA)
				read_dat |= 0x01;
			SCL = 1;
			Delay_I2c_5us();
	}

	return read_dat;
}
//主机接收从机数据全过程:
//start-address-ack-start-address-read-ack-stop
unsigned char AT24C02_Read(unsigned char addr_e2prom)
{
	char dat;
	I2cStart();
	
	I2cSend_Byte(AT24C02_ADDR + AT24C02_ADDR_Write);//地址 1010 xxx(000) + 0
	
	if(ReadACK())					//从机拒绝接收数据
		ACK_Flag = 1;
	else
		ACK_Flag = 0;
	I2cSend_Byte(addr_e2prom);
	ReadACK();
	
	I2cStart();
	I2cSend_Byte(AT24C02_ADDR + AT24C02_ADDR_Read);
	
	while(ReadACK())		//从机拒绝接收数据
	{
		XBYTE[0x8000] = 0xfe;
	}
		ACK_Flag = 0;
	XBYTE[0x8000] = 0xff;
	
	dat = I2cRead_Byte();
	
	SendACK(1);
	I2cStop();
	return (dat);
}

//
void Display_smg(unsigned char num)
{
	DisPlaySMG_Bit(0,SMGNoDot_CA[num/100]);
	DelaySMG(150);
	DisPlaySMG_Bit(1,SMGNoDot_CA[(num%100)/10]);
	DelaySMG(150);
	DisPlaySMG_Bit(2,SMGNoDot_CA[num%10]);
	DelaySMG(150);
	
	DisPlay_All(0xff);
	
}
//
void main()
{
	Initial();
	AT24C02_Write(2,9);
	delay(10000);
	while(1)
	{
		Display_smg(AT24C02_Read(2));
	}
}
//

数码管驱动代码:

/*****************************
数码管驱动:
数码管延时/
数码管按位写入/应用于动态显示
数码管全体写入/
*****************************/
#include "absacc.h"

void DelaySMG(unsigned char t)
{
	while(t--);
}

void DisPlaySMG_Bit(unsigned char pos,unsigned char dat)
{
	XBYTE[0XE000] =0xff;
	XBYTE[0XC000] =0x01 << pos;
	XBYTE[0XE000] =dat;
}

void DisPlay_All(unsigned char dat)
{
	XBYTE[0XC000] =0xff;
	XBYTE[0XE000] =dat;
	
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值