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

【经验分享】stm32f3的i2c使用小结

[复制链接]
STMCU小助手 发布时间:2021-12-5 10:44
这几天拿到了stm32f3discovery,拿到手的第一件事就是测试了硬件i2c,使用stm32cube生成库,测试对象为AD5934与ADG715。经过两天的调试,完美调通。中间也碰到了些问题。
1、一开始用的I2C1,一仿真就会出现死机的情况。
        由于I2C1与swd接口重合,所以调用HAL_I2C_Init()函数后就死机,改成I2C2后问题解决。
2、无法访问指定地址的设备
        库函数中的入口地址并不是7bit地址,需要输入8bit。我的设备地址为13,始终无法访问设备,改为26后解决。
3、可以读写单个地址的数据,但是不能多字节读写。
       (1)、对于多字节写, 库函数中的
        HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)
       其中 MemAddSize表示地址的位数,0表示7bit地址,1表示10bit地址。我误认为这个写的字节数,所以导致在写多字节的时候出错。
       (2)、对于多字节读,由于AD5934的读操作与库函数的读操作有些出入,所以导致一直读错误。在库函数中写完读的内存地址就开始读,而AD5934中写完block read后接着还要再写一个number bytes read然后才开始读。所以需要对库函数进行修改,新增一个函数,以适合AD5934的block read.


        stm32f3的i2c有三种模式:Reload、AutoEnd、SoftEnd模式。

        i2c每发送完一个字节,就会产生TXIS标志,当发送完最后一个字节时:

        对于Reload模式,当字节大于255字节时,必须使用此模式,此模式下发送结束后,会产生tcr标志。

        对于AutoEnd模式,发送后最后一个字节时,会自动产生STOP。

        对于SoftEnd模式,发送完最后一个字节时,会产生tc标志,对于发送过程中需要Restart的需要使用此模式。

        对于AD5934的读操作,可以事先工作在SoftEnd模式,发送完block read与number bytes read字节后,再转入AutoEnd模式进行Restart,读取完指定的字节后自动产生STOP。操作流程如下:

  1. HAL_StatusTypeDef   HAL_I2C_Mem_Read_AD5934_Block ( I2C_HandleTypeDef   * hi2c ,   uint16_t   DevAddress ,   uint16_t   MemAddress ,   uint16_t   MemAddSize ,   uint8_t   * pData ,   uint16_t   Size ,   uint32_t   Timeout )
  2. {
  3.    uint32_t   Sizetmp   =   0 ;

  4.    /* Check the parameters   */
  5.    assert_param ( IS_I2C_MEMADD_SIZE ( MemAddSize ));

  6.    if ( hi2c -> State   ==   HAL_I2C_STATE_READY )
  7.    {     
  8.      if (( pData   ==   NULL )   ||   ( Size   ==   0 ))  
  9.      {
  10.        return    HAL_ERROR ;                                    
  11.      }

  12.      if ( __HAL_I2C_GET_FLAG ( hi2c ,   I2C_FLAG_BUSY )   ==   SET )
  13.      {
  14.        return   HAL_BUSY ;
  15.      }

  16.      /* Process Locked */
  17.      __HAL_LOCK ( hi2c );

  18.      hi2c -> State   =   HAL_I2C_STATE_MEM_BUSY_RX ;
  19.      hi2c -> ErrorCode   =   HAL_I2C_ERROR_NONE ;
  20.      /*
  21.     //Send Slave Address and Memory Address
  22.     if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize, Timeout) != HAL_OK)
  23.     {
  24.       if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
  25.       {
  26.         // Process Unlocked
  27.         __HAL_UNLOCK(hi2c);
  28.         return HAL_ERROR;
  29.       }
  30.       else
  31.       {
  32.         // Process Unlocked
  33.         __HAL_UNLOCK(hi2c);
  34.         return HAL_TIMEOUT;
  35.       }
  36.     }*/

  37.      I2C_TransferConfig ( hi2c , DevAddress , MemAddSize + 1 ,   I2C_SOFTEND_MODE ,   I2C_GENERATE_START_WRITE );

  38.      /* Wait until TXIS flag is set */
  39.      if ( I2C_WaitOnTXISFlagUntilTimeout ( hi2c ,   Timeout )   !=   HAL_OK )
  40.      {
  41.        if ( hi2c -> ErrorCode   ==   HAL_I2C_ERROR_AF )
  42.        {
  43.          return   HAL_ERROR ;
  44.        }
  45.        else
  46.        {
  47.          return   HAL_TIMEOUT ;
  48.        }
  49.      }

  50.      /* If Memory address size is 8Bit */
  51.      if ( MemAddSize   ==   I2C_MEMADD_SIZE_8BIT )
  52.      {
  53.        /* Send Memory Address */
  54.        hi2c -> Instance -> TXDR   =   __HAL_I2C_MEM_ADD_LSB ( MemAddress );     
  55.      }      
  56.      /* If Mememory address size is 16Bit */
  57.      else
  58.      {
  59.        /* Send MSB of Memory Address */
  60.        hi2c -> Instance -> TXDR   =   __HAL_I2C_MEM_ADD_MSB ( MemAddress );  

  61.        /* Wait until TXIS flag is set */
  62.        if ( I2C_WaitOnTXISFlagUntilTimeout ( hi2c ,   Timeout )   !=   HAL_OK )
  63.        {
  64.          if ( hi2c -> ErrorCode   ==   HAL_I2C_ERROR_AF )
  65.          {
  66.            return   HAL_ERROR ;
  67.          }
  68.          else
  69.          {
  70.            return   HAL_TIMEOUT ;
  71.          }
  72.        }

  73.        /* Send LSB of Memory Address */
  74.        hi2c -> Instance -> TXDR   =   __HAL_I2C_MEM_ADD_LSB ( MemAddress );   
  75.      }

  76.      /* Wait until TXIS flag is set */
  77.      if ( I2C_WaitOnTXISFlagUntilTimeout ( hi2c ,   Timeout )   !=   HAL_OK )
  78.      {
  79.        if ( hi2c -> ErrorCode   ==   HAL_I2C_ERROR_AF )
  80.        {
  81.          return   HAL_ERROR ;
  82.        }
  83.        else
  84.        {
  85.          return   HAL_TIMEOUT ;
  86.        }
  87.      }

  88.      hi2c -> Instance -> TXDR   =   Size ;  

  89.      /* Wait until TC flag is set */
  90.      if ( I2C_WaitOnFlagUntilTimeout ( hi2c ,   I2C_FLAG_TC ,   RESET ,   Timeout )   !=   HAL_OK )      
  91.      {
  92.        return   HAL_TIMEOUT ;
  93.      }     

  94.      /* Send Slave Address */
  95.      /* Set NBYTES to write and reload if size > 255 and generate RESTART */
  96.      /* Size > 255, need to set RELOAD bit */
  97.      if ( Size   >   255 )
  98.      {
  99.        I2C_TransferConfig ( hi2c , DevAddress , 255 ,   I2C_RELOAD_MODE ,   I2C_GENERATE_START_READ );
  100.        Sizetmp   =   255 ;
  101.      }
  102.      else
  103.      {
  104.        I2C_TransferConfig ( hi2c , DevAddress , Size ,   I2C_AUTOEND_MODE ,   I2C_GENERATE_START_READ );
  105.        Sizetmp   =   Size ;
  106.      }

  107.      do
  108.      {   
  109.        /* Wait until RXNE flag is set */
  110.        if ( I2C_WaitOnFlagUntilTimeout ( hi2c ,   I2C_FLAG_RXNE ,   RESET ,   Timeout )   !=   HAL_OK )      
  111.        {
  112.          return   HAL_TIMEOUT ;
  113.        }

  114.        /* Read data from RXDR */
  115.        (* pData ++)   =   hi2c -> Instance -> RXDR ;

  116.        /* Decrement the Size counter */
  117.        Sizetmp --;
  118.        Size --;   

  119.        if (( Sizetmp   ==   0 )&&( Size != 0 ))
  120.        {
  121.          /* Wait until TCR flag is set */
  122.          if ( I2C_WaitOnFlagUntilTimeout ( hi2c ,   I2C_FLAG_TCR ,   RESET ,   Timeout )   !=   HAL_OK )      
  123.          {
  124.            return   HAL_TIMEOUT ;
  125.          }

  126.          if ( Size   >   255 )
  127.          {
  128.            I2C_TransferConfig ( hi2c , DevAddress , 255 ,   I2C_RELOAD_MODE ,   I2C_NO_STARTSTOP );
  129.            Sizetmp   =   255 ;
  130.          }
  131.          else
  132.          {
  133.            I2C_TransferConfig ( hi2c , DevAddress , Size ,   I2C_AUTOEND_MODE ,   I2C_NO_STARTSTOP );
  134.            Sizetmp   =   Size ;
  135.          }
  136.        }

  137.      } while ( Size   >   0 );

  138.      /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
  139.      /* Wait until STOPF flag is reset */  
  140.      if ( I2C_WaitOnSTOPFlagUntilTimeout ( hi2c ,   I2C_TIMEOUT_STOPF )   !=   HAL_OK )
  141.      {
  142.        if ( hi2c -> ErrorCode   ==   HAL_I2C_ERROR_AF )
  143.        {
  144.          return   HAL_ERROR ;
  145.        }
  146.        else
  147.        {
  148.          return   HAL_TIMEOUT ;
  149.        }
  150.      }

  151.      /* Clear STOP Flag */
  152.      __HAL_I2C_CLEAR_FLAG ( hi2c ,   I2C_FLAG_STOPF );

  153.      /* Clear Configuration Register 2 */
  154.      __HAL_I2C_RESET_CR2 ( hi2c );

  155.      hi2c -> State   =   HAL_I2C_STATE_READY ;

  156.      /* Process Unlocked */
  157.      __HAL_UNLOCK ( hi2c );

  158.      return   HAL_OK ;
  159.    }
  160.    else
  161.    {
  162.      return   HAL_BUSY ;
  163.    }
  164. }
复制代码


收藏 评论0 发布时间:2021-12-5 10:44

举报

0个回答

所属标签

相似技术帖

官网相关资源

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