atk_ms6050.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. #include "atk_ms6050.h"
  2. #include "atk_ms6050_iic.h"
  3. #include "cmsis_os.h"
  4. //#include "./SYSTEM/usart/usart.h"
  5. //#include "./SYSTEM/delay/delay.h"
  6. #define delay_ms HAL_Delay
  7. /**
  8. * @brief ATK-MS6050硬件初始化
  9. * @param 无
  10. * @retval 无
  11. */
  12. //static void atk_ms6050_hw_init(void)
  13. //{
  14. // GPIO_InitTypeDef gpio_init_struct = {0};
  15. //
  16. // /* 使能AD0引脚GPIO的时钟 */
  17. // ATK_MS6050_AD0_GPIO_CLK_ENABLE();
  18. //
  19. // /* 初始化AD0引脚 */
  20. // gpio_init_struct.Pin = ATK_MS6050_AD0_GPIO_PIN; /* AD0引脚 */
  21. // gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推挽输出 */
  22. // gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
  23. // gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */
  24. // HAL_GPIO_Init(ATK_MS6050_AD0_GPIO_PORT, &gpio_init_struct);
  25. //
  26. // /* 控制ATK-MS6050的AD0引脚为低电平
  27. // * 设置其IIC的从机地址为0x68
  28. // */
  29. // ATK_MS6050_AD0(0);
  30. //}
  31. /**
  32. * @brief 往ATK-MS6050的指定寄存器连续写入指定数据
  33. * @param addr: ATK-MS6050的IIC通讯地址
  34. * reg : ATK-MS6050寄存器地址
  35. * len : 写入的长度
  36. * dat : 写入的数据
  37. * @retval ATK_MS6050_EOK : 函数执行成功
  38. * ATK_MS6050_EACK: IIC通讯ACK错误,函数执行失败
  39. */
  40. uint8_t atk_ms6050_write(uint8_t addr,uint8_t reg, uint8_t len, uint8_t *dat)
  41. {
  42. uint8_t i;
  43. atk_ms6050_iic_start();
  44. atk_ms6050_iic_send_byte((addr << 1) | 0);
  45. if (atk_ms6050_iic_wait_ack() == 1)
  46. {
  47. atk_ms6050_iic_stop();
  48. return ATK_MS6050_EACK;
  49. }
  50. atk_ms6050_iic_send_byte(reg);
  51. if (atk_ms6050_iic_wait_ack() == 1)
  52. {
  53. atk_ms6050_iic_stop();
  54. return ATK_MS6050_EACK;
  55. }
  56. for (i=0; i<len; i++)
  57. {
  58. atk_ms6050_iic_send_byte(dat[i]);
  59. if (atk_ms6050_iic_wait_ack() == 1)
  60. {
  61. atk_ms6050_iic_stop();
  62. return ATK_MS6050_EACK;
  63. }
  64. }
  65. atk_ms6050_iic_stop();
  66. return ATK_MS6050_EOK;
  67. }
  68. /**
  69. * @brief 往ATK-MS6050的指定寄存器写入一字节数据
  70. * @param addr: ATK-MS6050的IIC通讯地址
  71. * reg : ATK-MS6050寄存器地址
  72. * dat : 写入的数据
  73. * @retval ATK_MS6050_EOK : 函数执行成功
  74. * ATK_MS6050_EACK: IIC通讯ACK错误,函数执行失败
  75. */
  76. uint8_t atk_ms6050_write_byte(uint8_t addr, uint8_t reg, uint8_t dat)
  77. {
  78. return atk_ms6050_write(addr, reg, 1, &dat);
  79. }
  80. /**
  81. * @brief 连续读取ATK-MS6050指定寄存器的值
  82. * @param addr: ATK-MS6050的IIC通讯地址
  83. * reg : ATK-MS6050寄存器地址
  84. * len: 读取的长度
  85. * dat: 存放读取到的数据的地址
  86. * @retval ATK_MS6050_EOK : 函数执行成功
  87. * ATK_MS6050_EACK: IIC通讯ACK错误,函数执行失败
  88. */
  89. uint8_t atk_ms6050_read(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *dat)
  90. {
  91. atk_ms6050_iic_start();
  92. atk_ms6050_iic_send_byte((addr << 1) | 0);
  93. if (atk_ms6050_iic_wait_ack() == 1)
  94. {
  95. atk_ms6050_iic_stop();
  96. return ATK_MS6050_EACK;
  97. }
  98. atk_ms6050_iic_send_byte(reg);
  99. if (atk_ms6050_iic_wait_ack() == 1)
  100. {
  101. atk_ms6050_iic_stop();
  102. return ATK_MS6050_EACK;
  103. }
  104. atk_ms6050_iic_start();
  105. atk_ms6050_iic_send_byte((addr << 1) | 1);
  106. if (atk_ms6050_iic_wait_ack() == 1)
  107. {
  108. atk_ms6050_iic_stop();
  109. return ATK_MS6050_EACK;
  110. }
  111. while (len)
  112. {
  113. *dat = atk_ms6050_iic_read_byte((len > 1) ? 1 : 0);
  114. len--;
  115. dat++;
  116. }
  117. atk_ms6050_iic_stop();
  118. return ATK_MS6050_EOK;
  119. }
  120. /**
  121. * @brief 读取ATK-MS6050指定寄存器的值
  122. * @param addr: ATK-MS6050的IIC通讯地址
  123. * reg : ATK-MS6050寄存器地址
  124. * dat: 读取到的寄存器的值
  125. * @retval ATK_MS6050_EOK : 函数执行成功
  126. * ATK_MS6050_EACK: IIC通讯ACK错误,函数执行失败
  127. */
  128. uint8_t atk_ms6050_read_byte(uint8_t addr, uint8_t reg, uint8_t *dat)
  129. {
  130. return atk_ms6050_read(addr, reg, 1, dat);
  131. }
  132. /**
  133. * @brief ATK-MS6050软件复位
  134. * @param 无
  135. * @retval 无
  136. */
  137. void atk_ms6050_sw_reset(void)
  138. {
  139. atk_ms6050_write_byte(ATK_MS6050_IIC_ADDR, MPU_PWR_MGMT1_REG, 0x80);
  140. delay_ms(100);
  141. atk_ms6050_write_byte(ATK_MS6050_IIC_ADDR, MPU_PWR_MGMT1_REG, 0x00);
  142. }
  143. /**
  144. * @brief ATK-MS6050设置陀螺仪传感器量程范围
  145. * @param frs: 0 --> ±250dps
  146. * 1 --> ±500dps
  147. * 2 --> ±1000dps
  148. * 3 --> ±2000dps
  149. * @retval ATK_MS6050_EOK : 函数执行成功
  150. * ATK_MS6050_EACK: IIC通讯ACK错误,函数执行失败
  151. */
  152. uint8_t atk_ms6050_set_gyro_fsr(uint8_t fsr)
  153. {
  154. return atk_ms6050_write_byte(ATK_MS6050_IIC_ADDR, MPU_GYRO_CFG_REG, fsr << 3);
  155. }
  156. /**
  157. * @brief ATK-MS6050设置加速度传感器量程范围
  158. * @param frs: 0 --> ±2g
  159. * 1 --> ±4g
  160. * 2 --> ±8g
  161. * 3 --> ±16g
  162. * @retval ATK_MS6050_EOK : 函数执行成功
  163. * ATK_MS6050_EACK: IIC通讯ACK错误,函数执行失败
  164. */
  165. uint8_t atk_ms6050_set_accel_fsr(uint8_t fsr)
  166. {
  167. return atk_ms6050_write_byte(ATK_MS6050_IIC_ADDR, MPU_ACCEL_CFG_REG, fsr << 3);
  168. }
  169. /**
  170. * @brief ATK-MS6050设置数字低通滤波器频率
  171. * @param lpf: 数字低通滤波器的频率(Hz)
  172. * @retval ATK_MS6050_EOK : 函数执行成功
  173. * ATK_MS6050_EACK: IIC通讯ACK错误,函数执行失败
  174. */
  175. uint8_t atk_ms6050_set_lpf(uint16_t lpf)
  176. {
  177. uint8_t dat;
  178. if (lpf >= 188)
  179. {
  180. dat = 1;
  181. }
  182. else if (lpf >= 98)
  183. {
  184. dat = 2;
  185. }
  186. else if (lpf >= 42)
  187. {
  188. dat = 3;
  189. }
  190. else if (lpf >= 20)
  191. {
  192. dat = 4;
  193. }
  194. else if (lpf >= 10)
  195. {
  196. dat = 5;
  197. }
  198. else
  199. {
  200. dat = 6;
  201. }
  202. return atk_ms6050_write_byte(ATK_MS6050_IIC_ADDR, MPU_CFG_REG, dat);
  203. }
  204. /**
  205. * @brief ATK-MS6050设置采样率
  206. * @param rate: 采样率(4~1000Hz)
  207. * @retval ATK_MS6050_EOK : 函数执行成功
  208. * ATK_MS6050_EACK: IIC通讯ACK错误,函数执行失败
  209. */
  210. uint8_t atk_ms6050_set_rate(uint16_t rate)
  211. {
  212. uint8_t ret;
  213. uint8_t dat;
  214. if (rate > 1000)
  215. {
  216. rate = 1000;
  217. }
  218. if (rate < 4)
  219. {
  220. rate = 4;
  221. }
  222. dat = 1000 / rate - 1;
  223. ret = atk_ms6050_write_byte(ATK_MS6050_IIC_ADDR, MPU_SAMPLE_RATE_REG, dat);
  224. if (ret != ATK_MS6050_EOK)
  225. {
  226. return ret;
  227. }
  228. ret = atk_ms6050_set_lpf(rate >> 1);
  229. if (ret != ATK_MS6050_EOK)
  230. {
  231. return ret;
  232. }
  233. return ATK_MS6050_EOK;
  234. }
  235. /**
  236. * @brief ATK-MS6050获取温度值
  237. * @param temperature: 获取到的温度值(扩大了100倍)
  238. * @retval ATK_MS6050_EOK : 函数执行成功
  239. * ATK_MS6050_EACK: IIC通讯ACK错误,函数执行失败
  240. */
  241. uint8_t atk_ms6050_get_temperature(int16_t *temp)
  242. {
  243. uint8_t dat[2];
  244. uint8_t ret;
  245. int16_t raw = 0;
  246. ret = atk_ms6050_read(ATK_MS6050_IIC_ADDR, MPU_TEMP_OUTH_REG, 2, dat);
  247. if (ret == ATK_MS6050_EOK)
  248. {
  249. raw = ((uint16_t)dat[0] << 8) | dat[1];
  250. *temp = (int16_t)((36.53f + ((float)raw / 340)) * 100);
  251. }
  252. return ret;
  253. }
  254. /**
  255. * @brief ATK-MS6050获取陀螺仪值
  256. * @param gx,gy,gz: 陀螺仪x、y、z轴的原始度数(带符号)
  257. * @retval ATK_MS6050_EOK : 函数执行成功
  258. * ATK_MS6050_EACK: IIC通讯ACK错误,函数执行失败
  259. */
  260. uint8_t atk_ms6050_get_gyroscope(int16_t *gx, int16_t *gy, int16_t *gz)
  261. {
  262. uint8_t dat[6];
  263. uint8_t ret;
  264. ret = atk_ms6050_read(ATK_MS6050_IIC_ADDR, MPU_GYRO_XOUTH_REG, 6, dat);
  265. if (ret == ATK_MS6050_EOK)
  266. {
  267. *gx = ((uint16_t)dat[0] << 8) | dat[1];
  268. *gy = ((uint16_t)dat[2] << 8) | dat[3];
  269. *gz = ((uint16_t)dat[4] << 8) | dat[5];
  270. }
  271. return ret;
  272. }
  273. /**
  274. * @brief ATK-MS6050获取加速度值
  275. * @param ax,ay,az: 加速度x、y、z轴的原始度数(带符号)
  276. * @retval ATK_MS6050_EOK : 函数执行成功
  277. * ATK_MS6050_EACK: IIC通讯ACK错误,函数执行失败
  278. */
  279. uint8_t atk_ms6050_get_accelerometer(int16_t *ax, int16_t *ay, int16_t *az)
  280. {
  281. uint8_t dat[6];
  282. uint8_t ret;
  283. ret = atk_ms6050_read(ATK_MS6050_IIC_ADDR, MPU_ACCEL_XOUTH_REG, 6, dat);
  284. if (ret == ATK_MS6050_EOK)
  285. {
  286. *ax = ((uint16_t)dat[0] << 8) | dat[1];
  287. *ay = ((uint16_t)dat[2] << 8) | dat[3];
  288. *az = ((uint16_t)dat[4] << 8) | dat[5];
  289. }
  290. return ret;
  291. }
  292. /**
  293. * @brief ATK-MS6050初始化
  294. * @param 无
  295. * @retval ATK_MS6050_EOK: 函数执行成功
  296. * ATK_MS6050_EID: 获取ID错误,函数执行失败
  297. */
  298. uint8_t atk_ms6050_init(void)
  299. {
  300. uint8_t id;
  301. // atk_ms6050_hw_init(); /* ATK-MS6050硬件初始化 */
  302. atk_ms6050_iic_init(); /* 初始化IIC接口 */
  303. atk_ms6050_sw_reset(); /* ATK-MS050软件复位 */
  304. atk_ms6050_set_gyro_fsr(3); /* 陀螺仪传感器,±2000dps */
  305. atk_ms6050_set_accel_fsr(0); /* 加速度传感器,±2g */
  306. atk_ms6050_set_rate(50); /* 采样率,50Hz */
  307. atk_ms6050_write_byte(ATK_MS6050_IIC_ADDR, MPU_INT_EN_REG, 0X00); /* 关闭所有中断 */
  308. atk_ms6050_write_byte(ATK_MS6050_IIC_ADDR, MPU_USER_CTRL_REG, 0X00); /* 关闭IIC主模式 */
  309. atk_ms6050_write_byte(ATK_MS6050_IIC_ADDR, MPU_FIFO_EN_REG, 0X00); /* 关闭FIFO */
  310. atk_ms6050_write_byte(ATK_MS6050_IIC_ADDR, MPU_INTBP_CFG_REG, 0X80); /* INT引脚低电平有效 */
  311. atk_ms6050_read_byte(ATK_MS6050_IIC_ADDR, MPU_DEVICE_ID_REG, &id); /* 读取设备ID */
  312. if (id != ATK_MS6050_IIC_ADDR)
  313. {
  314. return ATK_MS6050_EID;
  315. }
  316. atk_ms6050_write_byte(ATK_MS6050_IIC_ADDR, MPU_PWR_MGMT1_REG, 0x01); /* 设置CLKSEL,PLL X轴为参考 */
  317. atk_ms6050_write_byte(ATK_MS6050_IIC_ADDR, MPU_PWR_MGMT2_REG, 0x00); /* 加速度与陀螺仪都工作 */
  318. atk_ms6050_set_rate(50); /* 采样率,50Hz */
  319. return ATK_MS6050_EOK;
  320. }