GD32VW553-IOT-V2 通过MPU6050获取当前传感器的偏移角度

[复制链接]
265|0
本文转载自iCEasy商城口碑评测作者:123ff
欢迎大家戳链接GD32VW553-IOT-V2 通过MPU6050获取当前传感器的偏移角度与原贴作者互动交流哦~
视频链接
https://b23.tv/ujKJTkb

前言
GD32VW553-IOT-V2焊引脚的时候最好换成直的,官方配的弯的太难用了。汉化:https://blog.csdn.net/qq_45762107/article/details/147348992(csdn找的



开源口碑分享内容
引脚定义:
GD32VW553-IOT-V2通过MPU6050六轴传感器获取当前传感器的偏移角度
  1. bsp_mpu6050.c


  2. #include "bsp_mpu6050.h"

  3. #include "stdio.h"



  4. /******************************************************************

  5. * 函 数 名 称:IIC_Start

  6. * 函 数 说 明:IIC起始时序

  7. * 函 数 形 参:无

  8. * 函 数 返 回:无

  9. * 作       者:LC

  10. * 备       注:无

  11. ******************************************************************/

  12. void IIC_Start(void)

  13. {

  14.        SDA_OUT();

  15.        SCL(1);

  16.        SDA(0);



  17.        SDA(1);

  18.        delay_us(5);

  19.        SDA(0);

  20.        delay_us(5);



  21.        SCL(0);

  22. }

  23. /******************************************************************

  24. * 函 数 名 称:IIC_Stop

  25. * 函 数 说 明:IIC停止信号

  26. * 函 数 形 参:无

  27. * 函 数 返 回:无

  28. * 作       者:LC

  29. * 备       注:无

  30. ******************************************************************/

  31. void IIC_Stop(void)

  32. {

  33.        SDA_OUT();

  34.        SCL(0);

  35.        SDA(0);



  36.        SCL(1);

  37.        delay_us(5);

  38.        SDA(1);

  39.        delay_us(5);



  40. }



  41. /******************************************************************

  42. * 函 数 名 称:IIC_Send_Ack

  43. * 函 数 说 明:主机发送应答或者非应答信号

  44. * 函 数 形 参:0发送应答  1发送非应答

  45. * 函 数 返 回:无

  46. * 作       者:LC

  47. * 备       注:无

  48. ******************************************************************/

  49. void IIC_Send_Ack(unsigned char ack)

  50. {

  51.        SDA_OUT();

  52.        SCL(0);

  53.        SDA(0);

  54.        delay_us(5);

  55.        if(!ack) SDA(0);

  56.        else     SDA(1);

  57.        SCL(1);

  58.        delay_us(5);

  59.        SCL(0);

  60.        SDA(1);

  61. }





  62. /******************************************************************

  63. * 函 数 名 称:I2C_WaitAck

  64. * 函 数 说 明:等待从机应答

  65. * 函 数 形 参:无

  66. * 函 数 返 回:0有应答  1超时无应答

  67. * 作       者:LC

  68. * 备       注:无

  69. ******************************************************************/

  70. unsigned char I2C_WaitAck(void)

  71. {



  72.        char ack = 0;

  73.        unsigned char ack_flag = 10;

  74.        SCL(0);

  75.        SDA(1);

  76.        SDA_IN();



  77.        SCL(1);

  78.        while( (SDA_GET()==1) && ( ack_flag ) )

  79.        {

  80.                ack_flag--;

  81.                delay_us(5);

  82.        }



  83.        if( ack_flag <= 0 )

  84.        {

  85.                IIC_Stop();

  86.                return 1;

  87.        }

  88.        else

  89.        {

  90.                SCL(0);

  91.                SDA_OUT();

  92.        }

  93.        return ack;

  94. }



  95. /******************************************************************

  96. * 函 数 名 称:Send_Byte

  97. * 函 数 说 明:写入一个字节

  98. * 函 数 形 参:dat要写人的数据

  99. * 函 数 返 回:无

  100. * 作       者:LC

  101. * 备       注:无

  102. ******************************************************************/

  103. void Send_Byte(uint8_t dat)

  104. {

  105.        int i = 0;

  106.        SDA_OUT();

  107.        SCL(0);//拉低时钟开始数据传输



  108.        for( i = 0; i < 8; i++ )

  109.        {

  110.                SDA( (dat & 0x80) >> 7 );

  111.                delay_us(1);

  112.                SCL(1);

  113.                delay_us(5);

  114.                SCL(0);

  115.                delay_us(5);

  116.                dat<<=1;

  117.        }

  118. }



  119. /******************************************************************

  120. * 函 数 名 称:Read_Byte

  121. * 函 数 说 明:IIC读时序

  122. * 函 数 形 参:无

  123. * 函 数 返 回:读到的数据

  124. * 作       者:LC

  125. * 备       注:无

  126. ******************************************************************/

  127. unsigned char Read_Byte(void)

  128. {

  129.    unsigned char i,receive=0;

  130.    SDA_IN();//SDA设置为输入

  131.    for(i=0;i<8;i++ )

  132.    {

  133.        SCL(0);

  134.        delay_us(5);

  135.        SCL(1);

  136.        delay_us(5);

  137.        receive<<=1;

  138.        if( SDA_GET() )

  139.        {

  140.            receive|=1;

  141.        }

  142.        delay_us(5);

  143.    }



  144.    SCL(0);



  145.    return receive;

  146. }



  147. /******************************************************************

  148. * 函 数 名 称:MPU6050_WriteReg

  149. * 函 数 说 明:IIC连续写入数据

  150. * 函 数 形 参:addr器件地址 regaddr寄存器地址 num要写入的长度 regdata写入的数据地址

  151. * 函 数 返 回:0=读取成功   其他=读取失败

  152. * 作       者:LC

  153. * 备       注:无

  154. ******************************************************************/

  155. char MPU6050_WriteReg(uint8_t addr,uint8_t regaddr,uint8_t num,uint8_t *regdata)

  156. {

  157.    uint16_t i = 0;

  158.    IIC_Start();

  159.    Send_Byte((addr<<1)|0);

  160.    if( I2C_WaitAck() == 1 ) {IIC_Stop();return 1;}

  161.    Send_Byte(regaddr);

  162.    if( I2C_WaitAck() == 1 ) {IIC_Stop();return 2;}



  163.    for(i=0;i<num;i++)

  164.    {

  165.        Send_Byte(regdata[i]);

  166.        if( I2C_WaitAck() == 1 ) {IIC_Stop();return (3+i);}

  167.    }



  168.    IIC_Stop();

  169.    return 0;

  170. }





  171. /******************************************************************

  172. * 函 数 名 称:MPU6050_ReadData

  173. * 函 数 说 明:IIC连续读取数据

  174. * 函 数 形 参:addr器件地址 regaddr寄存器地址 num要读取的长度 Read读取到的数据要存储的地址

  175. * 函 数 返 回:0=读取成功   其他=读取失败

  176. * 作       者:LC

  177. * 备       注:无

  178. ******************************************************************/

  179. char MPU6050_ReadData(uint8_t addr, uint8_t regaddr,uint8_t num,uint8_t* Read)

  180. {

  181.        uint8_t i;

  182.        IIC_Start();

  183.        Send_Byte((addr<<1)|0);

  184.        if( I2C_WaitAck() == 1 ) {IIC_Stop();return 1;}

  185.        Send_Byte(regaddr);

  186.        if( I2C_WaitAck() == 1 ) {IIC_Stop();return 2;}



  187.        IIC_Start();

  188.        Send_Byte((addr<<1)|1);

  189.        if( I2C_WaitAck() == 1 ) {IIC_Stop();return 3;}



  190.        for(i=0;i<(num-1);i++){

  191.                Read[i]=Read_Byte();

  192.                IIC_Send_Ack(0);

  193.        }

  194.        Read[i]=Read_Byte();

  195.        IIC_Send_Ack(1);

  196.        IIC_Stop();

  197.        return 0;

  198. }





  199. /******************************************************************

  200. * 函 数 名 称:MPU_Set_Gyro_Fsr

  201. * 函 数 说 明:设置MPU6050陀螺仪传感器满量程范围

  202. * 函 数 形 参:fsr:0,±250dps;1,±500dps;2,±1000dps;3,±2000dps

  203. * 函 数 返 回:0,设置成功  其他,设置失败

  204. * 作       者:LC

  205. * 备       注:无

  206. ******************************************************************/

  207. uint8_t MPU_Set_Gyro_Fsr(uint8_t fsr)

  208. {

  209.        return MPU6050_WriteReg(0x68,MPU_GYRO_CFG_REG,1,(uint8_t*)(fsr<<3)); //设置陀螺仪满量程范围

  210. }



  211. /******************************************************************

  212. * 函 数 名 称:MPU_Set_Accel_Fsr

  213. * 函 数 说 明:设置MPU6050加速度传感器满量程范围

  214. * 函 数 形 参:fsr:0,±2g;1,±4g;2,±8g;3,±16g

  215. * 函 数 返 回:0,设置成功  其他,设置失败

  216. * 作       者:LC

  217. * 备       注:无

  218. ******************************************************************/

  219. uint8_t MPU_Set_Accel_Fsr(uint8_t fsr)

  220. {

  221.        return MPU6050_WriteReg(0x68,MPU_ACCEL_CFG_REG,1,(uint8_t*)(fsr<<3)); //设置加速度传感器满量程范围

  222. }



  223. /******************************************************************

  224. * 函 数 名 称:MPU_Set_LPF

  225. * 函 数 说 明:设置MPU6050的数字低通滤波器

  226. * 函 数 形 参:lpf:数字低通滤波频率(Hz)

  227. * 函 数 返 回:0,设置成功  其他,设置失败

  228. * 作       者:LC

  229. * 备       注:无

  230. ******************************************************************/

  231. uint8_t MPU_Set_LPF(uint16_t lpf)

  232. {

  233.      uint8_t data=0;



  234.      if(lpf>=188)data=1;

  235.      else if(lpf>=98)data=2;

  236.      else if(lpf>=42)data=3;

  237.      else if(lpf>=20)data=4;

  238.      else if(lpf>=10)data=5;

  239.      else data=6;

  240.      return data=MPU6050_WriteReg(0x68,MPU_CFG_REG,1,&data);//设置数字低通滤波器

  241. }

  242. /******************************************************************

  243. * 函 数 名 称:MPU_Set_Rate

  244. * 函 数 说 明:设置MPU6050的采样率(假定Fs=1KHz)

  245. * 函 数 形 参:rate:4~1000(Hz)  初始化中rate取50

  246. * 函 数 返 回:0,设置成功  其他,设置失败

  247. * 作       者:LC

  248. * 备       注:无

  249. ******************************************************************/

  250. uint8_t MPU_Set_Rate(uint16_t rate)

  251. {

  252.        uint8_t data;

  253.        if(rate>1000)rate=1000;

  254.        if(rate<4)rate=4;

  255.        data=1000/rate-1;

  256.        data=MPU6050_WriteReg(0x68,MPU_SAMPLE_RATE_REG,1,&data);        //设置数字低通滤波器

  257.        return MPU_Set_LPF(rate/2);            //自动设置LPF为采样率的一半

  258. }





  259. /******************************************************************

  260. * 函 数 名 称:MPU6050ReadGyro

  261. * 函 数 说 明:读取陀螺仪数据

  262. * 函 数 形 参:陀螺仪数据存储地址

  263. * 函 数 返 回:无

  264. * 作       者:LC

  265. * 备       注:无

  266. ******************************************************************/

  267. void MPU6050ReadGyro(short *gyroData)

  268. {

  269.        uint8_t buf[6];

  270.        uint8_t reg = 0;

  271.        //MPU6050_GYRO_OUT = MPU6050陀螺仪数据寄存器地址

  272.        //陀螺仪数据输出寄存器总共由6个寄存器组成,

  273.        //输出X/Y/Z三个轴的陀螺仪传感器数据,高字节在前,低字节在后。

  274.        //每一个轴16位,按顺序为xyz

  275.        reg = MPU6050_ReadData(0x68,MPU6050_GYRO_OUT,6,buf);

  276.        if( reg == 0 )

  277.        {

  278.                gyroData[0] = (buf[0] << 8) | buf[1];

  279.                gyroData[1] = (buf[2] << 8) | buf[3];

  280.                gyroData[2] = (buf[4] << 8) | buf[5];

  281.        }

  282. }



  283. /******************************************************************

  284. * 函 数 名 称:MPU6050ReadAcc

  285. * 函 数 说 明:读取加速度数据

  286. * 函 数 形 参:加速度数据存储地址

  287. * 函 数 返 回:无

  288. * 作       者:LC

  289. * 备       注:无

  290. ******************************************************************/

  291. void MPU6050ReadAcc(short *accData)

  292. {

  293.        uint8_t buf[6];

  294.        uint8_t reg = 0;

  295.        //MPU6050_ACC_OUT = MPU6050加速度数据寄存器地址

  296.        //加速度传感器数据输出寄存器总共由6个寄存器组成,

  297.        //输出X/Y/Z三个轴的加速度传感器值,高字节在前,低字节在后。

  298.        reg = MPU6050_ReadData(0x68, MPU6050_ACC_OUT, 6, buf);

  299.        if( reg == 0)

  300.        {

  301.                accData[0] = (buf[0] << 8) | buf[1];

  302.                accData[1] = (buf[2] << 8) | buf[3];

  303.                accData[2] = (buf[4] << 8) | buf[5];

  304.        }

  305. }



  306. /******************************************************************

  307. * 函 数 名 称:MPU6050_GetTemp

  308. * 函 数 说 明:读取MPU6050上的温度

  309. * 函 数 形 参:无

  310. * 函 数 返 回:温度值单位为℃

  311. * 作       者:LC

  312. * 备       注:温度换算公式为:Temperature = 36.53 + regval/340

  313. ******************************************************************/

  314. float MPU6050_GetTemp(void)

  315. {

  316.    short temp3;

  317.    uint8_t buf[2];

  318.    float Temperature = 0;

  319.    MPU6050_ReadData(0x68,MPU6050_RA_TEMP_OUT_H,2,buf);

  320.    temp3= (buf[0] << 8) | buf[1];

  321.    Temperature=((double) temp3/340.0)+36.53;

  322.    return Temperature;

  323. }



  324. /******************************************************************

  325. * 函 数 名 称:MPU6050ReadID

  326. * 函 数 说 明:读取MPU6050的器件地址

  327. * 函 数 形 参:无

  328. * 函 数 返 回:0=检测不到MPU6050   1=能检测到MPU6050

  329. * 作       者:LC

  330. * 备       注:无

  331. ******************************************************************/

  332. uint8_t MPU6050ReadID(void)

  333. {

  334.        unsigned char Re[2] = {0};

  335.        //器件ID寄存器 = 0x75

  336.        printf("mpu=%d\r\n",MPU6050_ReadData(0x68,0X75,1,Re)); //读器件地址



  337.        if (Re[0] != 0x68)

  338.        {

  339.                printf("There is no detection of MPU6050 !!!!");

  340.                return 1;

  341.        }

  342.        else

  343.        {

  344.                printf("MPU6050 ID = %x\r\n",Re[0]);

  345.                return 0;

  346.        }

  347. }



  348. /******************************************************************

  349. * 函 数 名 称:MPU6050_Init

  350. * 函 数 说 明:MPU6050初始化

  351. * 函 数 形 参:无

  352. * 函 数 返 回:0成功  1没有检测到MPU6050

  353. * 作       者:LC

  354. * 备       注:无

  355. ******************************************************************/

  356. char MPU6050_Init(void)

  357. {

  358.    Module_RCU_ENABLE();



  359.    //SCL引脚初始化

  360.    gpio_mode_set(Module_SCL_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, Module_SCL_PIN);

  361.    gpio_output_options_set(Module_SCL_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_25MHZ, Module_SCL_PIN);



  362. //SDA引脚初始化

  363. gpio_mode_set(Module_SDA_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, Module_SDA_PIN);

  364. gpio_output_options_set(Module_SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_25MHZ, Module_SDA_PIN);



  365.    SCL(1);

  366.    SDA(1);



  367.    delay_ms(100); // 等待传感器稳定



  368.    //复位6050

  369.    MPU6050_WriteReg(0x68,MPU6050_RA_PWR_MGMT_1, 1,(uint8_t*)(0x80));

  370.    delay_ms(100);

  371.    //电源管理寄存器

  372.    //选择X轴陀螺作为参考PLL的时钟源,设置CLKSEL=001

  373.    MPU6050_WriteReg(0x68,MPU6050_RA_PWR_MGMT_1,1, (uint8_t*)(0x00));



  374.    MPU_Set_Gyro_Fsr(3);    //陀螺仪传感器,±2000dps

  375.    MPU_Set_Accel_Fsr(0);   //加速度传感器,±2g

  376.    MPU_Set_Rate(50);



  377.    MPU6050_WriteReg(0x68,MPU_INT_EN_REG , 1,(uint8_t*)0x00);        //关闭所有中断

  378.    MPU6050_WriteReg(0x68,MPU_USER_CTRL_REG,1,(uint8_t*)0x00);       //I2C主模式关闭

  379.    MPU6050_WriteReg(0x68,MPU_FIFO_EN_REG,1,(uint8_t*)0x00);         //关闭FIFO

  380.    MPU6050_WriteReg(0x68,MPU_INTBP_CFG_REG,1,(uint8_t*)0X80);       //INT引脚低电平有效



  381.    if( !MPU6050ReadID() )//检查是否有6050

  382.    {

  383.        MPU6050_WriteReg(0x68,MPU6050_RA_PWR_MGMT_1, 1,(uint8_t*)0x01);//设置CLKSEL,PLL X轴为参考

  384.        MPU6050_WriteReg(0x68,MPU_PWR_MGMT2_REG, 1,(uint8_t*)0x00);//加速度与陀螺仪都工作

  385.        MPU_Set_Rate(50);

  386.        return 0;

  387.    }

  388.    // 出错

  389.    return 1;

  390. }



  391. bsp_mpu6050.h


  392. #ifndef BSP_CODE_BSP_MPU6050_H_

  393. #define BSP_CODE_BSP_MPU6050_H_



  394. #include "gd32vw55x.h"

  395. #include "systick.h"

  396. #include "inv_mpu.h" // 操作MPU

  397. #include "inv_mpu_dmp_motion_driver.h" // 操作DMP

  398. #include "math.h"



  399. #ifndef u8

  400. #define u8 uint8_t

  401. #endif



  402. #ifndef u16

  403. #define u16 uint16_t

  404. #endif



  405. #ifndef u32

  406. #define u32 uint32_t

  407. #endif



  408. #ifndef delay_ms

  409. #define delay_ms(x) delay_1ms(x)

  410. #endif



  411. #ifndef delay_us

  412. #define delay_us(x) delay_1us(x)

  413. #endif



  414. #define Module_RCU_ENABLE() \

  415. rcu_periph_clock_enable(Module_SCL_RCU); \

  416. rcu_periph_clock_enable(Module_SDA_RCU);



  417. #define Module_SCL_RCU RCU_GPIOA

  418. #define Module_SCL_PORT GPIOA

  419. #define Module_SCL_PIN GPIO_PIN_2 //SCL



  420. #define Module_SDA_RCU RCU_GPIOA

  421. #define Module_SDA_PORT GPIOA

  422. #define Module_SDA_PIN GPIO_PIN_3 //SDA



  423. //SDA输入模式

  424. #define SDA_IN() \

  425. gpio_mode_set(Module_SDA_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, Module_SDA_PIN);



  426. //SDA输出模式

  427. #define SDA_OUT() \

  428. gpio_mode_set(Module_SDA_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, Module_SDA_PIN); \

  429. gpio_output_options_set(Module_SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_25MHZ, Module_SDA_PIN);



  430. #define SCL(BIT) gpio_bit_write(Module_SCL_PORT, Module_SCL_PIN, BIT)

  431. #define SDA(BIT) gpio_bit_write(Module_SDA_PORT, Module_SDA_PIN, BIT)

  432. #define SDA_GET() gpio_input_bit_get(Module_SDA_PORT, Module_SDA_PIN)





  433. //MPU6050的AD0是IIC地址引脚,接地则IIC地址为0x68,接VCC则IIC地址为0x69

  434. #define MPU6050_RA_SMPLRT_DIV 0x19 //陀螺仪采样率 地址

  435. #define MPU6050_RA_CONFIG 0x1A //设置数字低通滤波器 地址

  436. #define MPU6050_RA_GYRO_CONFIG 0x1B //陀螺仪配置寄存器

  437. #define MPU6050_RA_ACCEL_CONFIG 0x1C //加速度传感器配置寄存器

  438. #define MPU_INT_EN_REG 0X38 //中断使能寄存器

  439. #define MPU_USER_CTRL_REG 0X6A //用户控制寄存器

  440. #define MPU_FIFO_EN_REG 0X23 //FIFO使能寄存器

  441. #define MPU_PWR_MGMT2_REG 0X6C //电源管理寄存器2

  442. #define MPU_GYRO_CFG_REG 0X1B //陀螺仪配置寄存器

  443. #define MPU_ACCEL_CFG_REG 0X1C //加速度计配置寄存器

  444. #define MPU_CFG_REG 0X1A //配置寄存器

  445. #define MPU_SAMPLE_RATE_REG 0X19 //采样频率分频器

  446. #define MPU_INTBP_CFG_REG 0X37 //中断/旁路设置寄存器



  447. #define MPU6050_RA_PWR_MGMT_1 0x6B

  448. #define MPU6050_RA_PWR_MGMT_2 0x6C



  449. #define MPU6050_WHO_AM_I 0x75

  450. #define MPU6050_SMPLRT_DIV 0 //8000Hz

  451. #define MPU6050_DLPF_CFG 0

  452. #define MPU6050_GYRO_OUT 0x43 //MPU6050陀螺仪数据寄存器地址

  453. #define MPU6050_ACC_OUT 0x3B //MPU6050加速度数据寄存器地址



  454. #define MPU6050_RA_TEMP_OUT_H 0x41 //温度高位

  455. #define MPU6050_RA_TEMP_OUT_L 0x42 //温度低位



  456. #define MPU_ACCEL_XOUTH_REG 0X3B //加速度值,X轴高8位寄存器

  457. #define MPU_ACCEL_XOUTL_REG 0X3C //加速度值,X轴低8位寄存器

  458. #define MPU_ACCEL_YOUTH_REG 0X3D //加速度值,Y轴高8位寄存器

  459. #define MPU_ACCEL_YOUTL_REG 0X3E //加速度值,Y轴低8位寄存器

  460. #define MPU_ACCEL_ZOUTH_REG 0X3F //加速度值,Z轴高8位寄存器

  461. #define MPU_ACCEL_ZOUTL_REG 0X40 //加速度值,Z轴低8位寄存器



  462. #define MPU_TEMP_OUTH_REG 0X41 //温度值高八位寄存器

  463. #define MPU_TEMP_OUTL_REG 0X42 //温度值低8位寄存器



  464. #define MPU_GYRO_XOUTH_REG 0X43 //陀螺仪值,X轴高8位寄存器

  465. #define MPU_GYRO_XOUTL_REG 0X44 //陀螺仪值,X轴低8位寄存器

  466. #define MPU_GYRO_YOUTH_REG 0X45 //陀螺仪值,Y轴高8位寄存器

  467. #define MPU_GYRO_YOUTL_REG 0X46 //陀螺仪值,Y轴低8位寄存器

  468. #define MPU_GYRO_ZOUTH_REG 0X47 //陀螺仪值,Z轴高8位寄存器

  469. #define MPU_GYRO_ZOUTL_REG 0X48 //陀螺仪值,Z轴低8位寄存器



  470. char MPU6050_Init(void);

  471. void MPU6050ReadGyro(short *gyroData);

  472. void MPU6050ReadAcc(short *accData);

  473. float MPU6050_GetTemp(void);

  474. uint8_t MPU6050ReadID(void);



  475. #endif /* BSP_CODE_BSP_MPU6050_H_ */
结果演示







您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

11

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部