备考蓝桥杯嵌入式5:捕获两个XL555产生的可调频率方波的频率

我们蓝桥杯的板子上有2个XL555定时器,这里,我们需要做的就是捕获我们PA15和PB4接口上产生的PWM定时器。还记得上一篇博客我们是怎么做的吗?这里是一样的:备考蓝桥杯嵌入式4:使用LCD显示我们捕捉的PWM波-CSDN博客

我们仍然设置PA15和PB4上的定时器为输入捕获模式,配置我们的预分频为80,当然,在使能全局中断后,不要忘记把使用回调函数记载一下捕获的频率。如下所示:

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    uint32_t capture_value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
    htim->Instance->CNT = 0;
    if(htim->Instance == TIM2){
        freq2 = HAL_RCC_GetSysClockFreq() / ((htim->Init.Prescaler + 1) * capture_value);
    }
    if(htim->Instance == TIM16)
    {
        freq1 = HAL_RCC_GetSysClockFreq() / ((htim->Init.Prescaler + 1) * capture_value);
    }
}

到这里,我们把捕获的示数写一个display

void display_captured_frequency555(void)
{
    snprintf(buffer, 20, "freq1: %d Hz", display_freq1);
    lcd_middledisplay(Line0, buffer);
    snprintf(buffer, 20, "freq2: %d Hz", display_freq2);
    lcd_middledisplay(Line1, buffer);
}

但是笔者发现,这样直接丢尽主函数循环内部,示数非常的不稳定,特别是对于高频部分,甚至千分位都起飞了!所以,我们需要做一些改进。也就是完成一些简单的滤波。

笔者采用的是最最简单的平均滤波办法。也就是多次采集取平均值,求解完成了平均值在做显示。所以:

// frequency that fetch as raw
uint32_t freq1, freq2;
// frequency using in storing the accumulations
uint32_t capture_freq1, capture_freq2;
// frequency that finally using in display
uint32_t display_freq1, display_freq2;
// captures recording
uint16_t capture_time;
static char buffer[20];
​
static void __make_real_display(void)
{
    snprintf(buffer, 20, "freq1: %d Hz", display_freq1);
    lcd_middledisplay(Line0, buffer);
    snprintf(buffer, 20, "freq2: %d Hz", display_freq2);
    lcd_middledisplay(Line1, buffer);
}
​
#define BETTER_ALG
void display_captured_frequency555(void)
{
#ifdef BETTER_ALG
    capture_time++;
    capture_freq1 += freq1;
    capture_freq2 += freq2;
    if(capture_time == MAKE_SCALAR){
        display_freq1 = capture_freq1 / MAKE_SCALAR;
        display_freq2 = capture_freq2 / MAKE_SCALAR;
        capture_freq1 = 0;
        capture_freq2 = 0;
        capture_time = 0;
        __make_real_display();
    }
#else
    __make_real_display();    
#endif
}

还有一种改进的方式是直到发生了中断我们才去做求取平均,而不是一个劲的加数据导致产生了无效的平均算法。

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    uint32_t capture_value = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1);
    htim->Instance->CNT = 0;
    if(htim->Instance == TIM2){
        freq2 = HAL_RCC_GetSysClockFreq() / ((htim->Init.Prescaler + 1) * capture_value);
        display_captured_frequency555();    // 直到发生采集了我们才求取
    }
    if(htim->Instance == TIM16)
    {
        freq1 = HAL_RCC_GetSysClockFreq() / ((htim->Init.Prescaler + 1) * capture_value);
        display_captured_frequency555();    // 直到发生采集了我们才求取
    }
}

现在我们的示数就会稳定许多了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值