| 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。操作流程如下:
 
 
 
 
 
 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;
 
 /* Check the parameters  http://tiyubisai.com/video_news/news_135585.html */
 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 and generate 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 is automatically 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;
 }
 }
 |