网上这方面内容较少,自己写了一个,供需要者参考。
1. 初始化:
void InitFMPI2C(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
FMPI2C_InitTypeDef I2C_InitStructure;
printf("Init FMP I2C\r\n");
RCC_AHB1PeriphClockCmd(PERI_FMPI2C1_SCL_GPIO_CLK | PERI_FMPI2C1_SDA_GPIO_CLK, ENABLE);
RCC_APB1PeriphClockCmd(PERI_FMPI2C1_CLK, ENABLE);
RCC_APB1PeriphResetCmd(PERI_FMPI2C1_CLK, ENABLE);
RCC_APB1PeriphResetCmd(PERI_FMPI2C1_CLK, DISABLE);
/* Connect PXx to I2C_SCL*/
GPIO_PinAFConfig(PERI_FMPI2C1_SCL_GPIO_PORT, PERI_FMPI2C1_SCL_SOURCE, PERI_FMPI2C1_SCL_AF);
/* Connect PXx to I2C_SDA*/
GPIO_PinAFConfig(PERI_FMPI2C1_SDA_GPIO_PORT, PERI_FMPI2C1_SDA_SOURCE, PERI_FMPI2C1_SDA_AF);
/* GPIO configuration */
/* Configure sEE_I2C pins: SCL */
GPIO_InitStructure.GPIO_Pin = PERI_FMPI2C1_SCL_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(PERI_FMPI2C1_SCL_GPIO_PORT, &GPIO_InitStructure);
/* Configure sEE_I2C pins: SDA */
GPIO_InitStructure.GPIO_Pin = PERI_FMPI2C1_SDA_PIN;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_Init(PERI_FMPI2C1_SDA_GPIO_PORT, &GPIO_InitStructure);
I2C_InitStructure.FMPI2C_Mode = FMPI2C_Mode_FMPI2C;
I2C_InitStructure.FMPI2C_Timing = 0x00308FF9; //0x00303D5B; // 此数由Stm32CubeMX工具产生。
I2C_InitStructure.FMPI2C_AnalogFilter = FMPI2C_AnalogFilter_Enable;
I2C_InitStructure.FMPI2C_AcknowledgedAddress = FMPI2C_AcknowledgedAddress_7bit;
I2C_InitStructure.FMPI2C_Ack = FMPI2C_Ack_Enable;
FMPI2C_Init(PERI_FMPI2C1, &I2C_InitStructure);
FMPI2C_Cmd(PERI_FMPI2C1, ENABLE);
}
2. Read,Write 实现:
static BYTE FMPI2C_CheckBusy(void)
{
DWORD TimeOut = I2C_LONG_TIMEOUT;
BYTE return_flag = I2C_OK;
while (FMPI2C_GetFlagStatus(FMPI2C1, FMPI2C_FLAG_BUSY))
{
if((TimeOut--) == 0)
{
return_flag = I2C_NOT_FREE;
break;
}
}
return return_flag;
}
static BYTE FMPI2C_Start(BYTE dAddr, BYTE nSize, BYTE mode)
{
FMPI2C_MasterRequestConfig(FMPI2C1, mode);
FMPI2C_SlaveAddressConfig(FMPI2C1, dAddr);
FMPI2C_NumberOfBytesConfig(FMPI2C1, nSize);
FMPI2C_AutoEndCmd(FMPI2C1, ENABLE);
FMPI2C_GenerateSTART(FMPI2C1, ENABLE);
return I2C_OK;
}
static BYTE FMPI2C_GetByte()
{
BYTE read;
I2CTimeout = I2C_LONG_TIMEOUT;
while(FMPI2C_GetFlagStatus(FMPI2C1, FMPI2C_FLAG_RXNE) == RESET)
{if((I2CTimeout--) == 0) return I2C_TIME_OUT;}
read = FMPI2C_ReceiveData(FMPI2C1);
return read;
}
static void FMPI2C_Clear(void)
{
FMPI2C1->ICR = 0x0000FFFF;
}
static BYTE FMPI2C_Wait_Event(DWORD event)
{
DWORD TimeOut = I2C_LONG_TIMEOUT;
BYTE return_flag = SET;
while (!FMPI2C_GetFlagStatus(FMPI2C1, event))
{
if((TimeOut--) == 0)
{
return_flag = RESET;
break;
}
}
return return_flag;
}
//--------------------------------------------------------------------------------------------------------------------------
BYTE FMPI2C_Write(BYTE dAddr, BYTE rAddr, PBYTE pBuff, WORD bytes)
{
uint32_t i = 0, j = 0;
if(FMPI2C_CheckBusy())
{
printf("FMP I2C Busy!\r\n");
return I2C_NOT_FREE;
}
FMPI2C_Clear();
FMPI2C_Start(dAddr, bytes+1, I2C_Direction_Transmitter);
if(FMPI2C_Wait_Event(FMPI2C_FLAG_TXIS))
{
FMPI2C_SendData(FMPI2C1, rAddr);
j = 0;
}
else {
printf("FMP I2C Write Error Start[%08X]\r\n", FMPI2C1->ISR);
return I2C_NOT_START;
}
for (i=0; i<bytes; i++)
{
if(FMPI2C_Wait_Event(FMPI2C_FLAG_TXIS))
{
FMPI2C_SendData(FMPI2C1, pBuff[i]);
j++;
}
else
{
printf("FMP I2C Write Data Error[%d][%08X]\r\n", j, FMPI2C1->ISR);
}
}
if(!FMPI2C_Wait_Event(FMPI2C_FLAG_STOPF))
{
printf("FMP I2C Write STOP error[%08X]\r\n", FMPI2C1->ISR);
}
FMPI2C_Clear();
return I2C_OK;
}
//--------------------------------------------------------------------------------------------------------------------------
BYTE FMPI2C_Read(BYTE dAddr, BYTE rAddr, PBYTE pBuff, WORD bytes)
{
uint32_t i;
if(FMPI2C_CheckBusy())
{
printf("FMP I2C Busy!\r\n");
return I2C_NOT_FREE;
}
FMPI2C_Clear();
FMPI2C_Start(dAddr, 1, I2C_Direction_Transmitter);
if(FMPI2C_Wait_Event(FMPI2C_FLAG_TXIS))
{
FMPI2C_SendData(FMPI2C1, rAddr);
}
else {
printf("FMP I2C Error Start[%08X]\r\n", FMPI2C1->ISR);
return I2C_NOT_START;
}
FMPI2C_Wait_Event(FMPI2C_FLAG_STOPF);
//printf("FMP I2C Write STOP [%08X]\r\n", FMPI2C1->ISR);
FMPI2C_ClearFlag(FMPI2C1, FMPI2C_FLAG_STOPF);
//return I2C_NO_DATA;
if(FMPI2C_CheckBusy())
{
printf("FMP I2C Busy!\r\n");
return I2C_NOT_FREE;
}
FMPI2C_Clear();
FMPI2C_Start(dAddr, bytes, I2C_Direction_Receiver);
for (i=0; i<bytes; i++){
pBuff[i] = FMPI2C_GetByte();
}
FMPI2C_Wait_Event(FMPI2C_FLAG_STOPF);
FMPI2C_Clear();
return I2C_OK;
}