CC2541的I2C接口驱动是否支持AT24Cxx系列的串行EEPROM ?
请问,C:\Texas Instruments\BLE-CC254x-1.3.2\Components\hal\target\CC2541ST\这个目录下的hal_i2c.h和hal_i2c.c文件是否支持AT24Cxx系列的串行EEPROM ?谢谢!
用CSR的也来插一脚。
没有用过CC2541,但是I2C的原理基本都是想通的。
只要CC2541的I2C驱动函数支持16位的reg_add,就能使用AT24Cxx的E2.
如果只支持8位的reg_add,那么你只能使用e2的前256个byte
我正好做项目中用到,这两个文件完全支持AT24xx的EEprom,这是通用的IIC底层驱动,一般IIC器件都支持IIC的读写规范,所以这两个没有问题。对于256K以下的EErom,可直接用hal_sensor,h中的bool HalSensorWriteReg(uint8 addr, uint8 *pBuf, uint8 nBytes),和bool HalSensorReadReg(uint8 addr, uint8 *pBuf, uint8 nBytes) 来进行Epprom的读写即可。但对于at24c256 或 512 ,存储地址是两个字节,需要对这两个函数修改后才能用。
對於使用二個 Byte 定址的 EEPROM (AT24C), 我找到這個網頁, 寫的很清楚, 大推.
ziye334: CC2541对AT24CXX系列存储器的支持
( http://ziye334.lofter.com/post/2435a3_2a2e1b4 )
若是超過二個字節, 則要把位址超過 16 bit 的這幾個 bit 嵌入 Device Address 中. 以 AT24CM01 (1024Kb) 為例, 則要把 memory address bit 16 (由 bit 0 起算) 加入至 device address 的 bit 1.
以下分別為我寫的 Read 與 Write 部份, 可以正確運作.
(其中 Read 部份很怪, 要在 dummy write 之後, 再寫入 I2C_STOP 才能開始 read 的 I2C_STRT, 這點跟 spec 中不同, 目前還搞不懂.)
uint8 My_I2C_Mem_Read(uint32 addr, uint8 len, uint8 *pBuf) { uint8 addrL = 0, addrH = 0, addrHH = 0; //KJ- addrL = (uint8)(addr & 0xff); //KJ- addrH = (uint8)(addr >> 8); //KJ- addrHH = (uint8)( (i2cAddr & 0xFC) | ((addr >> 15) & 0x02) ); //KJ- i2cAddr | P0 //KJ- Dummy Write Start_Signal I2C_STRT(); //KJ- Dummy Write Device_Addr. if ( I2CSTAT == mstStarted ) // A start condition has been transmitted { I2C_WRITE( addrHH & 0xFE ); //KJ- set LSB = 0 for Write } if ( I2CSTAT != mstAddrAckW ) { len = 0; } //KJ- Dummy Write Memory_Addr I2C_WRITE(addrH); //KJ- I2C_WRITE(addrL); //KJ- //KJ- Dummy Write Stop_Signal I2C_STOP(); //KJ- Write Start_Signal for Read I2C_STRT(); if ( I2CSTAT == mstStarted ) // A start condition has been transmitted { I2C_WRITE( addrHH | 0x01 ); //KJ- set LSB = 1 for Read } if ( I2CSTAT != mstAddrAckR ) { len = 0; } // All bytes are ACK'd except for the last one which is NACK'd. If only // 1 byte is being read, a single NACK will be sent. Thus, we only want // to enable ACK if more than 1 byte is going to be read. if (len > 1) { I2C_SET_ACK(); } for (uint8 cnt = 0; cnt < len; cnt++) { // slave devices require NACK to be sent after reading last byte if (cnt == len-1) { I2C_SET_NACK(); } I2C_READ(*pBuf++); // read a byte from the I2C interface if (I2CSTAT != mstDataAckR) { if (I2CSTAT == mstDataNackR) { len = cnt + 1; } else { len = cnt; // something went wrong, so don't count last byte } break; } } I2C_STOP(); return len; }
uint8 My_I2C_Mem_Write(uint32 addr, uint8 len, uint8 *pBuf) { uint8 addrL = 0, addrH = 0, addrHH = 0; //KJ- addrL = (uint8)(addr & 0xff); //KJ- addrH = (uint8)(addr >> 8); //KJ- addrHH = (uint8)( (i2cAddr & 0xFC) | ((addr >> 15) & 0x02) ); //KJ- i2cAddr | P0 //KJ- Write Start_Signal for Read I2C_STRT(); //KJ- Write Device_Addr. if ( I2CSTAT == mstStarted ) /* A start condition has been transmitted */ { I2C_WRITE( addrHH & 0xFE ); //KJ- set LSB = 0 for Write } if ( I2CSTAT != mstAddrAckW ) { len = 0; } //KJ- Write Memory_Addr I2C_WRITE( addrH ); //KJ- I2C_WRITE( addrL ); //KJ- //KJ- Write Data for (uint8 cnt = 0; cnt < len; cnt++) { I2C_WRITE(*pBuf++); if (I2CSTAT != mstDataAckW) { if (I2CSTAT == mstDataNackW) { len = cnt + 1; } else { len = cnt; } break; } } //KJ- Write Stop_Signal I2C_STOP(); return len; }
这个我最近也在写,然后我用的是硬件I2C,咱俩可以交流交流。
你好!
我用硬件I2C对EEROM读取也遇到一个问题就是,只使用一次HalSensorWriteReg()这个函数是可以的,但是如果我连续使用HalSensorWriteReg()这个函数发现只有第一个语句,内容被写入,后面的没有写入。
比如说
HalSensorReadReg(CURRENT_POSITION_ADDR,eerom_data_1,4 );
HalSensorReadReg(START_POSITION_ADDR,eerom_data_2,4 );
只有eerom_data_1这个数组被写入,请大神门在这一块指点一下!
不知道你的是哪款芯片,我是有24C02测试的,也是有这样的问题,调试发现当写完延时它又能写进去第二个的;但当写完一个,如果立即读或者写时,启动信号没有应答,导致读或者写都会失败,不知道你的问题现在解决了没有?
你好!
你要仔细研读一下,24C02的datasheet。存储芯片也是需要时间的,手册里面会提到时序,和步骤的细节。要循环判断好像是 发送启示信号ACK??现在记不清楚了。
不要直接用2451上面例程上面的。总之要研读24C02哦,加油。用示波器观察I2C的信号,也可以把它记录下来,看一下,翻一下数据。
加油!
我也想问这个问题,求回答!
------------
销售气相色谱仪,液相色谱仪,液相色谱柱,电子天平,PH计等