您的位置:首页 > 其它

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");
}
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: