cc2541 硬件i2c 读AT24CM01
2016-08-19 11:36
211 查看
之前一直读不出数据,设备地址对了,宏定义添加了,但就是读不出数据,调试这个花了我一天半的时间!不能忍:检查自己确实没有错误后,唯一一个需要注意的地方就是,写函数后不能立即调用读函数,因为在写需要一定时间,如果还没写完就去读那就会读取失败。
写函数需要注意跨页问题,读函数则不用,直接读就好。
关于跨页,不同芯片对应不同页数和一页的字节数,在传进来的地址需要判断是否已经另起一页,特别注意:一定要延时,留时间给上页写入完成,才能写新的一页数据。
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)( (i2cAddrSave & 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++)
{
if ((addr&0xff) == 0) //检查地址是否到达页边界,AT24CM01每页256字节,所以检测低7位是否为零即可
{
I2C_STOP();
Hal_HW_WaitUs(500);//延时等待上次写入操作完成,大概延时0.5ms,写过程需要大概0.5ms
addrL = (uint8)(addr & 0xff); //KJ-
addrH = (uint8)(addr >> 8); //KJ-
addrHH = (uint8)( (i2cAddrSave & 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-
}
I2C_WRITE(*pBuf++);
addr++;
if (I2CSTAT != mstDataAckW)
{
if (I2CSTAT == mstDataNackW)
{
len = cnt + 1;
}
else
{
len = cnt;
}
break;
}
}
//KJ- Write Stop_Signal
I2C_STOP();
return len;
}
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)( (i2cAddrSave & 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;
}
/**************************延时函数********************************************/
void Hal_HW_WaitUs(uint16 microSecs)
{
while(microSecs--)
{
/* 32 NOPs == 1 usecs */
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop");
}
}
写函数需要注意跨页问题,读函数则不用,直接读就好。
关于跨页,不同芯片对应不同页数和一页的字节数,在传进来的地址需要判断是否已经另起一页,特别注意:一定要延时,留时间给上页写入完成,才能写新的一页数据。
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)( (i2cAddrSave & 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++)
{
if ((addr&0xff) == 0) //检查地址是否到达页边界,AT24CM01每页256字节,所以检测低7位是否为零即可
{
I2C_STOP();
Hal_HW_WaitUs(500);//延时等待上次写入操作完成,大概延时0.5ms,写过程需要大概0.5ms
addrL = (uint8)(addr & 0xff); //KJ-
addrH = (uint8)(addr >> 8); //KJ-
addrHH = (uint8)( (i2cAddrSave & 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-
}
I2C_WRITE(*pBuf++);
addr++;
if (I2CSTAT != mstDataAckW)
{
if (I2CSTAT == mstDataNackW)
{
len = cnt + 1;
}
else
{
len = cnt;
}
break;
}
}
//KJ- Write Stop_Signal
I2C_STOP();
return len;
}
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)( (i2cAddrSave & 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;
}
/**************************延时函数********************************************/
void Hal_HW_WaitUs(uint16 microSecs)
{
while(microSecs--)
{
/* 32 NOPs == 1 usecs */
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop"); asm("nop"); asm("nop"); asm("nop");
asm("nop"); asm("nop");
}
}
相关文章推荐
- android 字符串拼接
- Andrew Ng coursera上的《机器学习》ex1
- java2ee Spring学习计划
- javascript简单实现跟随滚动条漂浮的返回顶部按钮效果
- Python中通过cx_oracle操作ORACLE数据库的封闭函数
- CSS伪对象选择符整理
- [转]Activemq管理和基本介绍
- POJ Number Sequence 1019
- iOS静态库与动态库
- python对文件的简单操作
- xcodebuild & xcrun & xctool 脚本打包
- Google开源OCR项目Tesseract训练(自己训练的记录,未成功)
- 禁用系统的Ctrl+Alt+Left/Right(方向键)
- npm ERR! tar.unpack untar error
- C语言入门-第一周:作业01
- POI
- Freemarker 自定义标签 实现TemplateDirectiveModel
- 笑笑
- git删除分支
- LeetCode 203. Remove Linked List Elements