I2C通信问题

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


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值