你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

IO口模拟I2C通信

[复制链接]
watercici 提问时间:2018-3-15 11:25 /
阅读主题, 点击返回1楼
收藏 评论24 发布时间:2018-3-15 11:25
24个回答
dsjsjf 回答时间:2018-3-15 16:20:12
发一个我在用的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;
}

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

watercici 回答时间:2018-3-15 16:34:32
dsjsjf 发表于 2018-3-15 16:20
发一个我在用的IO模拟IIC程序给你,不需要判断超时
static void I2c_delay_us(uint32_t i)
{

非常感谢,很有帮助
watercici 回答时间:2018-3-15 16:47:41
@dsjsjf   亲,你这个起始信号中拉低了两次SDA,而SCLK只是拉高就不管了,是不是应该把第二遍拉低SDA变为拉低SCLK
1.jpg
xmstudio 回答时间:2018-3-15 16:55:45
模拟I2C有必要吗?我记得有的程序里面有判断是否有ACK,也有的程序没有,可能如果在保证线路不会接触不良的情况下不需要判断是否有ACK吧

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

watercici 回答时间:2018-3-15 16:59:10
dsjsjf 发表于 2018-3-15 16:20
发一个我在用的IO模拟IIC程序给你,不需要判断超时
static void I2c_delay_us(uint32_t i)
{

亲,有两个问题,(1)为什么起始信号中,对SDA有两次拉低,而SCLK拉高一次就不管了呢,我看别的例程就是将SDA拉低后将SCL也拉低;(2)每一个函数中不用设定IO的传输方向吗?比如ACK和等待ACK时SDA的传输方向是不同的啊?
Inc_brza 回答时间:2018-3-15 18:42:22
我是没加,不过我也支持加了能让程序变得更加谨慎

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

Angel_YY 回答时间:2018-3-15 19:24:18
超时是一定要加的,IIC的时序是比较严格的,要按IIC的时序进行。
而PEC则可以不用的。一般用的模拟IIC都没有用到。

评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2

查看全部评分

watercici 回答时间:2018-3-16 10:35:14
Angel_YY 发表于 2018-3-15 19:24
超时是一定要加的,IIC的时序是比较严格的,要按IIC的时序进行。
而PEC则可以不用的。一般用的模拟IIC都没 ...

知道了,谢谢!
watercici 回答时间:2018-3-16 10:42:38

我还想问一下,等ACK用中断吗,中断可是必须的吗
watercici 回答时间:2018-3-16 10:43:13
watercici 发表于 2018-3-16 10:42
我还想问一下,等ACK用中断吗,中断可是必须的吗

如果用硬件I2C的话,等ACK是一定要用中断的吗

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版