![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
2 NVIC_InitTypeDef NVIC_InitStructure;
3 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
4 //!!!!!定时器3,用于产生标准时长的对外部脉冲计数的窗口,从而计算外部脉冲的频率!!!!!//
5 TIM_TimeBaseStructure.TIM_Period = arr-1; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000
6 TIM_TimeBaseStructure.TIM_Prescaler =(psc-1); //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率
7 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
8 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
9 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
10 TIM_ITConfig( //使能或者失能指定的TIM中断
11 TIM3, //TIM3
12 TIM_IT_Update, //数值溢出更新中断
13 ENABLE //使能
14 );
15 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
16 NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM2更新中断
17 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
18 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //从优先级3级
19 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
20 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
21 TIM_SetCounter(TIM3,0);
22 TIM_Cmd(TIM3, ENABLE); //使能TIMx外设
配置用于产生标准时长的TIM3
3)配置用于对外部被测脉冲进行计数的TIM2的时基单元和中断
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//!!!!!初始化定时器2,用于对外部被测脉冲进行计数!!!!!//
void Timer2_Init(void)//(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //时钟使能
TIM_TimeBaseStructure.TIM_Period = 65535;//设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000
TIM_TimeBaseStructure.TIM_Prescaler =0;
//设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_ITConfig( //使能或者失能指定的TIM中断
TIM2, //TIM2
TIM_IT_Update, //TIM 中断源
ENABLE //使能
);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM2更新中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_TIxExternalClockConfig(TIM2,TIM_TIxExternalCLK1Source_TI2,TIM_ICPolarity_Falling,0);
//选择外部输入作为TIM2的时钟
TIM_SetCounter(TIM2,0);//设置TIM2计数初值为0
TIM_Cmd(TIM2, ENABLE); //使能TIMx外设
}
配置用于对外部脉冲计数的TIM2
上面的代码中TIM2被配置为对外部时钟进行计数的计数器,当标准时间Tc1到到达后,TIM2计数的值就是测频法计数得到的数值。但为了对付计数器TIM2在标准时间Tc1完成之前就发生溢出从而造成计数值错误的情况,上面的代码还使用了TIM2中断。
4)计数器TIM2溢出中断服务程序
TMR2中断服务程序要做的事,是在TIM2计数器溢出后对溢出次数进行计数(溢出计数由软件完成,计数器为全局变量top_watch)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 unsigned short top_watch=0;//用于在顶层对外部脉冲计数器溢出次数进行计数
2 void TIM2_IRQHandler(void) //TIM2中断,产生标准时间
3 {
4 if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
5 {
6 TIM_ClearITPendingBit(TIM2, TIM_IT_Update ); //清除TIMx的中断待处理位:TIM 中断源
7 top_watch++;
8 }
9 }
计数器TIM2中断服务程序
5)标准时长定时器TIM3的中断服务程序
最后我们只需要在标准时长Tc1到达时——也就是TIM3定时器发生中断时,读取Tc1内的脉冲数计算即可(通过函数TIM_GetCounter(TIM2);)。
|