蓝桥杯嵌入式输入捕获

功能:测量频率、周期、占空比

百度云:https://pan.baidu.com/s/1e4BSJzzk3W2YQi2S7qHG5A?pwd=6666 
提取码:6666

目录

原理分析:

1.周期与频率测量分析

2.占空比分析

HAL配置

1.配置时钟

2.SYS配置

3.输入捕获的配置

4.PWM配置 

代码编写

定义的数据

输入捕获回调函数

定时器中断回调函数

结果演示


原理分析:

1.周期与频率测量分析

我们在第一次捕获上升沿时将计数值清零,第二次捕获到上升沿时记下当前值,也就是count3,在捕获count3之前可能会有溢出,我们要将它记录下来否则计算会出现差错。

也就是总计数值为N*ARR+count3,再乘上计数时间就可以算出周期了。

T = (N*ARR+count3)*t

F = 1/T

2.占空比分析

在第一次捕获到上升沿时将计数值清零,并且设置下次为捕获下降沿。在捕获下降沿时,中间也可能有N次溢出。

Th = (N*ARR+count2)*t

占空比 = Th/T*100%

HAL配置

1.配置时钟

然后回车一下。

因为开发板上接的是24MHz所以这里填1处24,官方给的历程都是80MHz所以4处填80。

2.SYS配置

防止只能下载一次程序所以这里设置为Serial Wire。

3.输入捕获的配置

配置时钟源以及输入捕获模式,通道选择对应引脚的通道,4处的分频可以小一些防止捕获不到,计数值我们设置为1000-1,是为了演示溢出所以小了一些一般默认就好。

默认捕获上升沿。

4.PWM配置 

我们这里方便验证捕获的准确性,所以捕获PWM的周期频率及占空比。

配置请看蓝桥杯嵌入式PWM_川页少年的博客-CSDN博客

代码编写

定义的数据

typedef struct
{
    double Period;//周期
    unsigned char N;//溢出N
    unsigned long Count;//测量的计数值
    bool N_Flag;//溢出标志位
    bool Flag;//测量上升沿的标志位
    unsigned int Frequency;//频率
    unsigned char state;
    double High_Time;//高电平时间
    unsigned char Duty_Cycle;//占空比
}PWM_TypeDef;

    //开启定时器中断
    HAL_TIM_Base_Start_IT(&htim3);
    //开启PWM
    HAL_TIM_PWM_Start(&htim16,TIM_CHANNEL_1);
    //开启输入捕获中断
    HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);

输入捕获回调函数

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
    //判断是否是TIM3的输入捕获中断
    if(htim->Instance == TIM3)
    {
        //判断是否是通道一
        if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1)
        {
            PA6.state++;
            if(PA6.state<=10)//测量多次周期和频率
            {
                if(PA6.Flag == 1)//第二次捕获上升沿
                {
                    PA6.Flag = 0;//设置下次为第一次捕获
                    PA6.N_Flag = 0;//失能溢出标志位
                    //读取第二次捕获的计数值
                    PA6.Count = __HAL_TIM_GetCounter(htim);
                    //周期 = 计数值*t
                    //TIM3的时钟源为80MHz,分频为80
                    //一个计数周期为 = 1/(80M/80) = 80.0/80000000.0
                    PA6.Period = (PA6.N*1000+PA6.Count)*(80.0/80000000.0);
                    PA6.Frequency = 1/PA6.Period;
                    PA6.N = 0;//清除溢出计数值
                }
                else//第一次捕获上升沿
                {
                    PA6.N_Flag = 1;//使能溢出标志位
                    PA6.Flag = 1;//设置下次为第二次捕获
                    //第一次捕获清除计数值
                    __HAL_TIM_SetCounter(htim,0);
                }
            }
            else//测量占空比
            {
                PA6.state = 11;
                if(PA6.Flag == 1)
                {
                    PA6.Flag = 0;
                    PA6.N_Flag = 0;
                    PA6.Count = __HAL_TIM_GetCounter(htim);
                    PA6.High_Time = (PA6.N*1000+PA6.Count)*(80.0/80000000.0);
                    PA6.Duty_Cycle = PA6.High_Time/PA6.Period*100;
                    PA6.N = 0;
                    //设置下次捕获上升沿
                    __HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_RISING);
                }
                else
                {
                    PA6.N_Flag = 1;
                    PA6.Flag = 1;
                    __HAL_TIM_SetCounter(htim,0);
                    //设置下次捕获下降沿
                    __HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,TIM_INPUTCHANNELPOLARITY_FALLING);
                }
            }
            //开启下次捕获
            HAL_TIM_IC_Start_IT(&htim3,TIM_CHANNEL_1);
        }
    }
}

定时器中断回调函数

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if(htim->Instance==TIM3)//判断是否是TIM3的溢出中断
    {
        if(PA6.N_Flag == 1)
            PA6.N++;
    }
}

结果演示

到此输入捕获完毕。

如有错误还请指正,谢谢。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值