IIC上拉电阻
IIC上拉电阻计算
1、所有的I2C接口都是OD开漏输出的模式(可以实现线与的功能),因此在使用MCU模拟I2C通信时,SCL和SDA必须配置为OD模式,不能配置为PP推挽输出模式(不能正常通信)
2、SCL和SDA总线需要分别上拉4.7KΩ电阻(一般是)
uint8_t FRAM_TxBuff[10],FRAM_RxBuff[10];
uint8_t FRAM_Addr_Set(uint16_t Addr)
{
uint8_t EEPROM_ADDRESS =0xA0;
if(Addr<0x100) // 选择第一页
{
EEPROM_ADDRESS =0xA0;
}
else if(Addr<0x200)//选择第二页
{
EEPROM_ADDRESS =0xA2;
}
else if(Addr<0x300)//选择第三页
{
EEPROM_ADDRESS =0xA4;
}
else if(Addr<0x400)//选择第四页
{
EEPROM_ADDRESS =0xA6;
}
else if(Addr<0x500)//选择第5页
{
EEPROM_ADDRESS =0xA8;
}
else if(Addr<0x600)//选择第6页
{
EEPROM_ADDRESS =0xAA;
}
else if(Addr<0x700)//选择第7页
{
EEPROM_ADDRESS =0xAC;
}
else if(Addr<0x800)//选择第8页
{
EEPROM_ADDRESS =0xAE;
}
return EEPROM_ADDRESS;
}
void I2C_delay(void)
{
}
bool I2C_Start(void)
{
FRAM_SDA_H;
FRAM_SCL_H;
I2C_delay();
if(!FRAM_SDA_READ)
{return false;}//SDA线为低电平则总线忙,退出
FRAM_SDA_L;
I2C_delay();
if(FRAM_SDA_READ)
{return false;}//SDA线为高电平则总线出错,退出
FRAM_SDA_L; //SCL为高电平时,SDA的下降沿表示停止位
I2C_delay();
return true;
}
void I2C_Stop(void)
{
FRAM_SCL_L;
I2C_delay();
FRAM_SDA_L;
I2C_delay();
FRAM_SCL_H;
I2C_delay();
FRAM_SDA_H; //SCL为高电平时,SDA的上升沿表示停止位
I2C_delay();
}
void I2C_Ack(void)
{
FRAM_SCL_L;
I2C_delay();
FRAM_SDA_L;
I2C_delay();
FRAM_SCL_H;
I2C_delay();
FRAM_SCL_L;
I2C_delay();
}
void I2C_NoAck(void)
{
FRAM_SCL_L;
I2C_delay();
FRAM_SDA_H;
I2C_delay();
FRAM_SCL_H;
I2C_delay();
FRAM_SCL_L;
I2C_delay();
}
bool I2C_WaitAck(void) //返回为:=1有ACK,=0无ACK
{
FRAM_SCL_L;
I2C_delay();
FRAM_SDA_H;
I2C_delay();
FRAM_SCL_H;
I2C_delay();
if(FRAM_SDA_READ)
{
FRAM_SCL_L;
return false;
}
FRAM_SCL_L;
return true;
}
void I2C_SendByte(uint8_t SendByte)
{
uint8_t i;
for(i=0;i<8;i++)
{
FRAM_SCL_L;
I2C_delay();
if(SendByte & 0x80)//数据从高位到低位
{FRAM_SDA_H;} //在SCL为低电平时,允许SDA数据改变
else
{FRAM_SDA_L;}
SendByte <<= 1;
I2C_delay();
FRAM_SCL_H;
I2C_delay();
}
FRAM_SCL_L;
}
uint8_t I2C_ReceiveByte(void) //数据从高位到低位
{
uint8_t i,u_temp_data8 = 0;
FRAM_SDA_H;
for(i=0;i<8;i++)
{
u_temp_data8 <<= 1;
FRAM_SCL_L;
I2C_delay();
FRAM_SCL_H;
I2C_delay();
if(FRAM_SDA_READ)//在SCL为高电平时,SDA上的数据保持不变,可以读回
{u_temp_data8 |= 0x01;}
}
FRAM_SCL_L;
return u_temp_data8;
}
bool FRAM_WriteReg(uint16_t Address,uint8_t*DataBuff,uint8_t DataCount)
{
FRAM_WRITE_ENABLE;
if(!I2C_Start())
{return false;}
I2C_SendByte(0xA0);//设置高起始地址+器件地址
if(!I2C_WaitAck())
{
I2C_Stop();
return false;
}
I2C_SendByte((uint8_t)(Address & 0xFF));
if(!I2C_WaitAck())
{
I2C_Stop();
return false;
}
for(uint8_t k=0;k<DataCount;k++)
{
I2C_SendByte(DataBuff[k]);
if(!I2C_WaitAck())
{
I2C_Stop();
return false;
}
}
I2C_Stop();
I2C_delay();
FRAM_WRITE_DISABLE;
return true;
}
bool FRAM_ReadReg(uint16_t Address,uint8_t*DataBuff,uint8_t DataCount)
{
if(!I2C_Start())
{return false;}
I2C_SendByte(FRAM_Addr_Set(Address));//设置高起始地址+器件地址
if(!I2C_WaitAck())
{
I2C_Stop();
return false;
}
I2C_SendByte((uint8_t)(Address & 0xFF));
if(!I2C_WaitAck())
{
I2C_Stop();
return false;
}
if(!I2C_Start())
{return false;}
I2C_SendByte(FRAM_Addr_Set(Address)+1); //读器件地址
if(!I2C_WaitAck())
{
I2C_Stop();
return false;
}
for(uint8_t k=0;k<DataCount;k++)
{
DataBuff[k]=I2C_ReceiveByte();
if(k!=(DataCount-1))
I2C_Ack();
else
I2C_NoAck();
}
I2C_Stop();
return true;
}