久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6146|回復(fù): 2
打印 上一主題 下一主題
收起左側(cè)

stm32f3的i2c使用小結(jié)

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:417196 發(fā)表于 2018-10-29 13:18 | 只看該作者 回帖獎勵 |倒序?yàn)g覽 |閱讀模式
stm32f3的i2c使用小結(jié)
這幾天拿到了stm32f3discovery,拿到手的第一件事就是測試了硬件i2c,使用stm32cube生成庫,測試對象為AD5934與ADG715。經(jīng)過兩天的調(diào)試,完美調(diào)通。中間也碰到了些問題。
1、一開始用的I2C1,一仿真就會出現(xiàn)死機(jī)的情況。
        由于I2C1與swd接口重合,所以調(diào)用HAL_I2C_Init()函數(shù)后就死機(jī),改成I2C2后問題解決。
2、無法訪問指定地址的設(shè)備
        庫函數(shù)中的入口地址并不是7bit地址,需要輸入8bit。我的設(shè)備地址為13,始終無法訪問設(shè)備,改為26后解決。
3、可以讀寫單個(gè)地址的數(shù)據(jù),但是不能多字節(jié)讀寫。
       (1)、對于多字節(jié)寫, 庫函數(shù)中的
        HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_tMemAddSize, uint8_t*pData, uint16_t Size, uint32_t Timeout)
       其中MemAddSize表示地址的位數(shù),0表示7bit地址,1表示10bit地址。我誤認(rèn)為這個(gè)寫的字節(jié)數(shù),所以導(dǎo)致在寫多字節(jié)的時(shí)候出錯(cuò)。
       (2)、對于多字節(jié)讀,由于AD5934的讀操作與庫函數(shù)的讀操作有些出入,所以導(dǎo)致一直讀錯(cuò)誤。在庫函數(shù)中寫完讀的內(nèi)存地址就開始讀,而AD5934中寫完block read后接著還要再寫一個(gè)number bytes read然后才開始讀。所以需要對庫函數(shù)進(jìn)行修改,新增一個(gè)函數(shù),以適合AD5934的block read.
        stm32f3的i2c有三種模式:Reload、AutoEnd、SoftEnd模式。
        i2c每發(fā)送完一個(gè)字節(jié),就會產(chǎn)生TXIS標(biāo)志,當(dāng)發(fā)送完最后一個(gè)字節(jié)時(shí):
        對于Reload模式,當(dāng)字節(jié)大于255字節(jié)時(shí),必須使用此模式,此模式下發(fā)送結(jié)束后,會產(chǎn)生tcr標(biāo)志。
        對于AutoEnd模式,發(fā)送后最后一個(gè)字節(jié)時(shí),會自動產(chǎn)生STOP。
        對于SoftEnd模式,發(fā)送完最后一個(gè)字節(jié)時(shí),會產(chǎn)生tc標(biāo)志,對于發(fā)送過程中需要Restart的需要使用此模式。
        對于AD5934的讀操作,可以事先工作在SoftEnd模式,發(fā)送完block read與number bytes read字節(jié)后,再轉(zhuǎn)入AutoEnd模式進(jìn)行Restart,讀取完指定的字節(jié)后自動產(chǎn)生STOP。操作流程如下:






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)
{
  uint32_t Sizetmp = 0;

  assert_param(IS_I2C_MEMADD_SIZE(MemAddSize));
  
  if(hi2c->State == HAL_I2C_STATE_READY)
  {   
    if((pData == NULL) || (Size == 0))
    {
      return  HAL_ERROR;                                 
    }

    if(__HAL_I2C_GET_FLAG(hi2c, I2C_FLAG_BUSY) == SET)
    {
      return HAL_BUSY;
    }

    /* Process Locked */
    __HAL_LOCK(hi2c);
   
    hi2c->State = HAL_I2C_STATE_MEM_BUSY_RX;
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
    /*
    //Send Slave Address and Memory Address
    if(I2C_RequestMemoryRead(hi2c, DevAddress, MemAddress, MemAddSize,Timeout) != HAL_OK)
    {
      if(hi2c->ErrorCode== HAL_I2C_ERROR_AF)
      {
        // Process Unlocked
        __HAL_UNLOCK(hi2c);
        return HAL_ERROR;
      }
      else
      {
        // Process Unlocked
        __HAL_UNLOCK(hi2c);
        return HAL_TIMEOUT;
      }
    }*/
   
    I2C_TransferConfig(hi2c,DevAddress,MemAddSize+1, I2C_SOFTEND_MODE, I2C_GENERATE_START_WRITE);
      
    /* Wait until TXIS flag is set */
    if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout) != HAL_OK)
    {
      if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
      {
        return HAL_ERROR;
      }
      else
      {
        return HAL_TIMEOUT;
      }
    }
   
    /* If Memory address size is 8Bit */
    if(MemAddSize == I2C_MEMADD_SIZE_8BIT)
    {
      /* Send Memory Address */
      hi2c->Instance->TXDR = __HAL_I2C_MEM_ADD_LSB(MemAddress);   
    }      
    /* If Mememory address size is 16Bit */
    else
    {
      /* Send MSB of Memory Address */
      hi2c->Instance->TXDR = __HAL_I2C_MEM_ADD_MSB(MemAddress);
      
      /* Wait until TXIS flag is set */
      if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout) != HAL_OK)
      {
        if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
        {
          return HAL_ERROR;
        }
        else
        {
          return HAL_TIMEOUT;
        }
      }
      
      /* Send LSB of Memory Address */
      hi2c->Instance->TXDR = __HAL_I2C_MEM_ADD_LSB(MemAddress);  
    }
   
    /* Wait until TXIS flag is set */
    if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout) != HAL_OK)
    {
      if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
      {
        return HAL_ERROR;
      }
      else
      {
        return HAL_TIMEOUT;
      }
    }
   
    hi2c->Instance->TXDR = Size;
   
    /* Wait until TC flag is set */
    if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TC, RESET, Timeout) != HAL_OK)     
    {
      return HAL_TIMEOUT;
    }   
   
    /* Send Slave Address */
    /* Set NBYTES to write and reload if size > 255 andgenerate RESTART */
    /* Size > 255, need to set RELOAD bit */
    if(Size > 255)
    {
      I2C_TransferConfig(hi2c,DevAddress,255, I2C_RELOAD_MODE, I2C_GENERATE_START_READ);
      Sizetmp = 255;
    }
    else
    {
      I2C_TransferConfig(hi2c,DevAddress,Size, I2C_AUTOEND_MODE, I2C_GENERATE_START_READ);
      Sizetmp = Size;
    }
   
    do
    {  
      /* Wait until RXNE flag is set */
      if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_RXNE, RESET, Timeout) != HAL_OK)     
      {
        return HAL_TIMEOUT;
      }
         
      /* Read data from RXDR */
      (*pData++) = hi2c->Instance->RXDR;

      /* Decrement the Size counter */
      Sizetmp--;
      Size--;   

      if((Sizetmp == 0)&&(Size!=0))
      {
        /* Wait until TCR flag is set */
        if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout) != HAL_OK)     
        {
          return HAL_TIMEOUT;
        }
        
        if(Size > 255)
        {
          I2C_TransferConfig(hi2c,DevAddress,255, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
          Sizetmp = 255;
        }
        else
        {
          I2C_TransferConfig(hi2c,DevAddress,Size, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
          Sizetmp = Size;
        }
      }

    }while(Size > 0);

    /* No need to Check TC flag, with AUTOEND mode the stop isautomatically generated */
    /* Wait until STOPF flag is reset */
    if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, I2C_TIMEOUT_STOPF) != HAL_OK)
    {
      if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
      {
        return HAL_ERROR;
      }
      else
      {
        return HAL_TIMEOUT;
      }
    }

    /* Clear STOP Flag */
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
   
    /* Clear Configuration Register 2 */
    __HAL_I2C_RESET_CR2(hi2c);
   
    hi2c->State = HAL_I2C_STATE_READY;
   
    /* Process Unlocked */
    __HAL_UNLOCK(hi2c);
   
    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}


http://blog.csdn.net/xiaoxiongli/article/details/49637785

http://blog.csdn.net/xiaoxiongli/


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:64451 發(fā)表于 2019-10-14 17:24 | 只看該作者
真心感謝樓主幫了我大忙,謝謝!
回復(fù)

使用道具 舉報(bào)

板凳
ID:64451 發(fā)表于 2019-10-14 17:25 | 只看該作者
樓主,我今天也用pca9535,發(fā)現(xiàn)上電后Int引腳總是為低電平
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 日韩欧美国产一区二区三区 | 亚洲精品视频在线 | 国产精品一区二 | 亚洲精品九九 | 在线国产视频 | 瑟瑟视频在线看 | 久久中文字幕在线 | 91精品在线播放 | 国产精品激情在线 | 亚洲一区二区视频 | 黄色毛片在线看 | 中文字幕1区 | 欧美一级艳情片免费观看 | 久久九九99| 一区二区三区国产精品 | 亚洲精品99 | 色婷婷综合久久久中字幕精品久久 | 成人在线影视 | 亚洲精品电影在线观看 | 亚洲一区免费 | 91麻豆蜜桃一区二区三区 | 精品国产欧美一区二区三区成人 | 国产欧美精品一区二区 | 精品国产1区2区3区 在线国产视频 | 日韩午夜影院 | 日韩三级电影一区二区 | 欧美天堂一区 | 91p在线观看 | 欧美日韩不卡合集视频 | 亚洲欧洲综合av | 91精品国产92 | 亚洲三级在线观看 | 精品久| 97在线观看 | 一级黄色片日本 | 国产成人av在线播放 | 日本久久网 | 久久69精品久久久久久久电影好 | 亚洲国产一区在线 | 一区二区小视频 | 九九99精品|