⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 71x_i2c.c

📁 STR7系列32位ARM控制器的固件库
💻 C
📖 第 1 页 / 共 2 页
字号:
  u16 result = 0;
  
  /* Get the FCLK frequency using the RCCU library */
  PCLK1 = RCCU_FrequencyValue (RCCU_PCLK1);
  
  /* Test on speed mode */
  /* Update the CCR and ECCR registers */

  /* If Standard mode is selected */
  if (Clock <= 100000)
  {
    result = ((PCLK1 / Clock) - 7) / 2;
    /* Clear FM/SM bit */
    I2Cx->CCR = result & 0x7f;
  }
 /* If Fast mode is selected */
  else if (Clock <= 400000)
  {
    result = ((PCLK1 / Clock) - 9) / 3;
    
    /* set FM/SM bit */
    I2Cx->CCR = result | 0x80;
  }
  I2Cx->ECCR = result >> 7;
}

/*******************************************************************************
* Function Name  : I2C_AddressConfig
* Description    : Defines the I2C bus address of the interface.
* Input          : - I2Cx: specifies the I2C to be configured, it can be:
*                     I2C0, I2C1
*                  - Address: an u16 parameter indicating the interface
*                    address.
*                  - Mode: specifies the addressing mode, it can be:
*                     I2C_Mode7, I2C_Mode10
* Output         : None.
* Return         : None.
*******************************************************************************/
void I2C_AddressConfig (I2C_TypeDef *I2Cx, u16 Address, I2C_Addressing Mode)
{
  /* Update OAR1 bit[7:1] by the lowest byte of address */
  I2Cx->OAR1 = (u8)Address;

  if (Mode == I2C_Mode10)
  {
    /* Update Add8 and add9 bits in OAR2 */
    I2Cx->OAR2 |= (Address & 0x0300) >> 7;
  }
}

/*******************************************************************************
* Function Name  : I2C_FCLKConfig
* Description    : Configures I2C frequency bits according to PCLK1 frequency.
*                  The selected I2C must be disabled.
* Input          : - I2Cx: specifies the I2C to be configured, it can be:
*                     I2C0, I2C1
* Output         : None.
* Return         : None.
*******************************************************************************/
void I2C_FCLKConfig (I2C_TypeDef *I2Cx)
{
  u32 PCLK1 = 0;
  
  /* Get the PCLK1 frequency using the RCCU library */
  PCLK1 = RCCU_FrequencyValue (RCCU_PCLK1);
  
  /* Test the value of the PCLK1 and affect FR0, FR1 and FR2 of the OAR2
   register*/
  if (PCLK1 > 5000000)
  {
    if (PCLK1 < 10000000)
    {
      I2Cx->OAR2 |= 0x00;
    }
    else if (PCLK1 < 16670000)
    {
      I2Cx->OAR2 |= 0x20;
    }
    else if (PCLK1 < 26670000)
    {
      I2Cx->OAR2 |= 0x40;
    }
    else if (PCLK1 < 40000000)
    {
      I2Cx->OAR2 |= 0x60;
    }
    else if (PCLK1 < 53330000)
    {
      I2Cx->OAR2 |= 0x80;
    }
    else if (PCLK1 < 66000000)
    {
      I2Cx->OAR2 |= 0xA0;
    }
    else if (PCLK1 < 80000000)
    {
      I2Cx->OAR2 |= 0xC0;
    }
    else if (PCLK1 < 100000000)
    {
      I2Cx->OAR2 |= 0xE0;
    }
  }
}

/*******************************************************************************
* Function Name  : I2C_AddressSend
* Description    : Sends the slave address with which the next communication
*                  will be performed.
* Input          : - I2Cx: specifies the I2C which will send the slave address, 
*                    it can be:
*                     I2C0, I2C1
*                  - Address: indicates the slave address which will be 
*                    transmitted
*                  - Mode: specifies the addressing mode, it can be:
*                     I2C_Mode10, I2C_Mode7
*                  - Direction: specifies the communication direction,
*                    it can be:
*                     I2C_RX, I2C_TX
* Output         : None.
* Return         : None.
*******************************************************************************/
void I2C_AddressSend (I2C_TypeDef *I2Cx, u16 Address, I2C_Addressing Mode,
                      I2C_Direction Direction)
{

  /* If the 10 bit addressing mode is selected */	
  if (Mode == I2C_Mode10)
  {
    /* Update the DR register by generated header */
    I2Cx->DR = ((Address >> 7) | 0xF0) & 0xFE;
    
    /* Wait till I2C_ADD10 flag is set */
    while ((I2Cx->SR1 & 0x40) == 0)
    {
      /* Wait*/
    }
    
    /* clear I2C_ADD10 flag */
    (void)I2Cx->SR2;
    
    I2Cx->DR = (u8)Address;
    
    /* Test on the direction to define the read/write bit */
    if (Direction == I2C_RX)
    {
      /* Wait till I2C_ENDAD flag is set */
      while ((I2Cx->SR2 & 0x20) == 0)
      {
        /* Wait*/
      }
      
      I2Cx->CR |= 0x20;
      
      /* Repeated START Generate */
      I2C_STARTGenerate (I2Cx, ENABLE);
      
      /* Test on SB flag status */
      while ((I2Cx->SR1 & 0x01) == 0)
      {
      }
      I2Cx->DR = ((Address >> 7) | 0xF1);
    }
  }
  /* If the 7 bit addressing mode is selected */
  else
  {
    if (Direction == I2C_RX)
    {
      Address |= 0x01;
    }
    else
    {
      Address &= ~0x01;
    }
    I2Cx->DR = (u8)Address;
  }
}

/*******************************************************************************
* Function Name  : I2C_ByteSend
* Description    : Transmits a single byte.
* Input          : - I2Cx: specifies the I2C which will send the single byte, 
*                    it can be:
*                     I2C0, I2C1
*                  - Data: the byte to be transmitted.
* Output         : None.
* Return         : None.
*******************************************************************************/
void I2C_ByteSend (I2C_TypeDef *I2Cx, u8 Data)
{
  /* Write in the DR register the byte to be sent */
  I2Cx->DR = Data;
}

/*******************************************************************************
* Function Name  : I2C_TransmissionStatus
* Description    : Reports the current transmission status.
* Input          : - I2Cx: specifies the I2C whose transmission status will be  
*                    tested,it can be:
*                     I2C0, I2C1
* Output         : None.
* Return         : The transmission status, it can be:
*                   I2C_TX_NO, I2C_TX_SB, I2C_TX_AF, I2C_TX_ARLO, I2C_TX_BERR,
*                   I2C_TX_ADD_OK, I2C_TX_DATA_OK, I2C_TX_ONGOING
*******************************************************************************/
I2C_Tx_Status I2C_TransmissionStatus (I2C_TypeDef *I2Cx)
{
  u8 SR1value = 0;
  u8 SR2value = 0;
  I2C_Tx_Status NewState = I2C_TX_NO;

  SR1value = I2Cx->SR1;
  SR2value = I2Cx->SR2;
  if ((I2Cx->SR1 & 0x10) == 0)
  {
    NewState = I2C_TX_NO;
  }
  /* If I2C_SB bit is set */
  else if (I2Cx->SR1 & 0x01)
  {
     NewState = I2C_TX_SB;
  }
  /* If I2C_ACK  and I2C_AF are both set */
  else if ((SR2value & 0x10) && (I2Cx->CR & 0x04))
  {
    NewState = I2C_TX_AF;
  }
  /* If I2C_ARLO is set in multimaster mode */
  else if (SR2value & 0x04)
  {
    NewState = I2C_TX_ARLO;
  }
  /* If I2C_BERR bit is set */
  else if (SR2value & 0x02)
  {
    NewState = I2C_TX_BERR;
  }
  /* If I2C_EVF and I2C_ENDAD are both set */
  else if ((SR1value & 0x80) && (I2Cx->SR2 & 0x20))
  {
    NewState = I2C_TX_ADD_OK;
  }
  /* If I2C_TRA and I2C_BTF are both set */  
  else if ((I2Cx->SR1 & 0x20) && (I2Cx->SR1 & 0x08))
  {
    NewState = I2C_TX_DATA_OK;
  }
  else
  {
    NewState = I2C_TX_ONGOING;
  }

  return NewState;
}

/*******************************************************************************
* Function Name  : I2C_ByteReceive
* Description    : Returns the received byte.
* Input          : - I2Cx: specifies the I2C peripheral to get a received data.  
*                    It can be:
*                     I2C0, I2C1
* Output         : None.
* Return         : The value of the received byte
*******************************************************************************/
u8 I2C_ByteReceive (I2C_TypeDef *I2Cx)
{
  
  while ((I2Cx->SR1 & 0x08) == 0)
  {
    /* Wait till I2C_BTF bit is set */
  }
  return I2Cx->DR;
}

/*******************************************************************************
* Function Name  : I2C_ReceptionStatus
* Description    : Reports the current reception status.
* Input          : - I2Cx: specifies the I2C whose reception status will be  
*                    tested,it can be:
*                     I2C0, I2C1
* Output         : None.
* Return         : The current receprtion status, it can be:
*                   I2C_RX_NO, I2C_RX_SB, I2C_RX_AF, I2C_RX_ARLO, I2C_RX_BERR,
*                   I2C_RX_ADD_OK, I2C_RX_DATA_OK, I2C_RX_ONGOING
*******************************************************************************/
I2C_Rx_Status I2C_ReceptionStatus (I2C_TypeDef *I2Cx)
{
  u8 SR1value = 0;
  u8 SR2value = 0;
  I2C_Rx_Status NewState = I2C_RX_NO;
  SR1value = I2Cx->SR1;
  SR2value = I2Cx->SR2;

  if ((I2Cx->SR1 & 0x10) == 0)
  {
    NewState = I2C_RX_NO;
  }
  /* If I2C_SB bit is set */
  else if (I2Cx->SR1 & 0x01)
  {
    NewState = I2C_RX_SB;
  }
  /* If I2C_ACK and I2C_AF are both set */
  else if ((SR2value & 0x10) && (I2Cx->CR & 0x04))
  {
    NewState = I2C_RX_AF;
  }
  /* If I2C_ARLO is set */
  else if (SR2value & 0x04)
  {
    NewState = I2C_RX_ARLO;
  }
  /* If I2C_BERR bit is set */
  else if (SR2value & 0x02)
  {
    NewState = I2C_RX_BERR;
  }
  /* If I2C_EVF is set and I2C_BTF is not set */
  else if ((SR1value & 0x80) && (I2Cx->SR1 & 0x08) == 0)
  {
    NewState = I2C_RX_ADD_OK;
  }
  /* If I2C_TRA is cleared and  I2C_BTF is set */
  else if (((I2Cx->SR1 & 0x20) == 0) && (I2Cx->SR1 & 0x08))
  {
    NewState = I2C_RX_DATA_OK;
  }
  else
  {
    NewState = I2C_RX_ONGOING;
  }
  return NewState;
}

/*******************************************************************************
* Function Name  : I2C_ErrorClear
* Description    : Clears any error flag.
* Input          : - I2Cx: specifies the I2C which error flags will be cleared.  
*                    It can be:
*                     I2C0, I2C1
* Output         : None.
* Return         : None.
*******************************************************************************/
void I2C_ErrorClear (I2C_TypeDef *I2Cx)
{
  /* Clear all error flags by reading the SR2 register */
  (void)I2Cx->SR2;
}

/*******************************************************************************
* Function Name  : I2C_GetStatus
* Description    : Reads the I2C status registers.
* Input          : - I2Cx: specifies the I2C to get its status registers.  
*                    It can be:
*                     I2C0, I2C1
* Output         : None.
* Return         : The I2C status registers value.
*******************************************************************************/
u32 I2C_GetStatus (I2C_TypeDef *I2Cx)
{
  u32 i2c_cr, i2c_sr1, i2c_sr2;

  i2c_cr  = I2Cx->CR;
  i2c_sr1 = I2Cx->SR1;
  i2c_sr2 = I2Cx->SR2;

  return (((i2c_cr) << 14) | (i2c_sr1 | (i2c_sr2 << 8)) & I2C_Event_Mask);
}

/******************* (C) COPYRIGHT 2007 STMicroelectronics *****END OF FILE****/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -