读写Eeprom

使用I2c协议读写Eeprom的例子

Eeprom是一种可擦除反复编程的存储器,掉电也可以保存里面的数据不会丢失,可多次循环编程利用。接下来我们就是要用I2c协议读写Eeprom了。

我们先看一下Eeprom读写时讯,同样在最后我会放出我们读写完Eeprom后,逻辑分析仪出现的结果然后一一分析是为什么.

首先根据I2c配置初始化使能引脚、时钟。里面还包括写一个字节。代码如下。PS(调用的i2c.WriteByte()函数实现过程参考我之前发的I2c库函数里面有具体代码)

///Initializes all necessary hardware
void I2cEeprom::Initialize(uint8_t channel)
{	
	i2c.Initialize(channel);

	//The parameter inside the function call can be 100 400 500.
	//Corresponding to the general mode(100), fast mode(400), fast plus mode(500).
	i2c.I2cClockSpeed(100);
	ConfigPins();
}

void I2cEeprom::ConfigPins()
{
	I2c::I2cPinConfig pinConfig;
	pinConfig.sclPin = 8;
	pinConfig.sclAltNum = 4;
	pinConfig.sclCh = Gpio::_ChB;
									
	pinConfig.sdaPin = 9;
	pinConfig.sdaAltNum = 4;
	pinConfig.sdaCh = Gpio::_ChB;

	i2c.ConfigPins(pinConfig);
	wpPin.Initialize(Gpio::_ChA, 2, Gpio::_High);
}

///sends one byte
void I2cEeprom::WriteByte(const uint8_t txData, uint8_t wordAddress)
{
	WpDisable();
	i2c.WriteByte(txData, dev_write_addr);
	WpEnable();
}

                                                                     按页写eeprom.


我们可以看到Eeprom的页写,页写比单节写效率更高。每页大小是8字节。代码如下。PS(里面调用的是I2c读写多个字节WriteBytesWithHeader函数)

///Write a number of bytes in a EEPROM write cycle
///However,the number of bytes written at a time can not exceed the size of the EEPROM page
///The AT24C02 has 8 bytes per page
void I2cEeprom::WritePage(uint8_t *txData, uint8_t size, uint8_t wordAddress)
{
	uint8_t bytesThisCycle = 0;

	bytesThisCycle = _I2cPageSize - (wordAddress & 0X07);

	WpDisable();

	while (size > 0)
	{
		if (size < bytesThisCycle) bytesThisCycle = size;

		i2c.WriteBytesWithHeader(txData, bytesThisCycle, wordAddress, dev_write_addr);

		txData += bytesThisCycle;
		wordAddress += bytesThisCycle;
		size -= bytesThisCycle; 
		bytesThisCycle = _I2cPageSize;

		System::DelayUs(10000);
	}

	WpEnable();
}页写分析:我们在页写的时候算出Eeprom的启始地址,数据启始地址,还剩多少字节传输。


随机读eeprom 


我们可以看到eeprom的随机读,它是先用写一个设备地址然后一个字节地址,但是里面不能有数据传输和停止信号的一个伪写,当写发送一个启始信号。接着用read发送正常的读信号。代码如下。

///read multiple bytes
uint8_t I2cEeprom::ReadBytes(uint8_t* rxData, uint8_t rxSize, uint8_t wordAddress)
{
	i2c.DisableAutoStop();
	i2c.WriteByte(wordAddress,dev_write_addr);
	while ( !i2c.IsTransferComplete() ) {}
	i2c.ReadBytes(rxData, rxSize, dev_read_addr);
	while ( !i2c.IsTransferComplete() ) {}
	i2c.ManualStop();
	i2c.EnableAutoStop();
}
代码分析:里面调用了I2c写一个字节但是里面已经使停止信号失能,然后就是调用读多个字节。如果需要源代码可以留言。


主函数如下:

int main(void)
{
	uint8_t write[] = {1,2,3,4,5,6,7,8,9,10,11};
	uint8_t read[11] = {};

	System::Initialize();
	System::ConfigureForHsi();
	i2ceeprom.Initialize(1);

	while (1)
	{
		i2ceeprom.WritePage(write,5, 0xa8);
		System::DelayUs(10000);
		i2ceeprom.ReadBytes(read, 5, 0xa8);
		System::DelayUs(10000);
	}
}

最后我们看一下逻辑分析仪的结果吧。

     

我们可以看到与手册里面的写时序是一样的。里面160是设备地址10100000,168是字节地址。



我们看一写读时序,我们之前看了随机读的时序图,所以我们知道要先伪写入一个设备地址一个字节地址,有一个开始信号,然后再一个开始信号(图中绿色的点是开始信号,红色是停止信号。)



eeprom的读写大概就是这样的啦。如果想参考源代码,可以留言。







    

猜你喜欢

转载自blog.csdn.net/weixin_39770778/article/details/78930943