#申请原创# 本次测试的是I2C外设,测试使用了ROHM的传感器,光照度传感器RPR-0521RS,气压传感器BM1383AGLV,地磁传感器BM1422AGMV。这几个传感器都是I2C接口,可以一起接I2C测试。
如图:使用arduino接口插在开发板。I2C使用的是I2C1,对应管脚为PB8:SCL,PB9:SDA。
PBB8,PB9对应的I2C功能引脚是重映射功能,需要重映射使能。
下面是重映射寄存器,为1就使能。未使能时I2C对应的PB6,PB7。
程序参考官方的BSP中的EEPROM例程的I2C程序,需要注意的是要使能IO复用重映射的时钟和I2C1的IO重映射使能。再就是I2C设备地址。
I2C初始化:
GPIO_InitType GPIO_InitStructure;
I2C_InitType I2C_InitStructure;
/* GPIO Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOB|RCC_APB2PERIPH_AFIO , ENABLE);
/* I2C Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1PERIPH_I2C1, ENABLE);
/* GPIO configuration */
/* Configure I2C pins: SCL */
GPIO_InitStructure.GPIO_Pins = I2C_SCL_PIN;
GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(I2C_SCL_Port, &GPIO_InitStructure);
/* Configure I2C pins: SDA */
GPIO_InitStructure.GPIO_Pins = I2C_SDA_PIN;
GPIO_Init(I2C_SDA_Port, &GPIO_InitStructure);
//重映射到PB8,PB9
GPIO_PinsRemapConfig(GPIO_Remap_I2C1,ENABLE);
/* I2C configuration */
I2C_InitStructure.I2C_Mode = I2C_Mode_I2CDevice;
I2C_InitStructure.I2C_FmDutyCycle = I2C_FmDutyCycle_2_1;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AddrMode = I2C_AddrMode_7bit;
I2C_InitStructure.I2C_BitRate = 100000; //100KHz
/* I2C Peripheral Enable */
I2C_Cmd(I2C1, ENABLE);
/* Apply I2C configuration after enabling it */
I2C_Init(I2C1, &I2C_InitStructure);
下面是实现读写函数,通过修改例程实现的。
I2C_StatusType I2C_Mem_Read(I2C_Type* I2Cx, uint16_t DevAddr, uint16_t DataAddr,
uint8_t *pBuffer, uint16_t NumByte, uint32_t Timeout)
{
/* Wait until BUSY flag is reset */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BUSYF, SET, I2C_EVT_CHECK_NONE, I2C_TIMEOUT_BUSY_FLAG) != I2C_OK)
{
return I2C_ERROR_STEP_1;
}
/* Disable Pos */
I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Current);
/* Enable Acknowledge */
I2C_AcknowledgeConfig(I2Cx, ENABLE);
/* Send START condition */
I2C_GenerateSTART(I2Cx, ENABLE);
/* Wait until SB flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_STARTF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_2;
}
/* Send slave address for write */
I2C_Send7bitAddress(I2Cx, (uint8_t)(DevAddr&0xff), I2C_Direction_Transmit);
/* Wait until ADDR flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_ADDRF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_3;
}
/* Clear ADDR flag */
I2C_ClearADDRFlag(I2Cx);
/* Wait until TDE flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_TDE, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_4;
}
/* Send Memory Address */
I2C_SendData(I2Cx, (uint8_t)(DataAddr&0xff));
/* Wait until TDE flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_TDE, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_5;
}
/* Send START condition */
I2C_GenerateSTART(I2Cx, ENABLE);
/* Wait until SB flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_STARTF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_6;
}
/* Send slave address for read */
I2C_Send7bitAddress(I2Cx, (uint8_t)(DevAddr&0xff), I2C_Direction_Receive);
/* Wait until ADDR flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_ADDRF, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_7;
}
if(NumByte == 1)
{
/* Disable Acknowledge */
I2C_AcknowledgeConfig(I2Cx, DISABLE);
/* Clear ADDR flag */
I2C_ClearADDRFlag(I2Cx);
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
}
else if(NumByte == 2)
{
/* Enable Pos */
I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Next);
/* Clear ADDR flag */
I2C_ClearADDRFlag(I2Cx);
/* Disable Acknowledge */
I2C_AcknowledgeConfig(I2Cx, DISABLE);
}
else
{
/* Enable Acknowledge */
I2C_AcknowledgeConfig(I2Cx, ENABLE);
/* Clear ADDR flag */
I2C_ClearADDRFlag(I2Cx);
}
while(NumByte > 0)
{
if(NumByte <= 3)
{
/* One byte */
if(NumByte == 1)
{
/* Wait until RXNE flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_RDNE, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_8;
}
/* Read data from DR */
(*pBuffer++) = I2C_ReceiveData(I2Cx);
NumByte--;
}
/* Two bytes */
else if(NumByte == 2)
{
/* Wait until BTF flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BTFF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_9;
}
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
/* Read data from DR */
(*pBuffer++) = I2C_ReceiveData(I2Cx);
NumByte--;
/* Read data from DR */
(*pBuffer++) = I2C_ReceiveData(I2Cx);
NumByte--;
}
/* 3 Last bytes */
else
{
/* Wait until BTF flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BTFF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_10;
}
/* Disable Acknowledge */
I2C_AcknowledgeConfig(I2Cx, DISABLE);
/* Read data from DR */
(*pBuffer++) = I2C_ReceiveData(I2Cx);
NumByte--;
/* Wait until BTF flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BTFF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_11;
}
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
/* Read data from DR */
(*pBuffer++) = I2C_ReceiveData(I2Cx);
NumByte--;
/* Read data from DR */
(*pBuffer++) = I2C_ReceiveData(I2Cx);
NumByte--;
}
}
else
{
/* Wait until RXNE flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_RDNE, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_12;
}
/* Read data from DR */
(*pBuffer++) = I2C_ReceiveData(I2Cx);
NumByte--;
}
}
return I2C_OK;
}
I2C_StatusType I2C_Mem_Write(I2C_Type* I2Cx, uint16_t DevAddr, uint16_t DataAddr,
uint8_t *pBuffer, uint16_t NumByte, uint32_t Timeout)
{
/* Wait until BUSY flag is reset */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BUSYF, SET, I2C_EVT_CHECK_NONE, I2C_TIMEOUT_BUSY_FLAG) != I2C_OK)
{
return I2C_ERROR_STEP_1;
}
/* Disable Pos */
I2C_NACKPositionConfig(I2Cx, I2C_NACKPosition_Current);
/* Send START condition */
I2C_GenerateSTART(I2Cx, ENABLE);
/* Wait until SB flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_STARTF, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_2;
}
/* Send slave address for write */
I2C_Send7bitAddress(I2Cx, (uint8_t)(DevAddr&0xff), I2C_Direction_Transmit);
/* Wait until ADDR flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_ADDRF, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_3;
}
/* Clear ADDR flag */
I2C_ClearADDRFlag(I2Cx);
/* Wait until TDE flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_TDE, RESET, I2C_EVT_CHECK_NONE, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_4;
}
/* Send Memory Address */
I2C_SendData(I2Cx, (uint8_t)(DataAddr&0xff));
/* Wait until TDE flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_TDE, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_5;
}
while(NumByte > 0)
{
/* Wait until TDE flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_TDE, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_6;
}
/* Write data to DR */
I2C_SendData(I2Cx, (*pBuffer++));
NumByte--;
}
/* Wait until BTF flag is set */
if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BTFF, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
{
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_ERROR_STEP_7;
}
/* Send STOP Condition */
I2C_GenerateSTOP(I2Cx, ENABLE);
return I2C_OK;
}
通过逻辑分析仪捕的I2C协议时序。
通过串口输出,读取的3个传感器的数值。
代码
|
共2人点赞
|