betaflight的陀螺仪初始化

在init函数里有一个判断

    if (!sensorsAutodetect()) {
        // if gyro was not detected due to whatever reason, notify and don't arm.
        indicateFailure(FAILURE_MISSING_ACC, 2);
        setArmingDisabled(ARMING_DISABLED_NO_GYRO);
    }

打开sensorsAutodetect就有

bool sensorsAutodetect(void)
{

    // gyro must be initialised before accelerometer

    bool gyroDetected = gyroInit();

    if (gyroDetected) {
        accInit(gyro.targetLooptime);
    }

#ifdef USE_MAG
    compassInit();
#endif

#ifdef USE_BARO
    baroDetect(&baro.dev, barometerConfig()->baro_hardware);
#endif

#ifdef USE_RANGEFINDER
    rangefinderInit();
#endif

    return gyroDetected;
}

在这里初始化了陀螺仪,就有

bool gyroInit(void)
{
#ifdef USE_GYRO_OVERFLOW_CHECK//有定义
    if (gyroConfig()->checkOverflow == GYRO_OVERFLOW_CHECK_YAW) {
        overflowAxisMask = GYRO_OVERFLOW_Z;
    } else if (gyroConfig()->checkOverflow == GYRO_OVERFLOW_CHECK_ALL_AXES) {
            overflowAxisMask = GYRO_OVERFLOW_X | GYRO_OVERFLOW_Y | GYRO_OVERFLOW_Z;
            //刚开始这里设置了.checkOverflow=GYRO_OVERFLOW_CHECK_ALL_AXES
    } else {
        overflowAxisMask = 0;
    }
    //就有overflowAxisMask = GYRO_OVERFLOW_X | GYRO_OVERFLOW_Y | GYRO_OVERFLOW_Z;
#endif

    switch (debugMode) {
    case DEBUG_FFT:
    case DEBUG_GYRO_NOTCH:
    case DEBUG_GYRO:
    case DEBUG_GYRO_RAW:
        gyroDebugMode = debugMode;
        break;
    default:
        // debugMode is not gyro-related
        gyroDebugMode = DEBUG_NONE;
        break;
    }
    //设置debug模式
    firstArmingCalibrationWasStarted = false;
    memset(&gyro, 0, sizeof(gyro));
    return gyroInitSensor(&gyroSensor1);
}

下面进入

static bool gyroInitSensor(gyroSensor_t *gyroSensor)
{
#if defined(USE_GYRO_MPU6050) || defined(USE_GYRO_MPU3050) || defined(USE_GYRO_MPU6500) || defined(USE_GYRO_SPI_MPU6500) || defined(USE_GYRO_SPI_MPU6000) \
 || defined(USE_ACC_MPU6050) || defined(USE_GYRO_SPI_MPU9250) || defined(USE_GYRO_SPI_ICM20601) || defined(USE_GYRO_SPI_ICM20649) || defined(USE_GYRO_SPI_ICM20689)
//mpu6050
#if defined(MPU_INT_EXTI)//没定义
    gyroSensor->gyroDev.mpuIntExtiTag =  IO_TAG(MPU_INT_EXTI);
#elif defined(USE_HARDWARE_REVISION_DETECTION)//没定义
    gyroSensor->gyroDev.mpuIntExtiTag =  selectMPUIntExtiConfigByHardwareRevision();
#else
    gyroSensor->gyroDev.mpuIntExtiTag =  IO_TAG_NONE;//只有这一个
#endif // MPU_INT_EXTI

#ifdef USE_DUAL_GYRO//没定义
    // set cnsPin using GYRO_n_CS_PIN defined in target.h
    gyroSensor->gyroDev.bus.busdev_u.spi.csnPin = gyroConfig()->gyro_to_use == 0 ? IOGetByTag(IO_TAG(GYRO_0_CS_PIN)) : IOGetByTag(IO_TAG(GYRO_1_CS_PIN));
#else
    gyroSensor->gyroDev.bus.busdev_u.spi.csnPin = IO_NONE; // set cnsPin to IO_NONE so mpuDetect will set it according to value defined in target.h
#endif // USE_DUAL_GYRO
    mpuDetect(&gyroSensor->gyroDev);
    mpuResetFn = gyroSensor->gyroDev.mpuConfiguration.resetFn; // must be set after mpuDetect
#endif
    gyroSensor->gyroDev.gyro_high_fsr = gyroConfig()->gyro_high_fsr;

    const gyroSensor_e gyroHardware = gyroDetect(&gyroSensor->gyroDev);
    if (gyroHardware == GYRO_NONE) {
        return false;
    }

    switch (gyroHardware) {
    case GYRO_MPU6500:
    case GYRO_MPU9250:
    case GYRO_ICM20601:
    case GYRO_ICM20602:
    case GYRO_ICM20608G:
    case GYRO_ICM20689:
        // do nothing, as gyro supports 32kHz
        break;
    default:
        // gyro does not support 32kHz
        gyroConfigMutable()->gyro_use_32khz = false;
        break;
    }

    // Must set gyro targetLooptime before gyroDev.init and initialisation of filters
    gyro.targetLooptime = gyroSetSampleRate(&gyroSensor->gyroDev, gyroConfig()->gyro_lpf, gyroConfig()->gyro_sync_denom, gyroConfig()->gyro_use_32khz);//采样率设置
    gyroSensor->gyroDev.lpf = gyroConfig()->gyro_lpf;//低通滤波
    gyroSensor->gyroDev.initFn(&gyroSensor->gyroDev);//这定义个函数指针处理了很多东西
    if (gyroConfig()->gyro_align != ALIGN_DEFAULT) {
        gyroSensor->gyroDev.gyroAlign = gyroConfig()->gyro_align;
    }

    gyroInitSensorFilters(gyroSensor);
#ifdef USE_GYRO_DATA_ANALYSE//有定义
    gyroDataAnalyseInit(gyro.targetLooptime);
#endif
    return true;
}

至此初始化完毕有一些细节
首先 mpuDetect判断mpu
mpuDetect(&gyroSensor1->gyroDev)

void mpuDetect(gyroDev_t *gyro)
{
    // MPU datasheet specifies 30ms.
    delay(35);

#ifdef USE_I2C//有定义
    gyro->bus.bustype = BUSTYPE_I2C;
    gyro->bus.busdev_u.i2c.device = MPU_I2C_INSTANCE;
    gyro->bus.busdev_u.i2c.address = MPU_ADDRESS;
    uint8_t sig = 0;
    bool ack = busReadRegisterBuffer(&gyro->bus, MPU_RA_WHO_AM_I, &sig, 1);
#else
    bool ack = false;
#endif

    if (!ack) {
#ifdef USE_SPI//没有
        detectSPISensorsAndUpdateDetectionResult(gyro);
#endif
        return;
    }

#ifdef USE_I2C
    // If an MPU3050 is connected sig will contain 0.
    uint8_t inquiryResult;
    ack = busReadRegisterBuffer(&gyro->bus, MPU_RA_WHO_AM_I_LEGACY, &inquiryResult, 1);
    inquiryResult &= MPU_INQUIRY_MASK;
    //判断是不是用的是mpu3050,不是
    if (ack && inquiryResult == MPUx0x0_WHO_AM_I_CONST) {
        gyro->mpuDetectionResult.sensor = MPU_3050;
        return;
    }

    sig &= MPU_INQUIRY_MASK;
    if (sig == MPUx0x0_WHO_AM_I_CONST) {
        //进入这个
        gyro->mpuDetectionResult.sensor = MPU_60x0;
        mpu6050FindRevision(gyro);
    } else if (sig == MPU6500_WHO_AM_I_CONST) {
        gyro->mpuDetectionResult.sensor = MPU_65xx_I2C;
    }
#endif
}

i2c读

bool busReadRegisterBuffer(const busDevice_t *busdev, uint8_t reg, uint8_t *data, uint8_t length)
{
#if !defined(USE_SPI) && !defined(USE_I2C)
    UNUSED(reg);
    UNUSED(data);
    UNUSED(length);
#endif
    switch (busdev->bustype) {
#ifdef USE_SPI
    case BUSTYPE_SPI:
        return spiBusReadRegisterBuffer(busdev, reg | 0x80, data, length);
#endif
#ifdef USE_I2C
    case BUSTYPE_I2C:
        return i2cBusReadRegisterBuffer(busdev, reg, data, length);
#endif
    default:
        return false;
    }
}

返回return i2cBusReadRegisterBuffer(&gyro->bus, MPU_RA_WHO_AM_I, &sig, 1);


bool i2cBusReadRegisterBuffer(const busDevice_t *busdev, uint8_t reg, uint8_t *data, uint8_t length)
{
    return i2cRead(busdev->busdev_u.i2c.device, busdev->busdev_u.i2c.address, reg, length, data);
}

读数据
下面回到
const gyroSensor_e gyroHardware = gyroDetect(&gyroSensor->gyroDev);

STATIC_UNIT_TESTED gyroSensor_e gyroDetect(gyroDev_t *dev)
{
    gyroSensor_e gyroHardware = GYRO_DEFAULT;

    dev->gyroAlign = ALIGN_DEFAULT;

    switch (gyroHardware) {
    case GYRO_DEFAULT:
        FALLTHROUGH;

#ifdef USE_GYRO_MPU6050
    case GYRO_MPU6050:
        if (mpu6050GyroDetect(dev)) {
            gyroHardware = GYRO_MPU6050;
#ifdef GYRO_MPU6050_ALIGN
            dev->gyroAlign = GYRO_MPU6050_ALIGN;
#endif
            break;
        }
        FALLTHROUGH;
#endif

#ifdef USE_GYRO_L3G4200D
    case GYRO_L3G4200D:
        if (l3g4200dDetect(dev)) {
            gyroHardware = GYRO_L3G4200D;
#ifdef GYRO_L3G4200D_ALIGN
            dev->gyroAlign = GYRO_L3G4200D_ALIGN;
#endif
            break;
        }
        FALLTHROUGH;
#endif

#ifdef USE_GYRO_MPU3050
    case GYRO_MPU3050:
        if (mpu3050Detect(dev)) {
            gyroHardware = GYRO_MPU3050;
#ifdef GYRO_MPU3050_ALIGN
            dev->gyroAlign = GYRO_MPU3050_ALIGN;
#endif
            break;
        }
        FALLTHROUGH;
#endif

#ifdef USE_GYRO_L3GD20
    case GYRO_L3GD20:
        if (l3gd20Detect(dev)) {
            gyroHardware = GYRO_L3GD20;
#ifdef GYRO_L3GD20_ALIGN
            dev->gyroAlign = GYRO_L3GD20_ALIGN;
#endif
            break;
        }
        FALLTHROUGH;
#endif

#ifdef USE_GYRO_SPI_MPU6000
    case GYRO_MPU6000:
        if (mpu6000SpiGyroDetect(dev)) {
            gyroHardware = GYRO_MPU6000;
#ifdef GYRO_MPU6000_ALIGN
            dev->gyroAlign = GYRO_MPU6000_ALIGN;
#endif
            break;
        }
        FALLTHROUGH;
#endif

#if defined(USE_GYRO_MPU6500) || defined(USE_GYRO_SPI_MPU6500)
    case GYRO_MPU6500:
    case GYRO_ICM20601:
    case GYRO_ICM20602:
    case GYRO_ICM20608G:
#ifdef USE_GYRO_SPI_MPU6500
        if (mpu6500GyroDetect(dev) || mpu6500SpiGyroDetect(dev)) {
#else
        if (mpu6500GyroDetect(dev)) {
#endif
            switch (dev->mpuDetectionResult.sensor) {
            case MPU_9250_SPI:
                gyroHardware = GYRO_MPU9250;
                break;
            case ICM_20601_SPI:
                gyroHardware = GYRO_ICM20601;
                break;
            case ICM_20602_SPI:
                gyroHardware = GYRO_ICM20602;
                break;
            case ICM_20608_SPI:
                gyroHardware = GYRO_ICM20608G;
                break;
            default:
                gyroHardware = GYRO_MPU6500;
            }
#ifdef GYRO_MPU6500_ALIGN
            dev->gyroAlign = GYRO_MPU6500_ALIGN;
#endif
            break;
        }
        FALLTHROUGH;
#endif

#ifdef USE_GYRO_SPI_MPU9250
    case GYRO_MPU9250:
        if (mpu9250SpiGyroDetect(dev)) {
            gyroHardware = GYRO_MPU9250;
#ifdef GYRO_MPU9250_ALIGN
            dev->gyroAlign = GYRO_MPU9250_ALIGN;
#endif
            break;
        }
        FALLTHROUGH;
#endif

#ifdef USE_GYRO_SPI_ICM20649
    case GYRO_ICM20649:
        if (icm20649SpiGyroDetect(dev)) {
            gyroHardware = GYRO_ICM20649;
#ifdef GYRO_ICM20649_ALIGN
            dev->gyroAlign = GYRO_ICM20649_ALIGN;
#endif
            break;
        }
        FALLTHROUGH;
#endif

#ifdef USE_GYRO_SPI_ICM20689
    case GYRO_ICM20689:
        if (icm20689SpiGyroDetect(dev)) {
            gyroHardware = GYRO_ICM20689;
#ifdef GYRO_ICM20689_ALIGN
            dev->gyroAlign = GYRO_ICM20689_ALIGN;
#endif
            break;
        }
        FALLTHROUGH;
#endif

#ifdef USE_ACCGYRO_BMI160
    case GYRO_BMI160:
        if (bmi160SpiGyroDetect(dev)) {
            gyroHardware = GYRO_BMI160;
#ifdef GYRO_BMI160_ALIGN
            dev->gyroAlign = GYRO_BMI160_ALIGN;
#endif
            break;
        }
        FALLTHROUGH;
#endif

#ifdef USE_FAKE_GYRO
    case GYRO_FAKE:
        if (fakeGyroDetect(dev)) {
            gyroHardware = GYRO_FAKE;
            break;
        }
        FALLTHROUGH;
#endif

    default:
        gyroHardware = GYRO_NONE;
    }

    if (gyroHardware != GYRO_NONE) {
        detectedSensors[SENSOR_INDEX_GYRO] = gyroHardware;
        sensorsSet(SENSOR_GYRO);
    }


    return gyroHardware;
}

这里得到
gyroHardware = GYRO_MPU6050;
dev->gyroAlign = GYRO_MPU6050_ALIGN;
这里有调用函数mpu6050GyroDetect赋值

bool mpu6050GyroDetect(gyroDev_t *gyro)
{
    if (gyro->mpuDetectionResult.sensor != MPU_60x0) {
        return false;
    }
    gyro->initFn = mpu6050GyroInit;
    gyro->readFn = mpuGyroRead;

    // 16.4 dps/lsb scalefactor
    gyro->scale = 1.0f / 16.4f;

    return true;
}

下面回到gyroInitSensor里的
gyro.targetLooptime = gyroSetSampleRate(&gyroSensor->gyroDev, gyroConfig()->gyro_lpf, gyroConfig()->gyro_sync_denom, gyroConfig()->gyro_use_32khz);

uint32_t gyroSetSampleRate(gyroDev_t *gyro, uint8_t lpf, uint8_t gyroSyncDenominator, bool gyro_use_32khz)
{                              //&gyroSensor->gyroDev, gyroConfig()->gyro_lpf, gyroConfig()->gyro_sync_denom, gyroConfig()->gyro_use_32khz
    float gyroSamplePeriod;

    if (lpf == GYRO_LPF_256HZ || lpf == GYRO_LPF_NONE) {
        if (gyro_use_32khz) {
            gyro->gyroRateKHz = GYRO_RATE_32_kHz;//flase
            gyroSamplePeriod = 31.5f;
        } else {
            switch (gyro->mpuDetectionResult.sensor) {
            case BMI_160_SPI:
                gyro->gyroRateKHz = GYRO_RATE_3200_Hz;
                gyroSamplePeriod = 312.0f;
                break;
            case ICM_20649_SPI:
                gyro->gyroRateKHz = GYRO_RATE_9_kHz;
                gyroSamplePeriod = 1000000.0f / 9000.0f;
                break;
            default:
                //进入这个
                gyro->gyroRateKHz = GYRO_RATE_8_kHz;
                gyroSamplePeriod = 125.0f;
                break;
            }
        }
    } else {
        switch (gyro->mpuDetectionResult.sensor) {
        case ICM_20649_SPI:
            gyro->gyroRateKHz = GYRO_RATE_1100_Hz;
            gyroSamplePeriod = 1000000.0f / 1100.0f;
            break;
        default:
            gyro->gyroRateKHz = GYRO_RATE_1_kHz;
            gyroSamplePeriod = 1000.0f;
            break;
        }
        gyroSyncDenominator = 1; // Always full Sampling 1khz
    }

    // calculate gyro divider and targetLooptime (expected cycleTime)
    gyro->mpuDividerDrops  = gyroSyncDenominator - 1;//4-1=3
    const uint32_t targetLooptime = (uint32_t)(gyroSyncDenominator * gyroSamplePeriod);
    return targetLooptime;//375
}

接着就有gyroInitSensorFilters:

static void gyroInitSensorFilters(gyroSensor_t *gyroSensor)
{
#if defined(USE_GYRO_SLEW_LIMITER)//有定义
    gyroInitSlewLimiter(gyroSensor);
#endif
    gyroInitFilterLpf(gyroSensor, gyroConfig()->gyro_soft_lpf_hz);
    gyroInitFilterNotch1(gyroSensor, gyroConfig()->gyro_soft_notch_hz_1, gyroConfig()->gyro_soft_notch_cutoff_1);
    gyroInitFilterNotch2(gyroSensor, gyroConfig()->gyro_soft_notch_hz_2, gyroConfig()->gyro_soft_notch_cutoff_2);
#ifdef USE_GYRO_DATA_ANALYSE//有定义
    gyroInitFilterDynamicNotch(gyroSensor);
#endif
}

接着初始化gyroDataAnalyseInit(gyro.targetLooptime);

void gyroDataAnalyseInit(uint32_t targetLooptimeUs)
{
    // initialise even if FEATURE_DYNAMIC_FILTER not set, since it may be set later
    samplingFrequency = 1000000 / targetLooptimeUs;
    fftSamplingScale = samplingFrequency / FFT_SAMPLING_RATE;
    fftMaxFreq = FFT_SAMPLING_RATE / 2;
    fftBinCount = fftFreqToBin(fftMaxFreq) + 1;
    fftResolution = FFT_SAMPLING_RATE / FFT_WINDOW_SIZE;
    arm_rfft_fast_init_f32(&fftInstance, FFT_WINDOW_SIZE);

    initGyroData();
    initHanning();

    // recalculation of filters takes 4 calls per axis => each filter gets updated every 3 * 4 = 12 calls
    // at 4khz gyro loop rate this means 4khz / 4 / 3 = 333Hz => update every 3ms
    float looptime = targetLooptimeUs * 4 * 3;
    for (int axis = 0; axis < XYZ_AXIS_COUNT; axis++) {
        fftResult[axis].centerFreq = 200; // any init value
        biquadFilterInitLPF(&fftFreqFilter[axis], DYN_NOTCH_CHANGERATE, looptime);
        biquadFilterInit(&fftGyroFilter[axis], FFT_BPF_HZ, 1000000 / FFT_SAMPLING_RATE, BIQUAD_Q, FILTER_BPF);
    }
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Betaflight 10.8.0是一款开源的多轴飞行控制软件。它专为无人机设计,具有强大的飞行控制能力和丰富的功能。如果您想下载Betaflight 10.8.0,您可以通过以下步骤获得它。 首先,您可以在Betaflight官方网站上获得最新版本的下载链接。访问官方网站后,找到下载页面并点击进入。在下载页面上,您将看到各种不同的版本可供选择。您需要找到10.8.0版本,并点击下载链接。 下载完成后,您可以将文件保存到您的计算机上的任意位置。请确保选择一个方便访问的位置,以便稍后安装软件。 然后,解压下载的文件。您可以使用常见的解压软件,例如WinRAR或7-Zip。右键点击文件并选择“解压缩到当前文件夹”或类似选项。解压完成后,您将在目标文件夹中看到Betaflight 10.8.0的文件和文件夹。 最后,您可以通过连接无人机到计算机上,使用飞行控制器如F4或F7,然后通过Betaflight Configurator来加载Betaflight 10.8.0。您只需打开Betaflight Configurator并选择正确的端口,然后将固件升级为Betaflight 10.8.0即可。 总之,下载Betaflight 10.8.0只需几个简单的步骤。请记住,使用Betaflight控制软件可能需要一定的技术知识和理解。在操作过程中,务必仔细阅读官方文档和教程,以确保您正确且安全地使用Betaflight 10.8.0。 ### 回答2: Betaflight是一款十分受欢迎的开源飞控固件,用于控制无人机的飞行和飞控功能。Betaflight 10.8.0是Betaflight团队开发的最新版本。 要下载Betaflight 10.8.0,首先需要访问Betaflight官方网站。在网站上,你可以找到下载页面。你可以在导航栏中找到“固件下载”或类似的选项。点击进入下载页面。 在下载页面,你会看到不同版本的Betaflight固件列在一起。现在你需要找到Betaflight 10.8.0的下载链接。可能有一些列如“最新稳定版”、“测试版”、“老版本”等的选项,你需要选择适合你的选择。找到Betaflight 10.8.0的选项并点击。 点击后,将会有一个提示框显示文件将要保存在电脑中的位置。选择一个你想保存固件文件的位置,并点击“保存”按钮。 下载过程可能需要一些时间,具体取决于你的网络连接和文件大小。一旦下载完成,你就可以在你选择的位置找到下载好的Betaflight 10.8.0固件文件。 下载好Betaflight 10.8.0后,你可以将固件文件烧录到你的飞控硬件中。具体的烧录步骤因不同的飞控硬件而异,你可以在Betaflight官方网站上找到详细的步骤和教程。 总之,要下载Betaflight 10.8.0,可以通过访问Betaflight官方网站,在下载页面中找到Betaflight 10.8.0的下载链接,然后保存到你的电脑中。下载完成后,可以将固件烧录到你的飞控硬件中,并开始享受最新版本的Betaflight带来的功能和飞行体验。 ### 回答3: Betaflight 10.8.0是一款开源的飞控固件,适用于无人机的飞行控制。要下载Betaflight 10.8.0版本,可以按照以下步骤进行操作: 第一步,打开Betaflight官方网站,网址为"https://betaflight.com/"。在网站首页的顶部导航栏中,可以找到一个名为"Downloads"的选项,点击进入。 第二步,进入Downloads页面后,会看到各个版本的Betaflight固件列表。向下滚动页面,直到找到Betaflight 10.8.0版本。点击版本号旁边的下载按钮。 第三步,选择适用于你的机型的固件下载链接。根据你的无人机型号和硬件配置,选择对应的下载链接,比如选择适用于F3飞控的固件。 第四步,点击下载链接后,会开始下载Betaflight 10.8.0的固件文件。下载完成后,将文件保存到你的计算机本地或指定的文件夹中。 第五步,将下载的Betaflight 10.8.0固件文件导入到你的飞控设备中。具体方法可以参考Betaflight官方网站提供的相关教程或使用说明。 总结,要下载Betaflight 10.8.0固件,首先前往Betaflight官方网站的Downloads页面,找到对应版本的固件文件,下载并导入到你的飞控设备中,然后按照相关教程进行设置和使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值