初级会员
- 积分
- 141
- 金钱
- 141
- 注册时间
- 2012-8-31
- 在线时间
- 20 小时
|
发表于 2019-12-6 16:50:52
|
显示全部楼层
#define I2C_Over_Time 0xFA //超时处理时间需要根据实际调整
void I2C_init(void)
{
//I2C_FREQR和I2C_CCRL,CCRH ,I2C_TRISER要对应fMASTER频率计算。。
//但测试的效果来看好像又没什么影响。
I2C_FREQR |= 0x10; //输入外设时钟频率为16MHz
I2C_CR1 = 0x00; //禁止I2C外设
I2C_TRISER = 0x0c;
I2C_CCRL = 0x37;
I2C_CCRH = 0x00;
I2C_CR1 |= 0x01; //开启I2C外设
I2C_CR2 |= 0x04; //应答使能
I2C_OARL = 0xfe; //自身地址
I2C_OARH = 0x40;
}
//读IIC器件,
//参数:返回的字节缓冲,器件地址,开始地址,要读的字节数。
void Read_I2C_Dev(u8 *pBuffer,u8 ID_addr,u8 address,u8 Number)
{
u8 cnt=0;
while(I2C_SR3 & 0x02) //等待总线空闲
{
if(++cnt>I2C_Over_Time) //超时退出
{
I2C_CR2|=0x02;
return;
}
}
cnt=0;
I2C_CR2 |= 0x01; //产生起始位
while(!(I2C_SR1 & 0x01)) //等待START发送完
{
if(++cnt>I2C_Over_Time) //超时退出
{
I2C_CR2|=0x02;
return;
}
}
cnt=0;
I2C_DR =ID_addr; //发24c02器件地址
while(!(I2C_SR1 & 0x02)) //等特7位器件地址发送完
{
if(++cnt>I2C_Over_Time) //超时退出
{
I2C_CR2|=0x02;
return;
}
}
cnt=0;
I2C_SR1;
I2C_SR3;
I2C_DR = address;
while(!(I2C_SR1 & 0x84))
{
if(++cnt>I2C_Over_Time) //超时退出
{
I2C_CR2|=0x02;
return;
}
}
cnt=0;
I2C_CR2 |= 0x01; //产生重复起始位
while(!(I2C_SR1 & 0x01)) //等待START发送完
{
if(++cnt>I2C_Over_Time) //超时退出
{
I2C_CR2|=0x02;
return;
}
}
cnt=0;
I2C_DR =ID_addr+1; //读
while(!(I2C_SR1 & 0x02)) //等特7位器件地址发送完
{
if(++cnt>I2C_Over_Time) //超时退出
{
I2C_CR2|=0x02;
return;
}
}
cnt=0;
I2C_SR1;
I2C_SR3;
while(Number) //要读几个字节
{
if(Number== 1)
{
I2C_CR2 &= ~0x04; //不返回应答
I2C_CR2 |= 0x02; //产生停止位
}
if(I2C_SR1 & 0x40)
{
I2C_SR1;
*pBuffer = I2C_DR;
pBuffer++;
Number--;
}
}
I2C_CR2 |= 0x04;
I2C_CR2 &= ~0x08;
} |
|