atk_ms6050_iic.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. #include "atk_ms6050_iic.h"
  2. //#include "./SYSTEM/delay/delay.h"
  3. void delay_us(uint32_t us) {
  4. uint32_t total_cycles = us * 72; // 假设1个指令周期为1/72MHz秒
  5. for (uint32_t i = 0; i < total_cycles; i++) {
  6. __NOP(); // 空操作指令,用于消耗一个指令周期
  7. }
  8. }
  9. // 初始化DWT延时函数
  10. void DWT_Delay_Init(void) {
  11. if (!(CoreDebug->DEMCR & CoreDebug_DEMCR_TRCENA_Msk)) {
  12. CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
  13. DWT->CYCCNT = 0;
  14. DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
  15. }
  16. }
  17. // 微秒级延时函数
  18. void DWT_Delay_us(volatile uint32_t microseconds) {
  19. uint32_t clk_cycle_start = DWT->CYCCNT;
  20. // 根据系统时钟频率计算需要的时钟周期数
  21. // SystemCoreClock 是每秒的时钟周期数
  22. uint32_t delay_ticks = (SystemCoreClock / 1000000) * microseconds;
  23. while ((DWT->CYCCNT - clk_cycle_start) < delay_ticks);
  24. }
  25. /**
  26. * @brief IIC接口延时函数,用于控制IIC读写速度
  27. * @param 无
  28. * @retval 无
  29. */
  30. static inline void atk_ms6050_iic_delay(void)
  31. {
  32. // delay_us(2);
  33. DWT_Delay_us(2);
  34. }
  35. /**
  36. * @brief 产生IIC起始信号
  37. * @param 无
  38. * @retval 无
  39. */
  40. void atk_ms6050_iic_start(void)
  41. {
  42. ATK_MS6050_IIC_SDA(1);
  43. ATK_MS6050_IIC_SCL(1);
  44. atk_ms6050_iic_delay();
  45. ATK_MS6050_IIC_SDA(0);
  46. atk_ms6050_iic_delay();
  47. ATK_MS6050_IIC_SCL(0);
  48. atk_ms6050_iic_delay();
  49. }
  50. /**
  51. * @brief 产生IIC停止信号
  52. * @param 无
  53. * @retval 无
  54. */
  55. void atk_ms6050_iic_stop(void)
  56. {
  57. ATK_MS6050_IIC_SDA(0);
  58. atk_ms6050_iic_delay();
  59. ATK_MS6050_IIC_SCL(1);
  60. atk_ms6050_iic_delay();
  61. ATK_MS6050_IIC_SDA(1);
  62. atk_ms6050_iic_delay();
  63. }
  64. /**
  65. * @brief 等待IIC应答信号
  66. * @param 无
  67. * @retval 0: 应答信号接收成功
  68. * 1: 应答信号接收失败
  69. */
  70. uint8_t atk_ms6050_iic_wait_ack(void)
  71. {
  72. uint8_t waittime = 0;
  73. uint8_t rack = 0;
  74. ATK_MS6050_IIC_SDA(1);
  75. atk_ms6050_iic_delay();
  76. ATK_MS6050_IIC_SCL(1);
  77. atk_ms6050_iic_delay();
  78. while (ATK_MS6050_IIC_READ_SDA())
  79. {
  80. waittime++;
  81. if (waittime > 250)
  82. {
  83. atk_ms6050_iic_stop();
  84. rack = 1;
  85. break;
  86. }
  87. }
  88. ATK_MS6050_IIC_SCL(0);
  89. atk_ms6050_iic_delay();
  90. return rack;
  91. }
  92. /**
  93. * @brief 产生ACK应答信号
  94. * @param 无
  95. * @retval 无
  96. */
  97. void atk_ms6050_iic_ack(void)
  98. {
  99. ATK_MS6050_IIC_SDA(0);
  100. atk_ms6050_iic_delay();
  101. ATK_MS6050_IIC_SCL(1);
  102. atk_ms6050_iic_delay();
  103. ATK_MS6050_IIC_SCL(0);
  104. atk_ms6050_iic_delay();
  105. ATK_MS6050_IIC_SDA(1);
  106. atk_ms6050_iic_delay();
  107. }
  108. /**
  109. * @brief 不产生ACK应答信号
  110. * @param 无
  111. * @retval 无
  112. */
  113. void atk_ms6050_iic_nack(void)
  114. {
  115. ATK_MS6050_IIC_SDA(1);
  116. atk_ms6050_iic_delay();
  117. ATK_MS6050_IIC_SCL(1);
  118. atk_ms6050_iic_delay();
  119. ATK_MS6050_IIC_SCL(0);
  120. atk_ms6050_iic_delay();
  121. }
  122. /**
  123. * @brief IIC发送一个字节
  124. * @param dat: 要发送的数据
  125. * @retval 无
  126. */
  127. void atk_ms6050_iic_send_byte(uint8_t dat)
  128. {
  129. uint8_t t;
  130. for (t=0; t<8; t++)
  131. {
  132. ATK_MS6050_IIC_SDA((dat & 0x80) >> 7);
  133. atk_ms6050_iic_delay();
  134. ATK_MS6050_IIC_SCL(1);
  135. atk_ms6050_iic_delay();
  136. ATK_MS6050_IIC_SCL(0);
  137. dat <<= 1;
  138. }
  139. ATK_MS6050_IIC_SDA(1);
  140. }
  141. /**
  142. * @brief IIC接收一个字节
  143. * @param ack: ack=1时,发送ack; ack=0时,发送nack
  144. * @retval 接收到的数据
  145. */
  146. uint8_t atk_ms6050_iic_read_byte(uint8_t ack)
  147. {
  148. uint8_t i;
  149. uint8_t dat = 0;
  150. for (i = 0; i < 8; i++ )
  151. {
  152. dat <<= 1;
  153. ATK_MS6050_IIC_SCL(1);
  154. atk_ms6050_iic_delay();
  155. if (ATK_MS6050_IIC_READ_SDA())
  156. {
  157. dat++;
  158. }
  159. ATK_MS6050_IIC_SCL(0);
  160. atk_ms6050_iic_delay();
  161. }
  162. if (ack == 0)
  163. {
  164. atk_ms6050_iic_nack();
  165. }
  166. else
  167. {
  168. atk_ms6050_iic_ack();
  169. }
  170. return dat;
  171. }
  172. /**
  173. * @brief 初始化IIC接口
  174. * @param 无
  175. * @retval 无
  176. */
  177. void atk_ms6050_iic_init(void)
  178. {
  179. GPIO_InitTypeDef gpio_init_struct = {0};
  180. /* 使能SCL、SDA引脚GPIO的时钟 */
  181. ATK_MS6050_IIC_SCL_GPIO_CLK_ENABLE();
  182. ATK_MS6050_IIC_SDA_GPIO_CLK_ENABLE();
  183. /* 初始化SCL引脚 */
  184. gpio_init_struct.Pin = ATK_MS6050_IIC_SCL_GPIO_PIN; /* SCL引脚 */
  185. gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
  186. gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
  187. gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
  188. HAL_GPIO_Init(ATK_MS6050_IIC_SCL_GPIO_PORT, &gpio_init_struct);
  189. /* 初始化SDA引脚 */
  190. gpio_init_struct.Pin = ATK_MS6050_IIC_SDA_GPIO_PIN; /* SDA引脚 */
  191. gpio_init_struct.Mode = GPIO_MODE_OUTPUT_OD; /* 开漏输出 */
  192. HAL_GPIO_Init(ATK_MS6050_IIC_SDA_GPIO_PORT, &gpio_init_struct);
  193. DWT_Delay_Init(); // 延时函数初始化
  194. atk_ms6050_iic_stop();
  195. }