- /* I2C configuration */
- I2C_InitStructure.I2C_Mode = I2C_Mode_I2CDevice;
- I2C_InitStructure.I2C_FmDutyCycle = I2C_FmDutyCycle_2_1;
- I2C_InitStructure.I2C_OwnAddr1 = I2C_SLAVE_ADDRESS7;
- I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
- I2C_InitStructure.I2C_AddrMode = I2C_AddrMode_7bit;
- I2C_InitStructure.I2C_BitRate = I2C_SPEED;
- /* I2C Peripheral Enable */
- I2C_Cmd(I2C_PORT, ENABLE);
- /* Apply I2C configuration after enabling it */
- I2C_Init(I2C_PORT, &I2C_InitStructure);
对着例程照搬就行。
(三)器件
IIC器件采用MPU9250,一个九轴传感器,八位器件地址0xD0,WHO AM I位 0x75,数据为0x71.
(四)写IIC
写的方法很简单,例程照搬即可:
- I2C_StatusType I2C_Master_Transmit(I2C_Type* I2Cx, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
- {
- /* Wait until BUSY flag is reset */
- if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BUSYF, SET, I2C_EVT_CHECK_NONE, Timeout) != 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, DevAddress, 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);
- while(Size > 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_4;
- }
- /* Write data to DR */
- I2C_SendData(I2Cx, (*pData++));
- Size--;
- }
- /* 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_5;
- }
- /* Send STOP Condition */
- I2C_GenerateSTOP(I2Cx, ENABLE);
- return I2C_OK;
- }
写入效果:
(五)读效果
雅特力的IIC在读IIC方面有一个比较特殊的处理,会预先读两位,可以通过配置CTL1寄存器第11位阻止预读取。
这里先不处理预读取的问题。
- I2C_StatusType I2C_Master_Rec2(I2C_Type* I2Cx, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
- {
- /* Wait until BUSY flag is reset */
- if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_BUSYF, SET, I2C_EVT_CHECK_NONE, Timeout) != 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, DevAddress, 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_3;
- }
- /* Clear ADDR flag */
- I2C_ClearADDRFlag(I2Cx);
- while(Size > 0)
- {
- /* Wait until TDE flag is set */
- if(I2C_WaitOnFlagUntilTimeout(I2Cx, I2C_FLAG_RDNE, RESET, I2C_EVT_CHECK_ACKFAIL, Timeout) != I2C_OK)
- {
- /* Send STOP Condition */
- I2C_GenerateSTOP(I2Cx, ENABLE);
- return I2C_ERROR_STEP_4;
- }
- /* Write data to DR */
- (*pData++) = I2C_ReceiveData(I2Cx);
- Size--;
- }
- 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_5;
- }
- /* Send STOP Condition */
- I2C_GenerateSTOP(I2Cx, ENABLE);
- /* Disable Address Acknowledge */
- I2C_AcknowledgeConfig(I2Cx, DISABLE);
- return I2C_OK;
- }
读取一个位的效果:
I2C_Master_Rec2(I2C_PORT, I2C_SLAVE_ADDRESS7, tx_buf, 1, 1000);
但是读取多个位的时候,则会出现把总线钳住不释放的现象:
I2C_Master_Rec2(I2C_PORT, I2C_SLAVE_ADDRESS7, tx_buf, 2, 1000);
并且总线被钳住之后,硬件复位是无法释放总线的,也就是第一次出错后,在不断电的情况下,即便复位,下一次程序重新运行,重新初始化,依旧是总线忙的状态,无法写也无法读。
main.zip
(2.24 KB, 下载次数: 2)