stm32f103c8t6输入捕捉模式精细测信号频率
#include "stm32f10x.h"
#include "usart.h"
#include "delay.h"
int num,num1;//记录第一次捕获中断和第二次捕捉中断寄存器值
int sum,n=0;//sum:记录所测信号一个周期计数器记了多少个数。n:做第一次和第二次的捕捉中断判断。
int main(void)
{
GPIO_InitTypeDef GPIO_Structure; //GPIO初始化
TIM_TimeBaseInitTypeDef TIM_TimeStructure;//时钟初始化
TIM_ICInitTypeDef TIM_ICTypeDef;//时钟输入捕捉通道初始化
NVIC_InitTypeDef NVIC_InitStruct;//中断初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能GPIOA
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);//使能TIM2
uart_init(9600);//初始化串口,波特率9600
delay_init();
My_PWMTIM3_Init(1999,71);//自己写的一个输出pwm波的一个库,引脚PA6输出周期为2000us的脉冲
TIM_SetCompare1(TIM3,1500);//设置比较值
GPIO_Structure.GPIO_Pin = GPIO_Pin_1;
GPIO_Structure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入,输入捕捉模式需要将具体引脚调为浮空输入
GPIO_Structure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_Structure);
TIM_TimeStructure.TIM_ClockDivision=TIM_CKD_DIV1;//分频因子
TIM_TimeStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数
TIM_TimeStructure.TIM_Period=0xFFFF;//自动重装载值
TIM_TimeStructure.TIM_Prescaler=71;//预分频系数
TIM_TimeBaseInit(TIM2, &TIM_TimeStructure);
TIM_ICTypeDef.TIM_Channel=TIM_Channel_2;//PA1/T2.2
TIM_ICTypeDef.TIM_ICPolarity=TIM_ICPolarity_Rising;//上升沿捕捉
TIM_ICTypeDef.TIM_ICSelection=TIM_ICSelection_DirectTI;//映射一波
TIM_ICTypeDef.TIM_ICPrescaler=TIM_ICPSC_DIV1;//不分频
TIM_ICTypeDef.TIM_ICFilter=0x00;//不滤波
TIM_ICInit(TIM2,&TIM_ICTypeDef);
TIM_ITConfig(TIM2,TIM_IT_CC2,ENABLE);//开启CC2中断
NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0; //抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1; //响应优先级
NVIC_Init(&NVIC_InitStruct);
TIM_Cmd(TIM2,ENABLE);
while(1)
{ printf("%d ",sum);//让串口每隔0.5秒打印测得周期值
delay_ms(500);}
}
void TIM2_IRQHandler(void)
{
if(TIM_GetITStatus(TIM2,TIM_IT_CC2) != RESET&&n==0)//第一个上升沿
{ num=TIM2->CCR2;//记录第一次捕捉比较寄存器值
n++;
}
if(TIM_GetITStatus(TIM2,TIM_IT_CC2) != RESET&&n==1)//第二个上升沿
{ num1=TIM2->CCR2;//记录第二次捕捉比较寄存器值
n=0;//n清零
if(num-num1>50000)
sum=65535-num+num1;
else
sum=num1-num;}//最后一点判断的关键我会在文章中讲解
}
//
//
//name:Vincent njw QQ:1504012979 glut
一,硬件19
stm32f103c8t6,ch340模块
二,软件
具体操作我在代码段有详细的注释,我觉得比较重要的一点是对于单片机时钟的配置思想,也很简单,第一步更改对应引脚模式,第二设定计时器计数模式,第三设定计时器工作模式,第四如果需要中断可以设定中断,并写好对应的中断服务函数。切记!勿忘了在设定定时器模式之后要开启时钟。
接下来给大家讲为什么在中断函数最后加一个判断的原因,我设定的计数器模式为向上计数模式,最大值是65535。我们可以想象这样一种情况,当计数器记到65534时,此时进行了第一个上升沿的捕捉,往后在过1us,定时器的值会自动清零,假设我们所测的信号周期为20us,那么第二次的上升沿捕捉就是在计数器记到19的位置,此时第二次记录的值减去第一次记录的值显然不等于20us,此时就需要一个判断,把第一次的值减去第二次的值,假如大于50000,那么对于周期较小的信号来说,必然是发生了溢出,此时我们用65535减去第一次的捕捉值加上第二次捕捉值即为信号周期。