IO口模拟I2C通信

2019-07-14 18:25发布

IO口模拟I2C通信中,是否用加超时检测,和PEC检错,因为我看了很多网上的例程,都没有这俩,但STM32芯片手册中有介绍这两点,那到底用不用呢,怎么用,有这方面的例程吗?方便贴出来给参考一下吗
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
18条回答
TOPCB
1楼-- · 2019-07-15 16:03
 精彩回答 2  元偷偷看……
cknz
2楼-- · 2019-07-15 16:18
要的,卡在里面,多尴尬呀..
tianyou15
3楼-- · 2019-07-15 16:19
发一个我在用的IO模拟IIC程序给你,不需要判断超时
static void I2c_delay_us(uint32_t i)
{
  for(i=0; i<72; i++)
  {
    ;
  }
}

static ErrorStatus I2C_Start(void)         //I2C开始位
{
  Bsp_I2cSdaHigh();
  Bsp_I2cSclHigh();
  I2c_delay_us(5);
  if(!Bsp_IsI2cSda())
    return ERROR;                            //SDA线为低电平则总线忙,退出
  Bsp_I2cSdaLow();
  I2c_delay_us(5);
  if(Bsp_IsI2cSda())
    return ERROR;                            //SDA线为高电平则总线出错,退出
  Bsp_I2cSdaLow();                                                        //SCL为高电平时,SDA的下降沿表示停止位
  I2c_delay_us(5);
  return SUCCESS;
}

static void I2C_Stop(void)                           //I2C停止位
{
  Bsp_I2cSclLow();
  I2c_delay_us(5);
  Bsp_I2cSdaLow();
  I2c_delay_us(5);
  Bsp_I2cSclHigh();
  I2c_delay_us(5);
  Bsp_I2cSdaHigh();                                           //SCL为高电平时,SDA的上升沿表示停止位
  I2c_delay_us(5);
}

static void I2C_Ack(void)                //I2C响应位
{       
  Bsp_I2cSclLow();
  I2c_delay_us(5);
  Bsp_I2cSdaLow();
  I2c_delay_us(5);
  Bsp_I2cSclHigh();
  I2c_delay_us(5);
  Bsp_I2cSclLow();
  I2c_delay_us(5);
}

static void I2C_NoAck(void)                //I2C非响应位
{       
  Bsp_I2cSclLow();
  I2c_delay_us(5);
  Bsp_I2cSdaHigh();
  I2c_delay_us(5);
  Bsp_I2cSclHigh();
  I2c_delay_us(5);
  Bsp_I2cSclLow();
  I2c_delay_us(5);
}

static ErrorStatus I2C_WaitAck(void)           //I2C等待应答位
{
  Bsp_I2cSclLow();
  I2c_delay_us(5);
  Bsp_I2cSdaHigh();                       
  I2c_delay_us(5);
  Bsp_I2cSclHigh();
  I2c_delay_us(5);
  if(Bsp_IsI2cSda())
  {
    Bsp_I2cSclLow();
    return ERROR;
  }
  Bsp_I2cSclLow();
  return SUCCESS;
}

/*******************************************************************************
* Function Name  : I2C_SendByte
* Description    : 数据从高位到低位
* Input          : - SendByte: 发送的数据
* Output         : None
* Return         : None
*******************************************************************************/
static void I2C_SendByte(uint8_t SendByte)
{
  uint8_t i;
  
  for(i=0; i<8; i++)
  {
    Bsp_I2cSclLow();
    I2c_delay_us(5);
    if(SendByte & 0x80)
      Bsp_I2cSdaHigh();                            //在SCL为低电平时,允许SDA数据改变
    else
      Bsp_I2cSdaLow();   
    SendByte <<= 1;
    I2c_delay_us(5);
    Bsp_I2cSclHigh();
    I2c_delay_us(5);
  }
  Bsp_I2cSclLow();
}

/*******************************************************************************
* Function Name  : I2C_ReceiveByte
* Description    : 数据从高位到低位
* Input          : None
* Output         : None
* Return         : I2C总线返回的数据
*******************************************************************************/
static uint8_t I2C_ReceiveByte(void)  
{
  uint8_t i,ReceiveByte = 0;
  
  Bsp_I2cSdaHigh();                               
  for(i=0; i<8; i++)
  {
    ReceiveByte <<= 1;      
    Bsp_I2cSclLow();
    I2c_delay_us(5);
    Bsp_I2cSclHigh();
    I2c_delay_us(5);       
    if(Bsp_IsI2cSda())                                   //在SCL为高电平时,SDA上的数据保持不变,可以读回来
    {
      ReceiveByte |= 0x01;
    }
  }
  Bsp_I2cSclLow();
  return ReceiveByte;
}
YY599566
4楼-- · 2019-07-15 18:24
tianyou15 发表于 2018-8-23 17:57
发一个我在用的IO模拟IIC程序给你,不需要判断超时
static void I2c_delay_us(uint32_t i)
{

非常感谢,很有帮助
YY599566
5楼-- · 2019-07-15 20:04
@dsjsjf   亲,你这个起始信号中拉低了两次SDA,而SCLK只是拉高就不管了,是不是应该把第二遍拉低SDA变为拉低SCLK
60user126
6楼-- · 2019-07-15 21:58
 精彩回答 2  元偷偷看……

一周热门 更多>