📄 71x_i2c.c
字号:
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 + -