5563|3

73

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

版主,STM32I2C疑惑 [复制链接]

问题一:STM32的I2C里那个BUSY位,置1的条件是SDA或SCL为低,是包括自己发起传输时将SDA和SCL拉低吗,是否意思是,不管这两条线是谁拉低的,只要有一根线出现低电平就置位BUSY?清除的条件是检测到STOP,那这个STOP是包括自己发出的STOP的还是总线上其它器件产生的?
Bit 1 BUSY: Bus busy
0: No communication on the bus
1: Communication ongoing on the bus
–Set by hardware on detection of SDA or SCL low
–cleared by hardware on detection of a Stop condition.
It indicates a communication in progress on the bus. This information is still updated when
the interface is disabled (PE=0).

问题二:STM32108PKT I2C-E2PROM例程里,I2C_Comm_MasterSend函数里发送完数据后最后有一段   "/* launch check write status procedure */"的代码,又等待1s,等待总线空闲,发start,address,stop什么的,有什么用?我去掉这一段的话,在发送函数之后需要加一段延时才能跟接收函数,否则返回ADDR_MATCH_ERR错误,这又是为什么,因为本身接收函数里就有一等待/判断总线空闲代码



I2C_Result  I2C_Comm_MasterSend(I2C_TypeDef* I2Cx, uint16_t slaveaddr, uint8_t offset, uint8_t* pBuffer, uint32_t length)
{
__IO uint32_t check_time = 0;
    /*wait 5us min for bus free time limitation for later transaction*/
    *(uint32_t *)0xe000e014 = one_us_unit*5;     //SysTick_SetReload(one_us_unit*5);
    *(uint32_t *)0xe000e018 = 0;                 //SysTick_CounterCmd(SysTick_Counter_Clear);
    *(uint32_t *)0xe000e010 |= 1;                //SysTick_CounterCmd(SysTick_Counter_Enable);
    while(!I2C_OT);
    *(uint32_t *)0xe000e010 &= 0xfffffffe;       //SysTick_CounterCmd(SysTick_Counter_Disable);
    I2C_OT = FALSE;   
   
   
    /*wait bus free*/
    *(uint32_t *)0xe000e014 = BUS_BUSY_TIMEOUT;  //SysTick_SetReload(BUS_BUSY_TIMEOUT);
    *(uint32_t *)0xe000e018 = 0;                 //SysTick_CounterCmd(SysTick_Counter_Clear);
    *(uint32_t *)0xe000e010 |= 1;                //SysTick_CounterCmd(SysTick_Counter_Enable);
    while((I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY))&&(!I2C_OT));
    *(uint32_t *)0xe000e010 &= 0xfffffffe;       //SysTick_CounterCmd(SysTick_Counter_Disable);
    if (I2C_OT)
    {
      I2C_OT = FALSE;
      return BUS_BUSY;
    }
   
   
    /*send start and wait*/
    I2C_GenerateSTART(I2Cx, ENABLE);
    *(uint32_t *)0xe000e014 = SEND_START_TIMEOUT;  //SysTick_SetReload(SEND_START_TIMEOUT);
    *(uint32_t *)0xe000e018 = 0;                   //SysTick_CounterCmd(SysTick_Counter_Clear);
    *(uint32_t *)0xe000e010 |= 1;                  //SysTick_CounterCmd(SysTick_Counter_Enable);
    while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT) || I2C_OT));
    *(uint32_t *)0xe000e010 &= 0xfffffffe;         //SysTick_CounterCmd(SysTick_Counter_Disable);
    if (I2C_OT)
    {
      I2C_OT = FALSE;
      return SEND_START_ERR;
    }  
   
   
    /* send 7-bit slave address and wait */
    I2C_Send7bitAddress(I2Cx, (u8)(slaveaddr & 0xFF), I2C_Direction_Transmitter);
    *(uint32_t *)0xe000e014 = SEND_ADDR7_TIMEOUT;  //SysTick_SetReload(SEND_ADDR7_TIMEOUT);
    *(uint32_t *)0xe000e018 = 0;                   //SysTick_CounterCmd(SysTick_Counter_Clear);
    *(uint32_t *)0xe000e010 |= 1;                  //SysTick_CounterCmd(SysTick_Counter_Enable);
    while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) || I2C_OT));  
    *(uint32_t *)0xe000e010 &= 0xfffffffe;         //SysTick_CounterCmd(SysTick_Counter_Disable);
    if (I2C_OT)
    {
      I2C_OT = FALSE;
      I2C_GenerateSTOP(I2Cx, ENABLE);
      while ((I2Cx->CR1 & 0x200) == 0x200);   //wait while stop bit not cleared
      if(I2C_GetFlagStatus(I2Cx, I2C_FLAG_AF))
        I2C_ClearFlag(I2Cx, I2C_FLAG_AF);
      return ADDR_MATCH_ERR;
    }   
        
    /* send offset if needed */
    if (offset != 0xff)
    {
      I2C_SendData(I2Cx, offset);
      *(uint32_t *)0xe000e014 = SEND_DATA_TIMEOUT; //SysTick_SetReload(SEND_DATA_TIMEOUT);
      *(uint32_t *)0xe000e018 = 0;                 //SysTick_CounterCmd(SysTick_Counter_Clear);
      *(uint32_t *)0xe000e010 |= 1;                //SysTick_CounterCmd(SysTick_Counter_Enable);
      while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED) || I2C_OT));
      *(uint32_t *)0xe000e010 &= 0xfffffffe;       //SysTick_CounterCmd(SysTick_Counter_Disable);
      if (I2C_OT)
      {
        I2C_OT = FALSE;
        I2C_GenerateSTOP(I2Cx, ENABLE);
        while ((I2Cx->CR1 & 0x200) == 0x200);   //wait while stop bit not cleared
        if(I2C_GetFlagStatus(I2Cx, I2C_FLAG_AF))
          I2C_ClearFlag(I2Cx, I2C_FLAG_AF);
        return DATA_TIMEOUT;
      }
    }
  
    I2C_SendData(I2Cx, *pBuffer++);
    length--;
    while (length--)
    {
        *(uint32_t *)0xe000e014 = SEND_DATA_TIMEOUT;
        *(u32 *)0xe000e018 = 0;                 
        *(uint32_t *)0xe000e010 |= 1;               
        while (((I2C_GetLastEvent(I2Cx) & 0x04) != 0x04)&&(!I2C_OT));  
        *(uint32_t *)0xe000e010 &= 0xfffffffe;  
        if (I2C_OT)
        {
          I2C_OT = FALSE;
          I2C_GenerateSTOP(I2Cx, ENABLE);
          while ((I2Cx->CR1 & 0x200) == 0x200);
          if(I2C_GetFlagStatus(I2Cx, I2C_FLAG_AF))
            I2C_ClearFlag(I2Cx, I2C_FLAG_AF);
          return DATA_TIMEOUT;
        }
        I2C_SendData(I2Cx, *pBuffer++);
    }
    *(uint32_t *)0xe000e014 = SEND_DATA_TIMEOUT;
    *(uint32_t *)0xe000e018 = 0;                 
    *(uint32_t *)0xe000e010 |= 1;
    while (!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED) || I2C_OT));
    *(uint32_t *)0xe000e010 &= 0xfffffffe;
    if (I2C_OT)
    {
      I2C_OT = FALSE;
      I2C_GenerateSTOP(I2Cx, ENABLE);
      while ((I2Cx->CR1 & 0x200) == 0x200);
      if(I2C_GetFlagStatus(I2Cx, I2C_FLAG_AF))
        I2C_ClearFlag(I2Cx, I2C_FLAG_AF);
      return DATA_TIMEOUT;
    }

    /* send stop to close communication */
    I2C_GenerateSTOP(I2Cx, ENABLE);
  
   
    /* launch check write status procedure */能力 //以下代码毛用?
    while(check_time != 1000000/5)
    {
      /*wait 5us min for bus free time limitation for later transaction : check phase*/
      *(uint32_t *)0xe000e014 = one_us_unit*5;     //SysTick_SetReload(one_us_unit*5);
      *(uint32_t *)0xe000e018 = 0;                 //SysTick_CounterCmd(SysTick_Counter_Clear);
      *(uint32_t *)0xe000e010 |= 1;                //SysTick_CounterCmd(SysTick_Counter_Enable);
      while(!I2C_OT);
      *(uint32_t *)0xe000e010 &= 0xfffffffe;       //SysTick_CounterCmd(SysTick_Counter_Disable);
      I2C_OT = FALSE;  
   
      /* wait bus for free */
      *(uint32_t *)0xe000e014 = CHECK_TIMEOUT;
      *(uint32_t *)0xe000e018 = 0;
      *(uint32_t *)0xe000e010 |= 1;
      while((I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY))&&(!I2C_OT));
      *(uint32_t *)0xe000e010 &= 0xfffffffe;
      I2C_OT = FALSE;
      if (I2C_OT)         //上面这句都已经赋为FALSE了,还判断它的真假????
      {
        I2C_OT = FALSE;
        /* during 1s, bus is occupied by other i2c comm */  
        /* after check_timeout(1s), target's internal must complete */
        return NO_ERR;     //如果I2C_OT为真都已经超时了,还返回NO_ERR??
      }      
      
      I2C_GenerateSTART(I2Cx, ENABLE);
      while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
      I2C_Send7bitAddress(I2Cx, slaveaddr, I2C_Direction_Transmitter);
      
       /* wait for 10 I2C clock pulse period and then check ADDR set or not*/
      *(uint32_t *)0xe000e014 = one_us_unit*i2c_10clk_us;
      *(uint32_t *)0xe000e018 = 0;
      *(uint32_t *)0xe000e010 |= 1;
      while(!I2C_OT);
      *(uint32_t *)0xe000e010 &= 0xfffffffe;
      I2C_OT = FALSE;
      if(I2C_GetFlagStatus(I2Cx, I2C_FLAG_ADDR))
      {
        break;
      }
      I2C_ClearFlag(I2Cx, I2C_FLAG_AF);   
      I2C_GenerateSTOP(I2Cx, ENABLE);
      while ((I2Cx->CR1 & 0x200) == 0x200);    //STOP bit
   
      check_time++;
    }
    if (check_time ==1000000/5)
      return WRITE_FAILURE;
    I2C_ClearFlag(I2Cx, I2C_FLAG_AF);   
    I2C_GenerateSTOP(I2Cx, ENABLE);
    while ((I2Cx->CR1 & 0x200) == 0x200);   

    return NO_ERR;
}
此帖出自stm32/stm8论坛

最新回复

                                 1)总线信号当然包括自己在总线上产生的信号。  详情 回复 发表于 2010-5-21 13:35
点赞 关注
 

回复
举报

68

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
1)按总线信号为准。
2)这个问题与EEPROM的时序有关,你要看看EEPROM的手册。
此帖出自stm32/stm8论坛
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

板凳
 


2# 版主
1.总线信号包不包括自己在总线上产生的信号?
2.明白,这应该是在写操作之后一直试探EEPROM是否能够对地址应答,以确定它内部编程完成.
此帖出自stm32/stm8论坛
 
 

回复

67

帖子

0

TA的资源

一粒金砂(初级)

4
 
                                 1)总线信号当然包括自己在总线上产生的信号。
此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表