一.开发环境
(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。
(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"
#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];
}
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]);}
}
short Acc[3],Gyro[3];
void GetData(unsigned char REG_Address,short data[3])
{
unsigned char H[1]={0},L[1]={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(LEDMain);
原作者:zhai