32-TIM输入捕获

 注意与输出比较区分。

频率测量方法

测频法实现:例如使用红外传感器,每个上升沿计次加一,再用一个定时器,定1S的定时中断,在中断里,每隔一秒取一下计次值,同时清零计次,所计的值就是频率。

 

 

 

 

主从触发模式(TRGO、TRGI)

 主模式将定时器内部的引脚映射到TRGO,用于触发别的外设。

从模式接受其他外设的信号,用于控制自身定时器的运行。

 

GPIO的输入信号,经滤波器和极性选择,TI1FP1信号兵分两路,CNT的值转运到CCR中,同时CNT清零(从模式完成)。

 

PWMI使用两个通道,可以同时测量频率和占空比,CCR2是高电平期间的CNT的计数值,CCR1是整个周期的计数值,那么使用CCR2/CCR1就能得到占空比,使用CCR1可以得到频率。

 

代码

在PA0产生一个PWM信号,然后PA6进行输入捕获,测量输入信号的占空比、频率。

复制代码
void PWM_Init()
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    
    TIM_InternalClockConfig(TIM2);//选择使用内部时钟
    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInitStruct.TIM_Period=100 -1;  //ARR  自动重装载         在这里固定ARR的值为100,下面利用单独的函数修改PSC的值
    TIM_TimeBaseInitStruct.TIM_Prescaler=720 -1;  //PSC  预分频器
    TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
    TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct);//配置时基单元
    
    TIM_OCInitTypeDef TIM_OCInitStruct;
    TIM_OCStructInit(&TIM_OCInitStruct);
    TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1;
    TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High;
    TIM_OCInitStruct.TIM_Pulse=50;  //CCR     
    TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;
    TIM_OC1Init(TIM2,&TIM_OCInitStruct);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //如果想用片上外设(这里是定时器)来控制引脚,需要使用复用推挽开漏输出模式
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    TIM_Cmd(TIM2,ENABLE);//使能定时器
}

void PWM_TIM_SetCompare1(uint16_t Compare)     //重新写入CCR的值
{
    TIM_SetCompare1(TIM2,Compare);
}

void PWM_SetPSC(uint16_t PSC)     //重新写入PSC的值
{
    TIM_PrescalerConfig(TIM2,PSC,TIM_PSCReloadMode_Immediate);
}
复制代码

首先,需要打开GPIOA和复用功能时钟的使能,以及TIM2时钟的使能。

 然后,需要初始化PA0口为复用推挽输出模式。

接着,需要初始化TIM2的基本定时器参数,包括自动重装值、分频系数、时钟分割和计数模式等。

接下来,需要初始化TIM2的PWM输出参数,包括PWM模式、输出使能、极性和初始占空比等。

最后,需要使能TIM2。

在主函数中调用两个独立函数分别设置CCR和PSC的值,这样,就可以在PA0口产生一个占空比为50%,频率为1KHZ的PWM信号了。

接下来写输入捕获部分的代码(根据上图)

第一步开启GPIO和TIM时钟

第二步GPIO初始化,配置成输入模式

第三步配置时基单元,让CNT在内部时钟的驱动下自增运行

第四步配置输入捕获单元,包括滤波器、极性、直连还是交叉通道、分频器等参数

第五步选择从模式的触发源,并选择触发之后的操作,用于复位

最后开启定时器即可

 

复制代码
void IC_Init(void)
{
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    
    TIM_InternalClockConfig(TIM3);//选择使用内部时钟
    
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    TIM_TimeBaseInitStruct.TIM_ClockDivision=TIM_CKD_DIV1;
    TIM_TimeBaseInitStruct.TIM_CounterMode=TIM_CounterMode_Up;
    TIM_TimeBaseInitStruct.TIM_Period=65536 -1;  //ARR  自动重装载        
    TIM_TimeBaseInitStruct.TIM_Prescaler=720 -1;  //PSC  预分频器
    TIM_TimeBaseInitStruct.TIM_RepetitionCounter=0;
    TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStruct);//配置时基单元
    
    TIM_ICInitTypeDef TIM_ICInitStruct;
    TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;  //
    TIM_ICInitStruct.TIM_ICFilter=0xF;  //滤波
    TIM_ICInitStruct.TIM_ICPolarity=TIM_ICPolarity_Rising;  //上升沿触发
    TIM_ICInitStruct.TIM_ICPrescaler=TIM_ICPSC_DIV1;   //不分频
    TIM_ICInitStruct.TIM_ICSelection=TIM_ICSelection_DirectTI;  //选择直连通道
    TIM_ICInit(TIM3,&TIM_ICInitStruct);
    
    TIM_SelectInputTrigger(TIM3,TIM_TS_TI1FP1);
    TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);
    
    TIM_Cmd(TIM3,ENABLE);
}
复制代码

 

posted @   要是天天吃鱼就好了  阅读(73)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示