1.实验现象如下:
不设置预分频前提下,遮挡一次,CNT+1,遮挡几次就加几。+9后,再+,NUM++,CNT==0。
2.代码部分:
主函数部分:
#include "stm32f10x.h" // Device header #include "Delay.h" #include "OLED.h" #include "Timer.h" uint16_t Num; int main(void) { OLED_Init(); Timer_Init(); OLED_ShowString(1, 1, "Num:"); OLED_ShowString(2, 1, "CNT:"); while(1) { OLED_ShowNum(1,5,Num,5); OLED_ShowNum(2,5,Timer_GetCounter(),5); //不设置预分频前提下,遮挡一次,CNT+1,遮挡几次就加几。+9后,再+,NUM++,CNT==0 } } //中断函数:当进入中断,自动执行该函数 void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)//获取中断标志位 { Num++; TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除标志位 } }
定时器外部函数(源文件部分):
#include "stm32f10x.h" // Device header void Timer_Init(void)//初始化定时器---过程查看定时器中断基本结构. //在Library中tim.h定义许多库函数,需要充分学习和使用,此处写几个用到的,重要的 { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//第一步:开启APB1时钟,因为TIM2是APB1总线的外设 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//开启,配置GPIO GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); //第二步:选择时基单元的时钟(外部时钟) TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00); //参数2:外部触发预分频器,可以是TIM_ExtTRGPSC_OFF,不分频;TIM_ExtTRGPSC_DIV2二分频...此处选择不分频即可 //参数3:外部触发极性,可以是TIM_ExtTRGPolarity_Inverted反向,即低电平或下降沿有效。 // 可以是TIM_ExtTRGPolarity_NonInverted不反向,高电平或上升沿有效。选择不反向即可。 //参数4:外部触发滤波器,必须是0x00到0x0f直接。决定f和N,参考手册有。不需要滤波器选择0x00。 //第三步:配置时基单元----TIM_TimeBaseInit的第二个参数是结构体,配置结构体 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; //TIM_CKD_DIV1,1分频,不分配;TIM_CKD_DIV2,2分频;TIM_CKD_DIV4,4分频----要求不高时,随意选择 TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //TIM_CounterMode_Up向上计数;TIM_CounterMode_Down向下计数;TIM_CounterMode_CenterAligned1等为中央对齐 TIM_TimeBaseInitStructure.TIM_Period=10-1;//手动模拟自动重装值要小 TIM_TimeBaseInitStructure.TIM_Prescaler=1-1;//预分频 TIM_TimeBaseInitStructure.TIM_RepetitionCounter=0;//高级定时器用到,通用定时器选0 TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//结构体 //第四步:使能中断 TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //第五步:NVIC中断 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级 NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;//响应优先级 NVIC_Init(&NVIC_InitStructure); //第六部分:启动定时器 TIM_Cmd(TIM2,ENABLE); } //实时观看CNT计数器的值 uint16_t Timer_GetCounter(void) { return TIM_GetCounter(TIM2); }
定时器外部函数(头文件部分):
#ifndef __TIMER_H #define __TIMER_H void Timer_Init(void); uint16_t Timer_GetCounter(void); #endif
3.注意事项:
定时器外部中断函数和定时器定时中断类似,只是将内部中断函数换为了外部中断,如图:
且外部时钟使用时,需要配置GPIO,如下:
CNT是用来反馈外部时钟被使用情况,需要如下设置:
其他部分基本与定时器中断一致。