14

zhai · 2021年12月27日

XR806开发板驱动6轴MPU6050 陀螺仪+加速度计及数据上传至上位机

一.开发环境
(1)ubuntu16.04虚拟机
(2)MPU6050陀螺仪
(3)匿名上位机
二.软件
(1).I2C引脚
使用Xr806硬件I2C,需要在文件夹找到“/home/a/xr806_openharmony/device/xradio/xr806/xr_skylark/project/common/board/xr806_OHOS/borad_config.c"板级配置文件,可以看到共有两个I2C端口可用,i2c0和i2c1,这里是使用i2c0,引脚为A12,A13,复用通道F9。找好端口号,插上MPU6050。
image.png
(2).12C协议
鸿蒙已自带多种I2C协议,MPU6050需要写寄存器地址,必须选用能写HAL_I2C_Master_Transmit_Mem_IT()函数,写寄存器大小设为8位,但是连续写协议,发送数据长度设为1。
(3).上位机协议

1:在调试过程中可以将某些标志位、寄存器、变量实时发回上位机,并在DEBUG页面显示。
2:通讯格式为:0x88 + 0xAD + len + num + DATA + SUM,  len为num与DATA的总长度,num表示要改变哪个显示
      状态,例如num=0x01即是要改变第一个LED,num=0x07即是改变第一个数字输出显示。当要改变LED时,
      DATA只需一字节,DATA=0x00表示关闭LED,大于0x00表示点亮LED;当要改变数字输出时,DATA需要两字
节,
      表示 一个uint16数字,高字节在前。SUM为从0x88开始到SUM前一字节的和校验,uint8格式。
      例如:发送 0x88 + 0xAD + 0x02 + 0x01 + 0x01 + 0x39    表示点亮第一个LED
                  发送 0x88 + 0xAD + 0x03 + 0x07 + 0x00 + 0x05 + 0x44   表示在第一个数字输出位置显示 5 。

3.源码



#include <stdio.h>
#include "ohos_init.h"
#include "kernel/os/os.h"
#include "/home/zfy/xr806_openharmony/base/iot_hardware/peripheral/interfaces/kits/iot_gpio.h"                                                           //(8)
#include "driver/chip/hal_i2c.h"
static OS_Thread_t g_main_thread,g_main_thread2;


#define GPIO_ID_PA21 21

#define I2C_SPEED (200000)




#define    SMPLRT_DIV        0x19    
#define    CONFIG            0x1A    
#define    GYRO_CONFIG        0x1B    
#define    ACCEL_CONFIG    0x1C    
#define    ACCEL_XOUT_H    0x3B
#define    ACCEL_XOUT_L    0x3C
#define    ACCEL_YOUT_H    0x3D
#define    ACCEL_YOUT_L    0x3E
#define    ACCEL_ZOUT_H    0x3F
#define    ACCEL_ZOUT_L    0x40
#define    TEMP_OUT_H        0x41
#define    TEMP_OUT_L        0x42
#define    GYRO_XOUT_H        0x43
#define    GYRO_XOUT_L        0x44    
#define    GYRO_YOUT_H        0x45
#define    GYRO_YOUT_L        0x46
#define    GYRO_ZOUT_H        0x47
#define    GYRO_ZOUT_L        0x48
#define    PWR_MGMT_1        0x6B    
#define    WHO_AM_I            0x75    
#define    SlaveAddress    0x68    

unsigned int i2c_id = 0;

void mpu6050_send_data(short aacx,short aacy,short aacz,short gyrox,short gyroy,short gyroz,short p,short r,short y)
{
     char str_buff[5];
     
     
     unsigned char head_buff[]={0x88,0xAF,0x1C};
     unsigned char end_buff[]={0x00,0x00,0x00,0x00};
     unsigned char check_sum[1]={0};
     unsigned char data[24];
     check_sum[0]+=0x88+0xAF+0x1C;
     
     data[0]=aacx>>8&0xFF;
     data[1]=aacx&0xFF;
     data[2]=aacy>>8&0xFF;
     data[3]=aacy&0xFF;
     data[4]=aacz>>8&0xFF;
     data[5]=aacz&0xFF;
     
     
     data[6]=gyrox>>8&0xFF;
     data[7]=gyrox&0xFF;
     data[8]=gyroy>>8&0xFF;
     data[9]=gyroy&0xFF;
     data[10]=gyroz>>8&0xFF;
     data[11]=gyroz&0xFF;
     
     data[12]=0;
     data[13]=0;
     data[14]=0;
     data[15]=0;
     data[16]=0;
     data[17]=0;
     
     
     data[18]=r>>8&0xFF;
     data[19]=r&0xFF;
     data[20]=p>>8&0xFF;
     data[21]=p;
     data[22]=y>>8&0xFF;
     data[23]=y&0xFF;
     
     
     int i=0;
     for(i=0;i<24;i++){
     check_sum[0]+=data[i]; 
     } 

    //  printf("%s",head_buff);
    //  printf("%s",data);
    //  printf("%s",end_buff);
    //  printf("%s",check_sum);

    for(int i=0;i<3;i++){ printf("%c",head_buff[i]);}
    for(int i=0;i<24;i++){ printf("%c",data[i]);}
    for(int i=0;i<4;i++){ printf("%c",end_buff[i]);}
    for(int i=0;i<1;i++){ printf("%c",check_sum[i]);}


    
    //uart_send_str(data,24);
    
     
}    

short Acc[3],Gyro[3];

void GetData(unsigned char REG_Address,short data[3])
{
    unsigned char H[1]={0},L[1]={0};
    
    //HAL_I2C_Master_Receive_Mem_IT(i2c_id, SlaveAddress, REG_Address+1, I2C_MEMADDR_SIZE_16BIT, L, 1);
    //return ((int)(H[0]<<8)+L[0]);
    for(int i=0;i<3;i++){
        HAL_I2C_Master_Receive_Mem_IT(i2c_id, SlaveAddress, REG_Address+(i*2), I2C_MEMADDR_SIZE_8BIT, H, 1);
        HAL_I2C_Master_Receive_Mem_IT(i2c_id, SlaveAddress, REG_Address+(i*2+1), I2C_MEMADDR_SIZE_8BIT, L, 1);
      
       data[i]=(( short)(H[0]<<8))|L[0];
    }

}




static void MainThread2(void *arg)                                               
{
  printf("LED test start\r\n");
  IoTGpioInit(GPIO_ID_PA21);                                                   
  IoTGpioSetDir(GPIO_ID_PA21, IOT_GPIO_DIR_OUT);   



    
    IoTI2cInit(i2c_id,I2C_SPEED);
    const unsigned char data[]={0x00};
    const unsigned char data1[]={0x07};
    const unsigned char data2[]={0x06};
    const unsigned char data3[]={0x18};
    const unsigned char data4[]={0x01};

    printf("i2c test start\r\n");
    int a=HAL_I2C_Master_Transmit_Mem_IT(i2c_id, SlaveAddress, PWR_MGMT_1, I2C_MEMADDR_SIZE_8BIT, data, 1);
    HAL_I2C_Master_Transmit_Mem_IT(i2c_id, SlaveAddress, PWR_MGMT_1, I2C_MEMADDR_SIZE_8BIT, data1, 1);
    OS_MSleep(1);
    HAL_I2C_Master_Transmit_Mem_IT(i2c_id, SlaveAddress, SMPLRT_DIV, I2C_MEMADDR_SIZE_8BIT, data2, 1);
    OS_MSleep(1);
    HAL_I2C_Master_Transmit_Mem_IT(i2c_id, SlaveAddress, GYRO_CONFIG, I2C_MEMADDR_SIZE_8BIT, data3, 1);
    OS_MSleep(1);
    HAL_I2C_Master_Transmit_Mem_IT(i2c_id, SlaveAddress, ACCEL_CONFIG, I2C_MEMADDR_SIZE_8BIT, data4, 1);
    OS_MSleep(1);


  while (1) {
        IoTGpioSetOutputVal(GPIO_ID_PA21, 1); 
        OS_MSleep(10);
        IoTGpioSetOutputVal(GPIO_ID_PA21, 0);    
        OS_MSleep(10);  
        GetData(ACCEL_XOUT_H,Acc);
        GetData(GYRO_XOUT_H,Gyro);
        GetData(GYRO_XOUT_H,Gyro);
        mpu6050_send_data(Acc[0],Acc[1],Acc[2],Gyro[0],Gyro[1],Gyro[2],0,0,0);

        
                                    
  }
  
}
void LEDMain(void)                                                            
{
  printf("LED Test Start\n");


 if (OS_ThreadCreate(&g_main_thread2, "MainThread2", MainThread2, NULL,
                OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK) {
        printf("[ERR] Create MainThread Failed\n");
    }
}








static void MainThread(void *arg)
{int i=0;

    while (1) {
        printf("hello world:%d\n",i);
        LOS_Msleep(1000);
        
        i++;
    }
}

void HelloTestMain(void)
{
    printf("Wifi Test Start\n");

    if (OS_ThreadCreate(&g_main_thread, "MainThread", MainThread, NULL,
                OS_THREAD_PRIO_APP, 4 * 1024) != OS_OK) {
        printf("[ERR] Create MainThread Failed\n");
    }
}



//SYS_RUN(HelloTestMain);
SYS_RUN(LEDMain);

三、效果
IMG_20211226_230612.jpg
xr806视频演示

推荐阅读
关注数
13823
内容数
139
全志XR806开发板相关的知识介绍以及应用专栏。
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息