一天精通无人机第 27 讲 中级篇系列:遥控器 PWM 与 PPM 协议

file

传统的遥控器接收机是采用多路PWM的方式进行输出的,遥控器中有多少个通道,接收机中就有多少路PWM输出,例如下图中的遥控器有6个可用通道,其接收机也有6个PWM输出通道与之对应:

file

此接收机除了PWM输出之外还有S.BUS协议输出方式,关于S.BUS我们已经在上一节中介绍过了,这里不再赘述。下面我们主要针对PWM信号输出来做讲解。

接收机的1-7个PWM输出通道,都是以PWM的形式输出的,这就需要飞控能够采集并解析这些PWM信号,并为飞控所用。我们知道PWM信号所表示的数值就是高电平持续时间占用整个周期时长的百分比,例如下图所示:

file

接收机输出的PWM与之前章节中讲述的电调需要接收的PWM完全一致。只不过我们需要使用飞控程序来读取接收机输出的PWM信号值。我们以第一个通道的PWM为例,讲述飞控程序对其处理的具体方法:

  1. 检测引脚由低点平变为高电平的时刻,并记录当前时间t0,表示高电平开始;

  2. 检测引脚由高电平变为低点平的时刻,并记录当前时间t1,表示高电平结束;

  3. 继续检测引脚由低点平变为高电平的时刻,并记录当前时间t2,表示一个PWM周期结束;

  4. 计算高电平时常 = t1 - t0;

  5. 计算整个PWM周期 = t2 - t0;

  6. 计算PWM占空比 = 高电平时常 / PWM周期

在STM32系列中,我们可以为GPIO引脚设置成PWM采集模式,并通过采集寄存器来读取当前PWM的周期和PWM占空比。

//定义PWM输入捕获引脚
#define GPIO_PWM_IN (GPIO_ALT|GPIO_AF2|GPIO_SPEED_50MHz|GPIO_FLOAT|GPIO_PORTD|GPIO_PIN13)

void PWMIN::_timer_init(void)
{
    //在定时器还没有使能之前关中断
    irqstate_t flags = px4_enter_critical_section();

    //配置PWM输入的GPIO引脚
    px4_arch_configgpio (GPIO_PWM_IN);
    px4_arch_configgpio (GPIO_VDD_RANGEFINDER_EN);

    //配置中断向量
    irq_attach(PWMIN_TIMER_VECTOR, pwmin_tim_isr, NULL);

    //修改定时器寄存器
    modifyreg32(PWMIN_TIMER_POWER_REG, 0, PWMIN_TIMER_POWER_BIT);

    //配置定时器寄存器
    rCR1 = 0;
    rCR2 = 0;
    rSMCR = 0;
    rDIER = DIER_PWMIN_A;
    rCCER = 0;
    rCCMR1 = CCMR1_PWMIN;
    rCCMR2 = CCMR2_PWMIN;
    rSMCR = SMCR_PWMIN_1;
    rSMCR = SMCR_PWMIN_2;
    rCCER = CCER_PWMIN;
    rDCR = 0;

    //配置捕获周期
    uint32_t prescaler = PWMIN_TIMER_CLOCK / 1000000UL;
    rPSC = prescaler - 1;

    //最大计数
    rARR = UINT16_MAX;
    rEGR = GTIM_EGR_UG;

    //定时器使能
    rCR1 = GTIM_CR1_CEN;    

    //开中断
    up_enable_irq (PWMIN_TIMER_VECTOR);

    px4_leave_critical_section(flags);
}

static int pwmin_tim_isr(int irq, void *context, void *arg)
{
    uint16_t status = rSR;
    uint32_t period = rCCR_PWMIN_A;
    uint32_t pulse_width = rCCR_PWMIN_B;

    //完成中断,清除标识位,允许继续中断
    rSR = 0;

    //处理得到的PWM数值
    //

    return OK;
}

每一个遥控器通道都需要一个PWM采集器进行采集,但是对于STM32来说不可能使用多个定时器来采集多个通道的PWM,这对于STM32的资源来说十分浪费。因此采用的就是PPM编码。PPM编码是PWM的扩展协议,可以在一个管脚中传输多路PWM信号。

PPM的频率通常是50Hz,周期长度20ms,每一个周期中可以存放最多10路PWM信号,每一路PWM的周期为2ms,如下图所示:

file

使用STM32的管脚中断配合定时器中的计数可以准确的捕获一个周期内的PPM信号中的高低电平变化,每2ms就是一路PWM信号的周期。

下期预告:《中级篇:Commander飞控主状态解析》

file