• HC32 IIC/I2C读写


    IIC状态码

    IIC 初始化

    1. void iicInit(uint32_t speed)
    2. {
    3. stc_gpio_cfg_t stcGpioCfg;
    4. DDL_ZERO_STRUCT(stcGpioCfg);
    5. Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); //开启GPIO时钟门控
    6. stcGpioCfg.enDir = GpioDirOut; ///< 端口方向配置->输出
    7. stcGpioCfg.enOD = GpioOdEnable; ///< 开漏输出
    8. stcGpioCfg.enPu = GpioPuEnable; ///< 端口上拉配置->使能
    9. stcGpioCfg.enPd = GpioPdDisable; ///< 端口下拉配置->禁止
    10. Gpio_Init(GpioPortB, GpioPin8, &stcGpioCfg); ///< 端口初始化
    11. Gpio_Init(GpioPortB, GpioPin9, &stcGpioCfg);
    12. Gpio_SetAfMode(GpioPortB, GpioPin8, GpioAf1); ///< 配置PB08为SCL
    13. Gpio_SetAfMode(GpioPortB, GpioPin9, GpioAf1); ///< 配置PB09为SDA
    14. stc_i2c_cfg_t stcI2cCfg;
    15. DDL_ZERO_STRUCT(stcI2cCfg); ///< 初始化结构体变量的值为0
    16. Sysctrl_SetPeripheralGate(SysctrlPeripheralI2c0, TRUE); ///< 开启I2C0时钟门控
    17. stcI2cCfg.u32Pclk = Sysctrl_GetPClkFreq(); ///< 获取PCLK时钟
    18. stcI2cCfg.u32Baud = speed; ///< 1MHz
    19. stcI2cCfg.enMode = I2cMasterMode; ///< 主机模式
    20. stcI2cCfg.u8SlaveAddr = SLAVE_ADDR; ///< 从地址,主模式无效
    21. stcI2cCfg.bGc = FALSE; ///< 广播地址应答使能关闭
    22. I2C_Init(M0P_I2C0, &stcI2cCfg); ///< 模块初始化
    23. }

    IIC读写

    1. /**
    2. ******************************************************************************
    3. ** 主机接收函数
    4. ** @param: I2CX
    5. ** @param: I2C_DEVADDR 从机设备地址
    6. ** @param:register_addr 读取寄存器addr
    7. ** @param:pu8Data 读取addr的 data值
    8. ** @param: u32Len 读取长度
    9. **
    10. ******************************************************************************/
    11. en_result_t I2C_MasterReadData(M0P_I2C_TypeDef *I2CX, uint8_t I2C_DEVADDR, uint8_t register_addr, uint8_t *pu8Data, uint32_t u32Len)
    12. {
    13. en_result_t enRet = Error;
    14. uint8_t u8i = 0, u8State;
    15. I2C_SetFunc(I2CX, I2cStart_En);
    16. while (1)
    17. {
    18. while (0 == I2C_GetIrq(I2CX))
    19. {;}
    20. u8State = I2C_GetState(I2CX);
    21. switch (u8State)
    22. {
    23. case 0x08: //已发送起始条件,将发送SLA+R
    24. I2C_ClearFunc(I2CX, I2cStart_En);
    25. I2C_WriteByte(I2CX, (I2C_DEVADDR)); //发送SLA+W
    26. break;
    27. case 0x18: //已发送SLA+W,并接收到ACK
    28. I2C_WriteByte(I2CX, register_addr); //发送内存地址
    29. break;
    30. case 0x28: //已发送数据,接收到ACK
    31. I2C_SetFunc(I2CX, I2cStart_En);
    32. break;
    33. case 0x10: //已发送重复起始条件
    34. I2C_ClearFunc(I2CX, I2cStart_En);
    35. I2C_WriteByte(I2CX, (I2C_DEVADDR) | 0x01); //读命令发送
    36. break;
    37. case 0x40: //已发送SLA+R,并接收到ACK
    38. if (u32Len > 1)
    39. {
    40. I2C_SetFunc(I2CX, I2cAck_En);
    41. }
    42. break;
    43. case 0x50: //已接收数据字节,并已返回ACK信号
    44. pu8Data[u8i++] = I2C_ReadByte(I2CX);
    45. if (u8i == u32Len - 1)
    46. {
    47. I2C_ClearFunc(I2CX, I2cAck_En); //读数据时,倒数第二个字节ACK关闭
    48. }
    49. break;
    50. case 0x58: //已接收到最后一个数据,NACK已返回
    51. pu8Data[u8i++] = I2C_ReadByte(I2CX);
    52. I2C_SetFunc(I2CX, I2cStop_En); //发送停止条件
    53. break;
    54. case 0x38: //在发送地址或数据时,仲裁丢失
    55. I2C_SetFunc(I2CX, I2cStart_En); //当总线空闲时发起起始条件
    56. break;
    57. case 0x48: //发送SLA+R后,收到一个NACK
    58. I2C_SetFunc(I2CX, I2cStop_En);
    59. I2C_SetFunc(I2CX, I2cStart_En);
    60. break;
    61. default: //其他错误状态,重新发送起始条件
    62. I2C_SetFunc(I2CX, I2cStart_En); //其他错误状态,重新发送起始条件
    63. break;
    64. }
    65. I2C_ClearIrq(I2CX); //清除中断状态标志位
    66. if (u8i == u32Len) //数据全部读取完成,跳出while循环
    67. {
    68. break;
    69. }
    70. }
    71. enRet = Ok;
    72. return enRet;
    73. }
    74. /**
    75. ******************************************************************************
    76. ** 主机发送函数
    77. ** @param: I2CX
    78. ** @param: I2C_DEVADDR 从机设备地址
    79. ** @param:register_addr 写入寄存器addr
    80. ** @param:pu8Data 写入addr的 data值
    81. ** @param: u32Len 写入长度
    82. **
    83. ******************************************************************************/
    84. en_result_t I2C_MasterWriteData(M0P_I2C_TypeDef *I2CX, uint8_t I2C_DEVADDR, uint8_t register_addr, uint8_t *pu8Data, uint32_t u32Len)
    85. {
    86. en_result_t enRet = Error;
    87. uint8_t u8i = 0, u8State;
    88. I2C_SetFunc(I2CX, I2cStart_En);
    89. while (1)
    90. {
    91. while (0 == I2C_GetIrq(I2CX))
    92. {;}
    93. u8State = I2C_GetState(I2CX);
    94. switch (u8State)
    95. {
    96. case 0x08: ///已发送起始条件
    97. I2C_ClearFunc(I2CX, I2cStart_En);
    98. I2C_WriteByte(I2CX, (I2C_DEVADDR)); ///从设备地址发送
    99. break;
    100. case 0x18: ///已发送SLA+W,并接收到ACK
    101. I2C_WriteByte(I2CX, register_addr);
    102. break;
    103. case 0x28: ///上一次发送数据后接收到ACK
    104. I2C_WriteByte(I2CX, pu8Data[u8i++]);
    105. break;
    106. case 0x20: ///上一次发送SLA+W后,收到NACK
    107. case 0x38: ///上一次在SLA+读或写时丢失仲裁
    108. I2C_SetFunc(I2CX, I2cStart_En); ///当I2C总线空闲时发送起始条件
    109. break;
    110. case 0x30: ///已发送I2Cx_DATA中的数据,收到NACK,将传输一个STOP条件
    111. I2C_SetFunc(I2CX, I2cStop_En); ///发送停止条件
    112. break;
    113. default:
    114. break;
    115. }
    116. if (u8i > u32Len)
    117. {
    118. I2C_SetFunc(I2CX, I2cStop_En); ///此顺序不能调换,出停止条件
    119. I2C_ClearIrq(I2CX);
    120. break;
    121. }
    122. I2C_ClearIrq(I2CX); ///清除中断状态标志位
    123. }
    124. enRet = Ok;
    125. return enRet;
    126. }

  • 相关阅读:
    产品经理就业喜报:沉舟侧畔终迎万木春
    什么是IPLC专线?IPLC专线有什么优势?
    八、【快速选择工具组】
    ‍ 太空网络攻击
    nrf9160做主控连接阿里云(mqtt_simple例程)——附MQTT协议浅解
    使用Blazor构建投资回报计算器
    2022VR高级研修班总结
    solidity部署和验证代理合约
    unittest自动化测试框架
    【PostgreSQL】Spring boot + Mybatis-plus + PostgreSQL 处理json类型情况
  • 原文地址:https://blog.csdn.net/cftchaoxiaoshu/article/details/133386492