MPU6050.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. /*
  2. * MPU6050.c
  3. *
  4. * Created on: Oct 26, 2021
  5. * Author: Administrator
  6. */
  7. #include "MPU6050.h"
  8. #include <stdio.h>
  9. extern int a;
  10. extern int t;
  11. u8 IIC_Write_Byte(u8 reg, u8 value)
  12. {
  13. return IIC_Write_Len(a, reg, 1, &value);
  14. }
  15. u8 IIC_Read_Byte(u8 reg)
  16. {
  17. u8 value = 0;
  18. IIC_Read_Len(a, reg, 1, &value);
  19. return value;
  20. }
  21. //IIC连续写
  22. u8 IIC_Write_Len(u8 addr,u8 reg, u8 len, u8 *buf)
  23. {
  24. addr = a;
  25. addr = (addr << 1) | 0;
  26. u8 data[10] = {0};
  27. data[0] = reg;
  28. for(int i = 0; i < len; i++)
  29. {
  30. data[1 + i] = buf[i];
  31. }
  32. if(t==1){
  33. if(HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)addr, (uint8_t*)data, len + 1, 10000)!= HAL_OK)
  34. {
  35. printf("++write len byte fail\r\n");
  36. return 1;
  37. }
  38. }
  39. else if(t==2){
  40. if(HAL_I2C_Master_Transmit(&hi2c2, (uint16_t)addr, (uint8_t*)data, len + 1, 10000)!= HAL_OK)
  41. {
  42. printf("++write len byte fail\r\n");
  43. return 1;
  44. }
  45. }
  46. else if(t==3){
  47. if(HAL_I2C_Master_Transmit(&hi2c3, (uint16_t)addr, (uint8_t*)data, len + 1, 10000)!= HAL_OK)
  48. {
  49. printf("++write len byte fail\r\n");
  50. return 1;
  51. }
  52. }
  53. return 0;
  54. }
  55. //IIC连续读
  56. u8 IIC_Read_Len(u8 addr,u8 reg,u8 len,u8 *buf)
  57. {
  58. addr = a;
  59. if(t==1){
  60. u8 tmp = (addr << 1) | 0;
  61. if(HAL_I2C_Master_Transmit(&hi2c1, (uint16_t)tmp, (uint8_t*)&reg, 1, 10000)!= HAL_OK)
  62. {
  63. printf("++write byte fail\r\n");
  64. return 1;
  65. }
  66. tmp = (addr << 1) | 1;
  67. if(HAL_I2C_Master_Receive(&hi2c1, (uint16_t)tmp, (uint8_t *)buf, len, 10000) != HAL_OK)
  68. {
  69. printf("--read byte fail\r\n");
  70. }
  71. }
  72. else if(t==2){
  73. u8 tmp = (addr << 1) | 0;
  74. if(HAL_I2C_Master_Transmit(&hi2c2, (uint16_t)tmp, (uint8_t*)&reg, 1, 10000)!= HAL_OK)
  75. {
  76. printf("++write byte fail\r\n");
  77. return 1;
  78. }
  79. tmp = (addr << 1) | 1;
  80. if(HAL_I2C_Master_Receive(&hi2c2, (uint16_t)tmp, (uint8_t *)buf, len, 10000) != HAL_OK)
  81. {
  82. printf("--read byte fail\r\n");
  83. }
  84. }
  85. else if(t==3){
  86. u8 tmp = (addr << 1) | 0;
  87. if(HAL_I2C_Master_Transmit(&hi2c3, (uint16_t)tmp, (uint8_t*)&reg, 1, 10000)!= HAL_OK)
  88. {
  89. printf("++write byte fail\r\n");
  90. return 1;
  91. }
  92. tmp = (addr << 1) | 1;
  93. if(HAL_I2C_Master_Receive(&hi2c3, (uint16_t)tmp, (uint8_t *)buf, len, 10000) != HAL_OK)
  94. {
  95. printf("--read byte fail\r\n");
  96. }
  97. }
  98. }
  99. //初始化MPU6050
  100. //返回值: 0,成功
  101. // 其他,错误代码
  102. u8 MPU_Init(void)
  103. {
  104. u8 res = 0;
  105. IIC_Write_Byte(MPU_PWR_MGMT1_REG,0X80);//复位MPU6050
  106. HAL_Delay(100);
  107. IIC_Write_Byte(MPU_PWR_MGMT1_REG,0X00);//唤醒MPU6050
  108. MPU_Set_Gyro_Fsr(3); //陀螺仪传感器,±2000dps
  109. MPU_Set_Accel_Fsr(0); //加速度传感器 ±2g
  110. MPU_Set_Rate(50); //设置采样率50HZ
  111. IIC_Write_Byte(MPU_INT_EN_REG,0X00); //关闭所有中断
  112. IIC_Write_Byte(MPU_USER_CTRL_REG,0X00);//I2C主模式关闭
  113. IIC_Write_Byte(MPU_FIFO_EN_REG,0X00);//关闭FIFO
  114. IIC_Write_Byte(MPU_INTBP_CFG_REG,0X80);//INT引脚低电平有效
  115. res=IIC_Read_Byte(MPU_DEVICE_ID_REG);
  116. printf("the addr is:%d\r\n", res);
  117. if(res==a)//器件ID正确
  118. {
  119. IIC_Write_Byte(MPU_PWR_MGMT1_REG,0X01);//设置CLKSEL,PLL X 轴为参考
  120. IIC_Write_Byte(MPU_PWR_MGMT2_REG,0X00);//加速度陀螺仪都工作
  121. MPU_Set_Rate(50); //设置采样率为50HZ
  122. }
  123. else
  124. {
  125. return 1;
  126. }
  127. return 0;
  128. }
  129. //设置MPU6050陀螺仪传感器满量程范围
  130. //fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps
  131. //返回值:0,设置成功
  132. // 其他,设置失败
  133. u8 MPU_Set_Gyro_Fsr(u8 fsr)
  134. {
  135. return IIC_Write_Byte(MPU_GYRO_CFG_REG, fsr<<3);//设置陀螺仪满量程范围
  136. }
  137. //设置MPU6050加速度传感器满量程范围
  138. //fsr:0,±2g;1,±4g;2,±8g;3,±16g
  139. //返回值:0,设置成功
  140. // 其他,设置失败
  141. u8 MPU_Set_Accel_Fsr(u8 fsr)
  142. {
  143. return IIC_Write_Byte(MPU_ACCEL_CFG_REG, fsr<<3);//设置加速度传感器满量程范围
  144. }
  145. //设置MPU6050的数字低通滤波器
  146. //lpf:数字低通滤波频率(Hz)
  147. //返回值:0,设置成功
  148. // 其他,设置失败
  149. u8 MPU_Set_LPF(u16 lpf)
  150. {
  151. u8 data=0;
  152. if(lpf>=188) data=1;
  153. else if(lpf>=98) data=2;
  154. else if(lpf>=42) data=2;
  155. else if(lpf>=42) data=3;
  156. else if(lpf>=20) data=4;
  157. else if(lpf>=10) data=5;
  158. else data=6;
  159. return IIC_Write_Byte(MPU_CFG_REG,data);//设置数字低通滤波器
  160. }
  161. //设置MPU6050的采样率(假定Fs=1KHz)
  162. //rate:4~1000(Hz)
  163. //返回值:0,设置成功
  164. // 其他,设置失败
  165. u8 MPU_Set_Rate(u16 rate)
  166. {
  167. u8 data;
  168. if(rate>1000)rate=1000;
  169. if(rate<4)rate=4;
  170. data=1000/rate-1;
  171. data=IIC_Write_Byte(MPU_SAMPLE_RATE_REG, data); //设置数字低通滤波器
  172. return MPU_Set_LPF(rate/2); //自动设置LPF为采样率的一半
  173. }
  174. //得到温度值
  175. //返回值:温度值(扩大了100倍)
  176. short MPU_Get_Temperature(void)
  177. {
  178. u8 buf[2];
  179. short raw;
  180. float temp;
  181. IIC_Read_Len(a, MPU_TEMP_OUTH_REG, 2, buf);
  182. raw=((u16)buf[0]<<8)|buf[1];
  183. temp=36.53+((double)raw)/340;
  184. return temp*100;;
  185. }
  186. //得到陀螺仪值(原始值)
  187. //gx,gy,gz:陀螺仪x,y,z轴的原始读数(带符号)
  188. //返回值:0,成功
  189. // 其他,错误代码
  190. u8 MPU_Get_Gyroscope(short *gx,short *gy,short *gz)
  191. {
  192. u8 buf[6],res;
  193. res=IIC_Read_Len(a,MPU_GYRO_XOUTH_REG,6,buf);
  194. if(res==0)
  195. {
  196. *gx=((u16)buf[0]<<8)|buf[1];
  197. *gy=((u16)buf[2]<<8)|buf[3];
  198. *gz=((u16)buf[4]<<8)|buf[5];
  199. }
  200. return res;
  201. }
  202. //得到加速度值(原始值)
  203. //ax,ay,az:陀螺仪x,y,z轴的原始读数(带符号)
  204. //返回值:0,成功
  205. // 其他,错误代码
  206. u8 MPU_Get_Accelerometer(short *ax,short *ay,short *az)
  207. {
  208. u8 buf[6],res;
  209. res=IIC_Read_Len(a,MPU_ACCEL_XOUTH_REG,6,buf);
  210. if(res==0)
  211. {
  212. *ax=((u16)buf[0]<<8)|buf[1];
  213. *ay=((u16)buf[2]<<8)|buf[3];
  214. *az=((u16)buf[4]<<8)|buf[5];
  215. }
  216. return res;;
  217. }
  218. /*--------------------以下为使用板载固件DMP的相关代码,这个融合得到的姿态角效果很好*/
  219. /**
  220. * @brief 获取当前毫秒值
  221. * @param 存储最新毫秒值的变量
  222. * @retval 无
  223. */
  224. int get_tick_count(unsigned long *count)
  225. {
  226. count[0] = HAL_GetTick();
  227. return 0;
  228. }
  229. #include "inv_mpu.h"
  230. #include "inv_mpu_dmp_motion_driver.h"
  231. /* Data requested by client. */
  232. #define PRINT_ACCEL (0x01)
  233. #define PRINT_GYRO (0x02)
  234. #define PRINT_QUAT (0x04)
  235. #define ACCEL_ON (0x01)
  236. #define GYRO_ON (0x02)
  237. #define MOTION (0)
  238. #define NO_MOTION (1)
  239. /* Starting sampling rate. */ //100
  240. #define DEFAULT_MPU_HZ (50)
  241. struct rx_s {
  242. unsigned char header[3];
  243. unsigned char cmd;
  244. };
  245. struct hal_s {
  246. unsigned char sensors;
  247. unsigned char dmp_on;
  248. unsigned char wait_for_tap;
  249. volatile unsigned char new_gyro;
  250. unsigned short report;
  251. unsigned short dmp_features;
  252. unsigned char motion_int_mode;
  253. struct rx_s rx;
  254. };
  255. static struct hal_s hal = {0};
  256. /* USB RX binary semaphore. Actually, it's just a flag. Not included in struct
  257. * because it's declared extern elsewhere.
  258. */
  259. volatile unsigned char rx_new;
  260. /* The sensors can be mounted onto the board in any orientation. The mounting
  261. * matrix seen below tells the MPL how to rotate the raw data from thei
  262. * driver(s).
  263. * TODO: The following matrices refer to the configuration on an internal test
  264. * board at Invensense. If needed, please modify the matrices to match the
  265. * chip-to-body matrix for your particular set up.
  266. */
  267. static signed char gyro_orientation[9] = {-1, 0, 0,
  268. 0,-1, 0,
  269. 0, 0, 1};
  270. /* Every time new gyro data is available, this function is called in an
  271. * ISR context. In this example, it sets a flag protecting the FIFO read
  272. * function.
  273. */
  274. static void gyro_data_ready_cb(void)
  275. {
  276. hal.new_gyro = 1;
  277. }
  278. enum packet_type_e {
  279. PACKET_TYPE_ACCEL,
  280. PACKET_TYPE_GYRO,
  281. PACKET_TYPE_QUAT,
  282. PACKET_TYPE_TAP,
  283. PACKET_TYPE_ANDROID_ORIENT,
  284. PACKET_TYPE_PEDO,
  285. PACKET_TYPE_MISC
  286. };
  287. #define BYTE u_char
  288. /* Send data to the Python client application.
  289. * Data is formatted as follows:
  290. * packet[0] = $
  291. * packet[1] = packet type (see packet_type_e)
  292. * packet[2+] = data
  293. */
  294. void send_packet(char packet_type, void *data)
  295. {
  296. #define MAX_BUF_LENGTH (18)
  297. char buf[MAX_BUF_LENGTH], length;
  298. memset(buf, 0, MAX_BUF_LENGTH);
  299. buf[0] = '$';
  300. buf[1] = packet_type;
  301. if (packet_type == PACKET_TYPE_ACCEL || packet_type == PACKET_TYPE_GYRO) {
  302. short *sdata = (short*)data;
  303. buf[2] = (char)(sdata[0] >> 8);
  304. buf[3] = (char)sdata[0];
  305. buf[4] = (char)(sdata[1] >> 8);
  306. buf[5] = (char)sdata[1];
  307. buf[6] = (char)(sdata[2] >> 8);
  308. buf[7] = (char)sdata[2];
  309. length = 8;
  310. } else if (packet_type == PACKET_TYPE_QUAT) {
  311. long *ldata = (long*)data;
  312. buf[2] = (char)(ldata[0] >> 24);
  313. buf[3] = (char)(ldata[0] >> 16);
  314. buf[4] = (char)(ldata[0] >> 8);
  315. buf[5] = (char)ldata[0];
  316. buf[6] = (char)(ldata[1] >> 24);
  317. buf[7] = (char)(ldata[1] >> 16);
  318. buf[8] = (char)(ldata[1] >> 8);
  319. buf[9] = (char)ldata[1];
  320. buf[10] = (char)(ldata[2] >> 24);
  321. buf[11] = (char)(ldata[2] >> 16);
  322. buf[12] = (char)(ldata[2] >> 8);
  323. buf[13] = (char)ldata[2];
  324. buf[14] = (char)(ldata[3] >> 24);
  325. buf[15] = (char)(ldata[3] >> 16);
  326. buf[16] = (char)(ldata[3] >> 8);
  327. buf[17] = (char)ldata[3];
  328. length = 18;
  329. } else if (packet_type == PACKET_TYPE_TAP) {
  330. buf[2] = ((char*)data)[0];
  331. buf[3] = ((char*)data)[1];
  332. length = 4;
  333. } else if (packet_type == PACKET_TYPE_ANDROID_ORIENT) {
  334. buf[2] = ((char*)data)[0];
  335. length = 3;
  336. } else if (packet_type == PACKET_TYPE_PEDO) {
  337. long *ldata = (long*)data;
  338. buf[2] = (char)(ldata[0] >> 24);
  339. buf[3] = (char)(ldata[0] >> 16);
  340. buf[4] = (char)(ldata[0] >> 8);
  341. buf[5] = (char)ldata[0];
  342. buf[6] = (char)(ldata[1] >> 24);
  343. buf[7] = (char)(ldata[1] >> 16);
  344. buf[8] = (char)(ldata[1] >> 8);
  345. buf[9] = (char)ldata[1];
  346. length = 10;
  347. } else if (packet_type == PACKET_TYPE_MISC) {
  348. buf[2] = ((char*)data)[0];
  349. buf[3] = ((char*)data)[1];
  350. buf[4] = ((char*)data)[2];
  351. buf[5] = ((char*)data)[3];
  352. length = 6;
  353. }
  354. // cdcSendDataWaitTilDone((BYTE*)buf, length, CDC0_INTFNUM, 100);
  355. }
  356. /* These next two functions converts the orientation matrix (see
  357. * gyro_orientation) to a scalar representation for use by the DMP.
  358. * NOTE: These functions are borrowed from Invensense's MPL.
  359. */
  360. static inline unsigned short inv_row_2_scale(const signed char *row)
  361. {
  362. unsigned short b;
  363. if (row[0] > 0)
  364. b = 0;
  365. else if (row[0] < 0)
  366. b = 4;
  367. else if (row[1] > 0)
  368. b = 1;
  369. else if (row[1] < 0)
  370. b = 5;
  371. else if (row[2] > 0)
  372. b = 2;
  373. else if (row[2] < 0)
  374. b = 6;
  375. else
  376. b = 7; // error
  377. return b;
  378. }
  379. static inline unsigned short inv_orientation_matrix_to_scalar(
  380. const signed char *mtx)
  381. {
  382. unsigned short scalar;
  383. /*
  384. XYZ 010_001_000 Identity Matrix
  385. XZY 001_010_000
  386. YXZ 010_000_001
  387. YZX 000_010_001
  388. ZXY 001_000_010
  389. ZYX 000_001_010
  390. */
  391. scalar = inv_row_2_scale(mtx);
  392. scalar |= inv_row_2_scale(mtx + 3) << 3;
  393. scalar |= inv_row_2_scale(mtx + 6) << 6;
  394. return scalar;
  395. }
  396. static inline void run_self_test(void)
  397. {
  398. int result;
  399. char test_packet[4] = {0};
  400. long gyro[3], accel[3];
  401. result = mpu_run_self_test(gyro, accel);
  402. if (result == 0x7) {
  403. /* Test passed. We can trust the gyro data here, so let's push it down
  404. * to the DMP.
  405. */
  406. float sens;
  407. unsigned short accel_sens;
  408. mpu_get_gyro_sens(&sens);
  409. gyro[0] = (long)(gyro[0] * sens);
  410. gyro[1] = (long)(gyro[1] * sens);
  411. gyro[2] = (long)(gyro[2] * sens);
  412. dmp_set_gyro_bias(gyro);
  413. mpu_get_accel_sens(&accel_sens);
  414. accel[0] *= accel_sens;
  415. accel[1] *= accel_sens;
  416. accel[2] *= accel_sens;
  417. dmp_set_accel_bias(accel);
  418. }
  419. /* Report results. */
  420. test_packet[0] = 't';
  421. test_packet[1] = result;
  422. send_packet(PACKET_TYPE_MISC, test_packet);
  423. }
  424. #define INT_EXIT_LPM0 12
  425. void DMP_Init(void)
  426. {
  427. struct int_param_s int_param;
  428. /* Set up gyro.
  429. * Every function preceded by mpu_ is a driver function and can be found
  430. * in inv_mpu.h.
  431. */
  432. int_param.cb = gyro_data_ready_cb;
  433. int_param.pin = 16;
  434. int_param.lp_exit = INT_EXIT_LPM0;
  435. int_param.active_low = 1;
  436. int result = mpu_init(&int_param);
  437. printf("mpu_init, %d\r\n", result);
  438. if(result == 0) //mpu初始化
  439. {
  440. if(!mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL)) //设置需要的传感器
  441. printf("mpu_set_sensor complete ......\r\n");
  442. if(!mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL)) //设置fifo
  443. printf("mpu_configure_fifo complete ......\r\n");
  444. if(!mpu_set_sample_rate(DEFAULT_MPU_HZ)) //设置采集样率
  445. printf("mpu_set_sample_rate complete ......\r\n");
  446. unsigned short gyro_rate = 0, gyro_fsr = 0;
  447. unsigned char accel_fsr = 0;
  448. mpu_get_sample_rate(&gyro_rate);
  449. mpu_get_gyro_fsr(&gyro_fsr);
  450. mpu_get_accel_fsr(&accel_fsr);
  451. printf("gyro_rate %d, gyro_fsr %d, accel_fsr %d\r\n", gyro_rate, gyro_fsr, accel_fsr);
  452. if(!dmp_load_motion_driver_firmware()) //加载dmp固件
  453. printf("dmp_load_motion_driver_firmware complete ......\r\n");
  454. if(!dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation)))
  455. printf("dmp_set_orientation complete ......\r\n"); //设置陀螺仪方向
  456. if(!dmp_enable_feature(DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_TAP |
  457. DMP_FEATURE_ANDROID_ORIENT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO |
  458. DMP_FEATURE_GYRO_CAL))
  459. printf("dmp_enable_feature complete ......\r\n");
  460. if(!dmp_set_fifo_rate(DEFAULT_MPU_HZ)) //设置速率
  461. printf("dmp_set_fifo_rate complete ......\r\n");
  462. run_self_test(); //自检(非必要)
  463. if(!mpu_set_dmp_state(1)) //使能
  464. printf("mpu_set_dmp_state complete ......\r\n");
  465. }
  466. }
  467. #define q30 1073741824.0
  468. uint8_t Read_DMP(float* Pitch,float* Roll,float* Yaw)
  469. {
  470. short gyro[3], accel[3], sensors;
  471. float q0=1.0f,q1=0.0f,q2=0.0f,q3=0.0f;
  472. unsigned long sensor_timestamp;
  473. unsigned char more;
  474. long quat[4];
  475. int ret = dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors, &more);
  476. // printf("dmp_read_fifo, %d\r\n", ret);
  477. if(ret)
  478. {
  479. return 1;
  480. }
  481. if (sensors & INV_WXYZ_QUAT)
  482. {
  483. q0=quat[0] / q30;
  484. q1=quat[1] / q30;
  485. q2=quat[2] / q30;
  486. q3=quat[3] / q30;
  487. *Pitch = (float)asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3;
  488. *Roll = (float)atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3; // roll
  489. *Yaw = (float)atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3;
  490. return 0;
  491. }
  492. else
  493. {
  494. return 2;
  495. }
  496. }