一种双边沿都可触发进中断的输入捕获

        本文基于一块新兴的国产芯片平台Z20K142单片机设计的一款输入捕获方法,可以正确捕获到PWM的频率和占空比。

主要算法写在输入捕获回调函数里面:

        主要考虑到以下几种条件,首先pwm是从高电平来的还是从低电平来的,其次考虑ccv计数值,是否快要接近mod值了,如果通过比较发现小于mod值,此pwm的频率就等于两次CCV值的差,相反的话就等于第二次CCV值减去第一次CCV值加上一个mod值,结果如下回调函数所示。

static uint32_t CapturePwmPeriod = 0xFF;         //输入捕获到的PWM周期
static uint32_t CapturePwmDuty = 0xFF;           //输入捕获到的PWM占空比
static int32_t Period1 = 0;                     //输入捕获到的PWM波形上升沿时刻的计数器值,前
static int32_t Period2 = 0;                     //输入捕获到的PWM波形上升沿时刻的计数器值,后
static int32_t Duty1 = 0;                       //输入捕获到的PWM波形下降沿时刻的计数器值
static uint32_t UnstableCounter = 0;             //输入捕获无效值的过滤次数

/**************************************************************************************************
*函数: TimCallback
*功能: TIM输入捕获的回调函数,计算输入PWM波形的占空比和周期
*参数: NONE
*返值: NONE
*说明: 占空比和周期的计算结果会更新到静态变量中;用周期内高电平时间占比计算占空比
**************************************************************************************************/
void TimCallback()
{
    if(GPIO_ReadPinLevel(CAPTURE_CHPORT,CAPTURE_CHPIN)==GPIO_HIGH)       //识别上升沿
    {
        Period1 = Period2;                                               //Period1更新前一个上升沿时刻的计数器值
        Period2 = TIM_GetCCVal(CAPTURE_TIMID,CAPTURE_CH);                //Period2更新当前上升沿时刻的计数器值
        if(Period2 <= Period1)
        {
            CapturePwmPeriod = CAPTURE_COUNTERMAX + (Period2 - Period1); //输入PWM波形相邻边沿中间出现TIM溢出时,需要加TIM的溢出值再相减,得到周期
        }
        else
        {
            CapturePwmPeriod = Period2 - Period1;                        //输入PWM波形相邻边沿中间没有TIM溢出时,直接相减得到周期
        }
    }
    else
    {
        Duty1 = TIM_GetCCVal(CAPTURE_TIMID,CAPTURE_CH);                  //Duty1更新当前下降沿时刻的计数器值
        if(Duty1 <= Period2)                                             
        {
            CapturePwmDuty = CAPTURE_COUNTERMAX + (Duty1 - Period2);     //输入PWM波形相邻边沿中间出现TIM溢出时,需要加TIM的溢出值再相减,得到占空比
        }
        else
        {
            CapturePwmDuty = Duty1 - Period2;                            //输入PWM波形相邻边沿中间没有TIM溢出时,直接相减得到得到占空比
        }
    }
    
    if(UnstableCounter<4)
    {
        UnstableCounter++;                                              //输入捕获第1次边沿可能是假的需要丢弃,之后至少经过3次边沿,才能保证周期和占空比计算正确
    }
}


/**************************************************************************************************
*函数: Bsp_GetPwmPeriod
*功能: 获取输入PWM波形的周期
*参数: NONE
*返值: 输入PWM波形的周期
*说明: 
**************************************************************************************************/
uint32_t Bsp_GetPwmPeriod(void)
{
    if(UnstableCounter<4)
    {
        return CAPTURE_COUNTERMAX;      //输入捕获第1次边沿可能是假的需要丢弃,之后至少经过3次边沿,才能保证周期和占空比计算正确
    }
    return CapturePwmPeriod;
}

/**************************************************************************************************
*函数: Bsp_GetPwmDuty
*功能: 获取输入PWM波形的占空比
*参数: NONE
*返值: 输入PWM波形的占空比
*说明: 
**************************************************************************************************/
uint32_t Bsp_GetPwmDuty(void)
{
    if(UnstableCounter<4)
    {
        return CAPTURE_COUNTERMAX;      //输入捕获第1次边沿可能是假的需要丢弃,之后至少经过3次边沿,才能保证周期和占空比计算正确
    }
    return CapturePwmDuty;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值