读写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的读写大概就是这样的啦。如果想参考源代码,可以留言。
【读写Eeprom】
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- iOS中的Block
- Linux下面如何查看tomcat已经使用多少线程
- 使用composer自动加载类文件
- android|android studio中ndk的使用
- 使用协程爬取网页,计算网页数据大小