久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2323|回復: 1
收起左側

mpu6050 DMP算法基于stm32

[復制鏈接]
ID:272602 發(fā)表于 2019-6-2 11:32 | 顯示全部樓層 |閱讀模式
發(fā)一個基于stm32F103的MPU6050 dma算法。詳情請下載。iar文件。共同學習。
#include "include.h"
static signed char gyro_orientation[9] = {-1, 0, 0,
                                           0,-1, 0,
                                           0, 0, 1};
float q0=1.0f,q1=0.0f,q2=0.0f,q3=0.0f;
float Pitch,Roll,Yaw;
unsigned long sensor_timestamp;
short gyro[3], accel[3], sensors;
unsigned char more;
long quat[4];

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//下面四個函數(shù)對接dmp庫


//addr:器件slave_address
//reg :從器件將要寫入數(shù)據(jù)的首地址
//len :寫入數(shù)據(jù)的長度
//data:將要寫入的一串數(shù)據(jù)          
u8 I2C_Write_Buffer(u8 addr, u8 reg, u8 len, u8 * data)
{
    int i;
    I2C_Start();
    I2C_Send_Byte(addr << 1 | 0);//7位器件從地址+讀寫位
    if (I2C_Wait_Ack())
        {
        I2C_Stop();
        return 0;
    }
    I2C_Send_Byte(reg);
    I2C_Wait_Ack();
    for (i = 0; i < len; i++)
        {
        I2C_Send_Byte(*data);
        if (I2C_Wait_Ack())
                {
            I2C_Stop();
            return 0;
        }
                data++;
    }
    I2C_Stop();
    return 1;
}



//addr:器件slave_address
//reg :從器件將要讀的數(shù)據(jù)的首地址
//len :讀出數(shù)據(jù)的長度
//buf :將要讀出的數(shù)據(jù)存儲位置
u8 I2C_Read_Buffer(u8 addr, u8 reg, u8 len, u8* buf)
{
    I2C_Start();
    I2C_Send_Byte(addr << 1 | 0);
    if (I2C_Wait_Ack())
        {
        I2C_Stop();
        return 0;
    }
    I2C_Send_Byte(reg);
    I2C_Wait_Ack();

    I2C_Start();
    I2C_Send_Byte(addr << 1 | 1);
    I2C_Wait_Ack();
    while (len)
        {
        *buf = I2C_Read_Byte();
        if (len == 1)
            I2C_NAck();
        else
            I2C_Ack();
        buf++;
        len--;
    }
    I2C_Stop();
    return 1;
}

//返回值 0:讀成功
//                -1:讀失敗
int I2C_Read(u8 addr, u8 reg, u8 len, u8 *buf)
{
        if(I2C_Read_Buffer(addr,reg,len,buf))
                return 0;
        else
                return -1;
}
//返回值 0:寫成功
//                -1:寫失敗
int I2C_Write(u8 addr, u8 reg, u8 len, u8* data)
{
        if(I2C_Write_Buffer(addr,reg,len,data))
                return 0;
        else
                return -1;
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



void MPU6050_Init(void)
{
        int result=0;
        I2C_Init_IO();
        result=mpu_init();
        if(!result)
        {                          
                if(!mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL))                //mpu_set_sensor
                if(!mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL))        //mpu_configure_fifo
                if(!mpu_set_sample_rate(DEFAULT_MPU_HZ))                                     //mpu_set_sample_rate
                if(!dmp_load_motion_driver_firmware())                                     //dmp_load_motion_driver_firmvare
                if(!dmp_set_orientation(inv_orientation_matrix_to_scalar(gyro_orientation)))           //dmp_set_orientation
                if(!dmp_enable_feature(DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_TAP |
                    DMP_FEATURE_ANDROID_ORIENT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO |
                    DMP_FEATURE_GYRO_CAL))                                                                     //dmp_enable_feature
                if(!dmp_set_fifo_rate(DEFAULT_MPU_HZ))                                     //dmp_set_fifo_rate
                run_self_test();                //??
                if(!mpu_set_dmp_state(1));
        }
}


void MPU6050_Pose(void)
{
        dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors,&more);         
        if(sensors & INV_WXYZ_QUAT )
        {
                q0 = quat[0] / q30;       
                q1 = quat[1] / q30;
                q2 = quat[2] / q30;
                q3 = quat[3] / q30;

                Pitch = asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3;        // pitch
                Roll  = atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3;        // roll
                Yaw   = atan2(2*(q1*q2 + q0*q3),q0*q0+q1*q1-q2*q2-q3*q3) * 57.3;        //yaw
        }
}
//通用定時器中斷初始化
//這里時鐘選擇為APB1的2倍,而APB1為36M
//arr:自動重裝值。
//psc:時鐘預分頻數(shù)
//這里使用的是定時器2!
void Timer2_Init(u16 arr,u16 psc)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //時鐘使能

        TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值         計數(shù)到5000為500ms
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作為TIMx時鐘頻率除數(shù)的預分頻值  10Khz的計數(shù)頻率  
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鐘分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上計數(shù)模式
        TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時間基數(shù)單位

        TIM_ITConfig(TIM2,TIM_IT_Update ,ENABLE );//使能或者失能指定的TIM2中斷
        NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;  //TIM3中斷
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;  //先占優(yōu)先級1級
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //從優(yōu)先級3級
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根據(jù)NVIC_InitStruct中指定的參數(shù)初始化外設NVIC寄存器

        TIM_Cmd(TIM2, ENABLE);  //使能TIMx外設                                                 
}
//定時器2中斷服務程序         
//void TIM2_IRQHandler(void)
//{                                                                   
//        if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //溢出中斷
//        {
//                                MPU6050_Pose();
//        }                                  
//        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);  //清除TIMx的中斷待處理位:TIM 中斷源
//}




iic.rar

1.31 KB, 下載次數(shù): 8, 下載積分: 黑幣 -5

MPU6050.rar

2.47 KB, 下載次數(shù): 7, 下載積分: 黑幣 -5

MPU6050_DMP.rar

35.2 KB, 下載次數(shù): 17, 下載積分: 黑幣 -5

回復

使用道具 舉報

ID:1 發(fā)表于 2019-6-2 17:32 | 顯示全部樓層
本帖需要重新編輯補全電路原理圖,源碼,詳細說明與圖片即可獲得100+黑幣(帖子下方有編輯按鈕)
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一区二区三区在线免费观看 | 久久国内精品 | 国产福利91精品 | 五月婷婷色| 亚洲精品9999久久久久 | 激情五月综合 | 国产一区精品 | 日韩精品影院 | 久久久成人一区二区免费影院 | 欧美日韩国产高清 | 欧美精品一区二区三区蜜桃视频 | 美国十次成人欧美色导视频 | 精品国产成人 | 国产一级片一区二区三区 | 国产亚洲成av人在线观看导航 | 国产精品视频一区二区三区, | 欧美日韩国产一区二区 | 欧美a视频 | 在线国产小视频 | 男女激情网站免费 | 一区二区精品 | 国产精品视频免费观看 | 我想看国产一级毛片 | 91精品国产91久久综合桃花 | www.天天干.com | 国产成人精品视频在线观看 | 中文字幕在线观看www | 在线观看av不卡 | 91九色在线观看 | 羞羞视频在线观免费观看 | 成人黄色电影在线播放 | 亚洲成人一区二区三区 | 黑人巨大精品欧美一区二区一视频 | 91最新入口 | 日韩国产中文字幕 | 欧美日韩在线高清 | av在线亚洲天堂 | 日韩欧美一级 | 欧美一级大黄 | 欧美精品一区二区蜜桃 | 天堂中文字幕av |