MPU6050.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. /*
  2. * Copyright (c) 2020 Nanjing Xiaoxiongpai Intelligent Technology Co., Ltd.
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #include "MPU6050.h"
  16. #include "cmsis_os2.h"
  17. #include "iot_errno.h"
  18. #include "iot_gpio.h"
  19. #include "iot_gpio_ex.h"
  20. #include "iot_i2c.h"
  21. #include "iot_i2c_ex.h"
  22. #include <math.h>
  23. #include <stdio.h>
  24. #include <string.h>
  25. #include <unistd.h>
  26. #define WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA 6
  27. #define WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL 6
  28. #define WIFI_IOT_IO_FUNC_GPIO_8_GPIO 0
  29. #define WIFI_IOT_IO_FUNC_GPIO_7_GPIO 0
  30. #define WIFI_IOT_I2C_IDX_1 1
  31. #define WIFI_IOT_IO_NAME_GPIO_7 7
  32. #define WIFI_IOT_IO_NAME_GPIO_8 8
  33. #define WIFI_IOT_IO_NAME_GPIO_0 0
  34. #define WIFI_IOT_IO_NAME_GPIO_1 1
  35. #define RESET_DELAY_US 20000
  36. #define READ_DATA_DELAY_US 50000
  37. /***************************************************************
  38. * 函数名称: GpioInit
  39. * 说 明: GPIO初始化
  40. * 参 数: 无
  41. * 返 回 值: 无
  42. ***************************************************************/
  43. static void GpioInit(void)
  44. {
  45. IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_8);
  46. IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_IO_FUNC_GPIO_8_GPIO);
  47. IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, IOT_GPIO_DIR_OUT); // 设置GPIO_8为输出模式
  48. IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_7);
  49. IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_7, WIFI_IOT_IO_FUNC_GPIO_7_GPIO);
  50. IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_7, IOT_GPIO_DIR_OUT); // 设置GPIO_7为输出模式
  51. IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_0);
  52. IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_0, WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA); // GPIO_0复用为I2C1_SDA
  53. IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_1);
  54. IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_1, WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL); // GPIO_1复用为I2C1_SCL
  55. IoTI2cInit(WIFI_IOT_I2C_IDX_1, 400000); /* baudrate: 400kbps */
  56. }
  57. /***************************************************************
  58. * 函数功能: 通过I2C写入一个值到指定寄存器内
  59. * 输入参数: Addr:I2C设备地址
  60. * Reg:目标寄存器
  61. * Value:值
  62. * 返 回 值: 无
  63. * 说 明: 无
  64. **************************************************************/
  65. static int MPU6050WriteData(uint8_t Reg, uint8_t Value)
  66. {
  67. uint32_t ret;
  68. uint8_t send_data[2] = {Reg, Value};
  69. ret = IoTI2cWrite(WIFI_IOT_I2C_IDX_1, (MPU6050_SLAVE_ADDRESS << 1) | 0x00, send_data, 2);
  70. if (ret != 0) {
  71. printf("===== Error: I2C write ret = 0x%x! =====\r\n", ret);
  72. return -1;
  73. }
  74. return 0;
  75. }
  76. /***************************************************************
  77. * 函数功能: 通过I2C写入一段数据到指定寄存器内
  78. * 输入参数: Addr:I2C设备地址
  79. * Reg:目标寄存器
  80. * RegSize:寄存器尺寸(8位或者16位)
  81. * pBuffer:缓冲区指针
  82. * Length:缓冲区长度
  83. * 返 回 值: HAL_StatusTypeDef:操作结果
  84. * 说 明: 在循环调用是需加一定延时时间
  85. **************************************************************/
  86. static int MPU6050WriteBuffer(uint8_t Reg, uint8_t* pBuffer, uint16_t Length)
  87. {
  88. uint32_t ret = 0;
  89. uint8_t send_data[256] = {0};
  90. send_data[0] = Reg;
  91. for (int j = 0; j < Length; j++) {
  92. send_data[j + 1] = pBuffer[j];
  93. }
  94. ret = IoTI2cWrite(WIFI_IOT_I2C_IDX_1, (MPU6050_SLAVE_ADDRESS << 1) | 0x00, send_data, Length + 1);
  95. if (ret != 0) {
  96. printf("===== Error: I2C write ret = 0x%x! =====\r\n", ret);
  97. return -1;
  98. }
  99. return 0;
  100. }
  101. /***************************************************************
  102. * 函数功能: 通过I2C读取一段寄存器内容存放到指定的缓冲区内
  103. * 输入参数: Addr:I2C设备地址
  104. * Reg:目标寄存器
  105. * RegSize:寄存器尺寸(8位或者16位)
  106. * pBuffer:缓冲区指针
  107. * Length:缓冲区长度
  108. * 返 回 值: HAL_StatusTypeDef:操作结果
  109. * 说 明: 无
  110. **************************************************************/
  111. static int MPU6050ReadBuffer(uint8_t Reg, uint8_t* pBuffer, uint16_t Length)
  112. {
  113. uint32_t ret = 0;
  114. IotI2cData mpu6050_i2c_data = {0};
  115. uint8_t buffer[1] = {Reg};
  116. mpu6050_i2c_data.sendBuf = buffer;
  117. mpu6050_i2c_data.sendLen = 1;
  118. mpu6050_i2c_data.receiveBuf = pBuffer;
  119. mpu6050_i2c_data.receiveLen = Length;
  120. ret = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (MPU6050_SLAVE_ADDRESS << 1) | 0x00, &mpu6050_i2c_data);
  121. if (ret != 0) {
  122. printf("===== Error: I2C writeread ret = 0x%x! =====\r\n", ret);
  123. return -1;
  124. }
  125. return 0;
  126. }
  127. /***************************************************************
  128. * 函数功能: 写数据到MPU6050寄存器
  129. * 输入参数: 无
  130. * 返 回 值: 无
  131. * 说 明: 无
  132. ***************************************************************/
  133. static void MPU6050WriteReg(uint8_t reg_add, uint8_t reg_dat)
  134. {
  135. MPU6050WriteData(reg_add, reg_dat);
  136. }
  137. /***************************************************************
  138. * 函数功能: 从MPU6050寄存器读取数据
  139. * 输入参数: 无
  140. * 返 回 值: 无
  141. * 说 明: 无
  142. ***************************************************************/
  143. static int MPU6050Read(uint8_t reg_add, unsigned char* read, uint8_t num)
  144. {
  145. return MPU6050ReadBuffer(reg_add, read, num);
  146. }
  147. /***************************************************************
  148. * 函数功能: 读取MPU6050的加速度数据
  149. * 输入参数: 无
  150. * 返 回 值: 无
  151. * 说 明: 无
  152. ***************************************************************/
  153. static int MPU6050ReadAcc(short* accData)
  154. {
  155. int ret;
  156. uint8_t buf[ACCEL_DATA_LEN];
  157. ret = MPU6050Read(MPU6050_ACC_OUT, buf, ACCEL_DATA_LEN);
  158. if (ret != 0) {
  159. return -1;
  160. }
  161. accData[ACCEL_X_AXIS] = (buf[ACCEL_X_AXIS_LSB] << SENSOR_DATA_WIDTH_8_BIT) | buf[ACCEL_X_AXIS_MSB];
  162. accData[ACCEL_Y_AXIS] = (buf[ACCEL_Y_AXIS_LSB] << SENSOR_DATA_WIDTH_8_BIT) | buf[ACCEL_Y_AXIS_MSB];
  163. accData[ACCEL_Z_AXIS] = (buf[ACCEL_Z_AXIS_LSB] << SENSOR_DATA_WIDTH_8_BIT) | buf[ACCEL_Z_AXIS_MSB];
  164. return 0;
  165. }
  166. /***************************************************************
  167. * 函数功能: 读取MPU6050的角速度数据
  168. * 输入参数: 无
  169. * 返 回 值: 无
  170. * 说 明: 无
  171. ***************************************************************/
  172. static int MPU6050ReadGyro(short* gyroData)
  173. {
  174. int ret;
  175. uint8_t buf[ACCEL_DATA_LEN];
  176. ret = MPU6050Read(MPU6050_GYRO_OUT, buf, ACCEL_DATA_LEN);
  177. if (ret != 0) {
  178. return -1;
  179. }
  180. gyroData[ACCEL_X_AXIS] = (buf[ACCEL_X_AXIS_LSB] << SENSOR_DATA_WIDTH_8_BIT) | buf[ACCEL_X_AXIS_MSB];
  181. gyroData[ACCEL_Y_AXIS] = (buf[ACCEL_Y_AXIS_LSB] << SENSOR_DATA_WIDTH_8_BIT) | buf[ACCEL_Y_AXIS_MSB];
  182. gyroData[ACCEL_Z_AXIS] = (buf[ACCEL_Z_AXIS_LSB] << SENSOR_DATA_WIDTH_8_BIT) | buf[ACCEL_Z_AXIS_MSB];
  183. return 0;
  184. }
  185. /***************************************************************
  186. * 函数功能: 读取MPU6050的原始温度数据
  187. * 输入参数: 无
  188. * 返 回 值: 无
  189. * 说 明: 无
  190. ***************************************************************/
  191. static int MPU6050ReadTemp(short* tempData)
  192. {
  193. int ret;
  194. uint8_t buf[TEMP_DATA_LEN];
  195. ret = MPU6050Read(MPU6050_RA_TEMP_OUT_H, buf, TEMP_DATA_LEN); // 读取温度值
  196. if (ret != 0) {
  197. return -1;
  198. }
  199. *tempData = (buf[TEMP_LSB] << SENSOR_DATA_WIDTH_8_BIT) | buf[TEMP_MSB];
  200. return 0;
  201. }
  202. /***************************************************************
  203. * 函数功能: 读取MPU6050的温度数据,转化成摄氏度
  204. * 输入参数: 无
  205. * 返 回 值: 无
  206. * 说 明: 无
  207. **************************************************************/
  208. static int MPU6050ReturnTemp(short* Temperature)
  209. {
  210. int ret;
  211. short temp3;
  212. uint8_t buf[TEMP_DATA_LEN];
  213. ret = MPU6050Read(MPU6050_RA_TEMP_OUT_H, buf, TEMP_DATA_LEN); // 读取温度值
  214. if (ret != 0) {
  215. return -1;
  216. }
  217. temp3 = (buf[TEMP_LSB] << SENSOR_DATA_WIDTH_8_BIT) | buf[TEMP_MSB];
  218. *Temperature = (((double)(temp3 + 13200)) / 280) - 13;
  219. return 0;
  220. }
  221. /***************************************************************
  222. * 函数功能: 自由落体中断
  223. * 输入参数: 无
  224. * 返 回 值: 无
  225. * 说 明: 无
  226. **************************************************************/
  227. void FreeFallInterrupt(void) // 自由落体中断
  228. {
  229. MPU6050WriteReg(MPU6050_RA_FF_THR, 0x01); // 自由落体阈值
  230. MPU6050WriteReg(MPU6050_RA_FF_DUR, 0x01); // 自由落体检测时间20ms 单位1ms 寄存器0X20
  231. }
  232. void MotionInterrupt(void) // 运动中断
  233. {
  234. MPU6050WriteReg(MPU6050_RA_MOT_THR, 0x03); // 运动阈值
  235. MPU6050WriteReg(MPU6050_RA_MOT_DUR, 0x14); // 检测时间20ms 单位1ms 寄存器0X20
  236. }
  237. void ZeroMotionInterrupt(void) // 静止中断
  238. {
  239. MPU6050WriteReg(MPU6050_RA_ZRMOT_THR, 0x20); // 静止阈值
  240. MPU6050WriteReg(MPU6050_RA_ZRMOT_DUR, 0x20); // 静止检测时间20ms 单位1ms 寄存器0X20
  241. }
  242. /***************************************************************
  243. * 函数功能: 初始化MPU6050芯片
  244. * 输入参数: 无
  245. * 返 回 值: 无
  246. * 说 明: 无
  247. ***************************************************************/
  248. void MPU6050Init(void)
  249. {
  250. MPU6050WriteReg(MPU6050_RA_PWR_MGMT_1, 0X80); // 复位MPU6050
  251. usleep(RESET_DELAY_US);
  252. MPU6050WriteReg(MPU6050_RA_PWR_MGMT_1, 0X00); // 唤醒MPU6050
  253. MPU6050WriteReg(MPU6050_RA_INT_ENABLE, 0X00); // 关闭所有中断
  254. MPU6050WriteReg(MPU6050_RA_USER_CTRL, 0X00); // I2C主模式关闭
  255. MPU6050WriteReg(MPU6050_RA_FIFO_EN, 0X00); // 关闭FIFO
  256. MPU6050WriteReg(MPU6050_RA_INT_PIN_CFG,
  257. 0X80); // 中断的逻辑电平模式,设置为0,中断信号为高电;设置为1,中断信号为低电平时。
  258. MotionInterrupt(); // 运动中断
  259. MPU6050WriteReg(MPU6050_RA_CONFIG, 0x04); // 配置外部引脚采样和DLPF数字低通滤波器
  260. MPU6050WriteReg(MPU6050_RA_ACCEL_CONFIG, 0x1C); // 加速度传感器量程和高通滤波器配置
  261. MPU6050WriteReg(MPU6050_RA_INT_PIN_CFG, 0X1C); // INT引脚低电平平时
  262. MPU6050WriteReg(MPU6050_RA_INT_ENABLE, 0x40); // 中断使能寄存器
  263. }
  264. /***************************************************************
  265. * 函数功能: 读取MPU6050的ID
  266. * 输入参数: 无
  267. * 返 回 值: 无
  268. * 说 明: 无
  269. ***************************************************************/
  270. int MPU6050ReadID(void)
  271. {
  272. unsigned char Re = 0;
  273. MPU6050Read(MPU6050_RA_WHO_AM_I, &Re, 1); // 读器件地址
  274. if (Re != 0x68) {
  275. printf("MPU6050 dectected error!\r\n");
  276. return -1;
  277. } else {
  278. return 0;
  279. }
  280. }
  281. /***************************************************************
  282. * 函数名称: BoardInit
  283. * 说 明: 初始化扩展板
  284. * 参 数: 无
  285. * 返 回 值: 无
  286. ***************************************************************/
  287. int BoardInit(void)
  288. {
  289. uint32_t ret = 0;
  290. GpioInit();
  291. MPU6050Init();
  292. ret = MPU6050ReadID();
  293. if (ret != 0) {
  294. return -1;
  295. }
  296. osDelay(100);
  297. return 0;
  298. }
  299. /***************************************************************
  300. * 函数名称: MPU6050ReadData
  301. * 说 明: 读取数据
  302. * 参 数: 无
  303. * 返 回 值: 无
  304. ***************************************************************/
  305. int MPU6050ReadData(MPU6050Data* ReadData)
  306. {
  307. int ret;
  308. short Accel[3];
  309. short Temp;
  310. if (MPU6050ReadID() != 0) {
  311. return -1;
  312. }
  313. ret = MPU6050ReadAcc(Accel);
  314. if (ret != 0) {
  315. return -1;
  316. }
  317. ret = MPU6050ReturnTemp(&Temp);
  318. if (ret != 0) {
  319. return -1;
  320. }
  321. ReadData->Temperature = Temp;
  322. ReadData->Accel[ACCEL_X_AXIS] = Accel[ACCEL_X_AXIS];
  323. ReadData->Accel[ACCEL_Y_AXIS] = Accel[ACCEL_Y_AXIS];
  324. ReadData->Accel[ACCEL_Z_AXIS] = Accel[ACCEL_Z_AXIS];
  325. usleep(READ_DATA_DELAY_US);
  326. return 0;
  327. }
  328. /***************************************************************
  329. * 函数名称: LedD1StatusSet
  330. * 说 明: LED_D1状态设置
  331. * 参 数: status,ENUM枚举的数据
  332. * OFF,关
  333. * ON,开
  334. * 返 回 值: 无
  335. ***************************************************************/
  336. void LedD1StatusSet(SwitchStatus status)
  337. {
  338. if (status == ON) {
  339. IoTGpioSetOutputVal(7, 1); // 设置GPIO_7输出高电平点亮灯
  340. }
  341. if (status == OFF) {
  342. IoTGpioSetOutputVal(7, 0); // 设置GPIO_7输出低电平关闭灯
  343. }
  344. }
  345. /***************************************************************
  346. * 函数名称: LedD2StatusSet
  347. * 说 明: LED_D2状态设置
  348. * 参 数: status,ENUM枚举的数据
  349. * OFF,关
  350. * ON,开
  351. * 返 回 值: 无
  352. ***************************************************************/
  353. void LedD2StatusSet(SwitchStatus status)
  354. {
  355. if (status == ON) {
  356. IoTGpioSetOutputVal(8, 1); // 设置GPIO_8输出高电平点亮灯
  357. }
  358. if (status == OFF) {
  359. IoTGpioSetOutputVal(8, 0); // 设置GPIO_8输出低电平关闭灯
  360. }
  361. }