CC2538 zigbee I2C示例代码读写AT24C02D eeprom
2017-06-22 17:24
323 查看
AT24C02D
AT24C02D由于不是标准的I2C总线,所以没有完全使用I2C的8字节地址总线,而是使用了5+3外部引脚设置(A2,A1,A0)来决定和哪路器件通讯的,一个i2c总线上最多能挂载8个AT24C02D,刚好是2的三次方。不明白为什么AT24C02D把i2c里面的sub address叫做Word Address,很是奇怪,我这里表述都按照sub address来表述,下同。
AT24C02D 作为CC2538外挂的eeprom,通过i2c总线和CC2538通讯,实现读写,花了很长时间一直搞不定,网上找的十有八九都是什么GPIO模拟i2c,我的CC2538本身就有i2c接口,还模拟什么模拟。
开始没搞懂读写AT24C02D eeprom,以为和普通的i2c器件一样,写的话,发送slave address+ sub address+data,就可以写了,读的话,发送slave address+sub address,就可以读出指定地址的数据了,其实是错的。
我们都知道,i2c有起始位,也就是Start,有停止位,也就是Stop。写的话,按照eeprom芯片手册给的时序图,就是Start以后,发送从机地址slave address,发送完从机地址,是不能有Stop的,必须接着发送sub address,然后也不能有Stop,接着发送data,就是需要写入的数据,最后再发送Stop,才算是完成了一次写操作,真麻烦。
读的话,芯片手册里面提到的有三种读的方式,分别为Current Address Read、Random Address Read、Sequential Read,
我们这里先探讨随机读,我认为说是随机读不太准确,应该是读取指定地址的数据才准确。随机读实际上是通过写入一个地址改变eeprom里面data word address 的值,然后再进行当前地址读。并不是直接发送slave address+sub address就可以读的。读之前,必须先把slave address+sub address写进去,延时20ms,然后再开始读,读的时候,只需要给slave address就可以,不需要sub address,就能读出数据了。
CC2538 I2C功能
找遍互联网,也找不到CC2538 I2C相关的示例代码,除了一个master_slave_loopback.c示例回环读写i2c之外,别的要么是什么gpio模拟i2c,要么是什么firmware foundation提供的示例代码,竟没有一个是真正能成功使用过的。看来使用CC2538的人少的很,多数人都用CC2530带十几个二十个节点满足home应用就完事了。给出CC2538 i2c读写eeprom头文件:
/* Atmel AT24C02 EEPROM read and write */ #ifndef HAL_EEPROM_H #define HAL_EEPROM_H #include <stdint.h> #ifdef __cplusplus extern "C" { #endif /* * PC.6->I2C_SCL * PC.7->I2C_SDA */ #define I2C_SCL GPIO_PIN_6 #define I2C_SDA GPIO_PIN_7 #define GPIO_I2C_BASE GPIO_C_BASE void HalEepromInit(void); uint32_t HalEepromWriteByte(uint8 slaveAddr,uint32_t subAddr,uint32_t data); uint32_t HalEepromReadByte(uint8 slaveAddr,uint32_t subAddr); uint32_t HalEepromReadByteEx(uint8 slaveAddr,uint32_t subAddr); #ifdef __cplusplus } #endif #endif
给出CC2538 i2c读写eeprom的源文件,可以参考i2c功能的使用和eeprom功能的使用
/************************************************************************************************** * INCLUDES * * Description: Atmel Inc AT24C02D eeprom chip write and read. For CC2538 cortex-M3 core * * **************************************************************************************************/ #include <string.h> #include "hal_types.h" #include "hal_eeprom.h" #include "hw_ioc.h" #include "hal_mcu.h" void HalEepromInit(void) { #if (HAL_EEPROM == TRUE) // // Set the clocking to run directly from the external crystal/oscillator. // (no ext 32k osc, no internal osc) // SysCtrlClockSet(false, false, SYS_CTRL_SYSDIV_32MHZ); // // Set IO clock to the same as system clock // SysCtrlIOClockSet(SYS_CTRL_SYSDIV_32MHZ); // // The I2C peripheral must be enabled before use. // SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_I2C); // // Do reset of I2C module // SysCtrlPeripheralReset(SYS_CTRL_PERIPH_I2C); // // Configure I2C physical pins // GPIOPinTypeI2C(GPIO_I2C_BASE, I2C_SCL); GPIOPinTypeI2C(GPIO_I2C_BASE, I2C_SDA); // Configure pins as peripheral input and output //IOCPinConfigPeriphInput(GPIO_I2C_BASE, I2C_SCL,IOC_I2CMSSCL); IOCPinConfigPeriphInput(GPIO_I2C_BASE, I2C_SDA,IOC_I2CMSSDA); IOCPinConfigPeriphOutput(GPIO_I2C_BASE, I2C_SCL,IOC_MUX_OUT_SEL_I2C_CMSSCL); IOCPinConfigPeriphOutput(GPIO_I2C_BASE, I2C_SDA,IOC_MUX_OUT_SEL_I2C_CMSSDA); // data rate setting // fase:100kbps // true:400kbps I2CMasterInitExpClk(SysCtrlClockGet(), false); #endif } /* *Write data to external eeprom(AT24C02D) * @param 7-bit of slave address @param 8-bit of sub-address @param byte to be write @param index of total eeprom(0~255) */ uint32_t HalEepromWriteByte(uint8 slaveAddr,uint32_t subAddr,uint32_t data) { #if (HAL_EEPROM == TRUE) if(subAddr < 0xFF) { //set slave address(Device Address) I2CMasterSlaveAddrSet(slaveAddr,false); //false:write //set sub address(Word Address) I2CMasterDataPut(subAddr); I2CMasterControl(I2C_MASTER_CMD_BURST_SEND_START); //star+run // Wait until master module is done transferring. while(I2CMasterBusy()){} // Place the data to be sent in the data register I2CMasterDataPut(data); I2CMasterControl(I2C_MASTER_CMD_BURST_SEND_FINISH); //run+stop // Wait until master module is done transferring. while(I2CMasterBusy()){} } #endif return 0; } /* * dummy write for read purpose @param index of total eeprom(0~255) */ uint32_t HalEepromReadByte(uint8 slaveAddr,uint32_t subAddr) { uint32_t uRead=0; #if (HAL_EEPROM == TRUE) if(subAddr < 0xFF) { //1. dummy write //set slave address(Device Address) I2CMasterSlaveAddrSet(slaveAddr,false); //false:write //set sub address(Word Address) I2CMasterDataPut(subAddr); I2CMasterControl(I2C_MASTER_CMD_BURST_SEND_START); while(I2CMasterBusy()){} } #endif return uRead; } /* * Radom read(AT24C02D chip),read the specify Word address * @param index of total eeprom(0~255) */ uint32_t HalEepromReadByteEx(uint8 slaveAddr,uint32_t subAddr) { uint32_t uRead=0; #if (HAL_EEPROM == TRUE) if(subAddr < 0xFF) { //2. actual read I2CMasterSlaveAddrSet(slaveAddr,true); I2CMasterControl(I2C_MASTER_CMD_SINGLE_RECEIVE); // Read the data from the master. // uRead = I2CMasterDataGet(); while(I2CMasterBusy()){} } #endif return uRead; }
相关文章推荐
- javascript读写TEXT文本文件示例代码
- C#.NET示例读写xml所有节点的代码实现方法和读取xml节点的数据总结
- 集算器读写EXCEL文件的代码示例
- 读写注册表的示例代码(待更新)
- io流操作之读写示例代码(一)
- C#.NET示例读写xml所有节点的代码实现方法和读取xml节点的数据总结
- shapefile格式的说明及读写代码示例
- shapefile格式说明及读写代码示例
- shapefile格式说明及读写代码示例
- SSE命令示例代码(整型、读写控制寄存器、混杂、矩阵变换)
- shapefile格式说明及读写代码示例 --http://www.gispower.org/article/arcgis/arcother/2008/48/0848115049GB922C13K2I22H7G06A4.html
- shapefile格式说明及读写代码示例
- shapefile格式说明及读写代码示例(C++)(转)
- shapefile格式说明及读写代码示例(C++)(转)
- c#/ASP.NET操作cookie(读写)代码示例
- 利用I2C总线读写AT24C512的FPGA原创代码
- io流操作之读写示例代码(二)
- ASP.NET中读写cookie数据示例代码
- C/C++读写注册表中二进制数据【代码示例】
- Windows系统中C#读写ini配置文件的程序代码示例分享