读写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
文章图片


我们可以看到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
文章图片


我们可以看到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
文章图片




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




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













【读写Eeprom】

    推荐阅读