IIC状态码
IIC 初始化
void iicInit(uint32_t speed)
{stc_gpio_cfg_t stcGpioCfg;DDL_ZERO_STRUCT(stcGpioCfg);Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //开启GPIO时钟门控stcGpioCfg.enDir = GpioDirOut; ///< 端口方向配置->输出stcGpioCfg.enOD = GpioOdEnable; ///< 开漏输出stcGpioCfg.enPu = GpioPuEnable; ///< 端口上拉配置->使能stcGpioCfg.enPd = GpioPdDisable; ///< 端口下拉配置->禁止Gpio_Init(GpioPortB, GpioPin8, &stcGpioCfg); ///< 端口初始化Gpio_Init(GpioPortB, GpioPin9, &stcGpioCfg);Gpio_SetAfMode(GpioPortB, GpioPin8, GpioAf1); ///< 配置PB08为SCLGpio_SetAfMode(GpioPortB, GpioPin9, GpioAf1); ///< 配置PB09为SDAstc_i2c_cfg_t stcI2cCfg;DDL_ZERO_STRUCT(stcI2cCfg); ///< 初始化结构体变量的值为0Sysctrl_SetPeripheralGate(SysctrlPeripheralI2c0, TRUE); ///< 开启I2C0时钟门控stcI2cCfg.u32Pclk = Sysctrl_GetPClkFreq(); ///< 获取PCLK时钟stcI2cCfg.u32Baud = speed; ///< 1MHzstcI2cCfg.enMode = I2cMasterMode; ///< 主机模式stcI2cCfg.u8SlaveAddr = SLAVE_ADDR; ///< 从地址,主模式无效stcI2cCfg.bGc = FALSE; ///< 广播地址应答使能关闭I2C_Init(M0P_I2C0, &stcI2cCfg); ///< 模块初始化
}
IIC读写
/********************************************************************************** 主机接收函数** @param: I2CX** @param: I2C_DEVADDR 从机设备地址** @param:register_addr 读取寄存器addr** @param:pu8Data 读取addr的 data值** @param: u32Len 读取长度********************************************************************************/
en_result_t I2C_MasterReadData(M0P_I2C_TypeDef *I2CX, uint8_t I2C_DEVADDR, uint8_t register_addr, uint8_t *pu8Data, uint32_t u32Len)
{en_result_t enRet = Error;uint8_t u8i = 0, u8State;I2C_SetFunc(I2CX, I2cStart_En);while (1){while (0 == I2C_GetIrq(I2CX)){;}u8State = I2C_GetState(I2CX);switch (u8State){case 0x08: //已发送起始条件,将发送SLA+RI2C_ClearFunc(I2CX, I2cStart_En);I2C_WriteByte(I2CX, (I2C_DEVADDR)); //发送SLA+Wbreak;case 0x18: //已发送SLA+W,并接收到ACKI2C_WriteByte(I2CX, register_addr); //发送内存地址break;case 0x28: //已发送数据,接收到ACKI2C_SetFunc(I2CX, I2cStart_En);break;case 0x10: //已发送重复起始条件I2C_ClearFunc(I2CX, I2cStart_En);I2C_WriteByte(I2CX, (I2C_DEVADDR) | 0x01); //读命令发送break;case 0x40: //已发送SLA+R,并接收到ACKif (u32Len > 1){I2C_SetFunc(I2CX, I2cAck_En);}break;case 0x50: //已接收数据字节,并已返回ACK信号pu8Data[u8i++] = I2C_ReadByte(I2CX);if (u8i == u32Len - 1){I2C_ClearFunc(I2CX, I2cAck_En); //读数据时,倒数第二个字节ACK关闭}break;case 0x58: //已接收到最后一个数据,NACK已返回pu8Data[u8i++] = I2C_ReadByte(I2CX);I2C_SetFunc(I2CX, I2cStop_En); //发送停止条件break;case 0x38: //在发送地址或数据时,仲裁丢失I2C_SetFunc(I2CX, I2cStart_En); //当总线空闲时发起起始条件break;case 0x48: //发送SLA+R后,收到一个NACKI2C_SetFunc(I2CX, I2cStop_En);I2C_SetFunc(I2CX, I2cStart_En);break;default: //其他错误状态,重新发送起始条件I2C_SetFunc(I2CX, I2cStart_En); //其他错误状态,重新发送起始条件break;}I2C_ClearIrq(I2CX); //清除中断状态标志位if (u8i == u32Len) //数据全部读取完成,跳出while循环{break;}}enRet = Ok;return enRet;
}/********************************************************************************** 主机发送函数** @param: I2CX** @param: I2C_DEVADDR 从机设备地址** @param:register_addr 写入寄存器addr** @param:pu8Data 写入addr的 data值** @param: u32Len 写入长度********************************************************************************/
en_result_t I2C_MasterWriteData(M0P_I2C_TypeDef *I2CX, uint8_t I2C_DEVADDR, uint8_t register_addr, uint8_t *pu8Data, uint32_t u32Len)
{en_result_t enRet = Error;uint8_t u8i = 0, u8State;I2C_SetFunc(I2CX, I2cStart_En);while (1){while (0 == I2C_GetIrq(I2CX)){;}u8State = I2C_GetState(I2CX);switch (u8State){case 0x08: ///已发送起始条件I2C_ClearFunc(I2CX, I2cStart_En);I2C_WriteByte(I2CX, (I2C_DEVADDR)); ///从设备地址发送break;case 0x18: ///已发送SLA+W,并接收到ACKI2C_WriteByte(I2CX, register_addr);break;case 0x28: ///上一次发送数据后接收到ACKI2C_WriteByte(I2CX, pu8Data[u8i++]);break;case 0x20: ///上一次发送SLA+W后,收到NACKcase 0x38: ///上一次在SLA+读或写时丢失仲裁I2C_SetFunc(I2CX, I2cStart_En); ///当I2C总线空闲时发送起始条件break;case 0x30: ///已发送I2Cx_DATA中的数据,收到NACK,将传输一个STOP条件I2C_SetFunc(I2CX, I2cStop_En); ///发送停止条件break;default:break;}if (u8i > u32Len){I2C_SetFunc(I2CX, I2cStop_En); ///此顺序不能调换,出停止条件I2C_ClearIrq(I2CX);break;}I2C_ClearIrq(I2CX); ///清除中断状态标志位}enRet = Ok;return enRet;
}