赞
踩
void Timer_Init(void){//第一步:开启外部时钟和外设时钟(注意使用APB1的开启时钟函数,因为TIM2是APB1总线的外设RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//需要额外配置GPIO来驱动对射式红外传感器RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);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);//第二步:选择时基单元的时钟(在stm32f10x_tim.h文件中查找函数)TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x04);//通过ETR引脚的外部时钟模式2配置//时基单元就由外部时钟ETR(查表可知引脚PA0)驱动了//第三步:配置时基单元(在stm32f10x_tim.h文件中查找函数)TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//指定时钟分频TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//指定计数器模式(此处选择向上计数)TIM_TimeBaseInitStructure.TIM_Period = 10 - 1;//指定要在下一次更新事件时加载到ARR自动重新加载寄存器中的周期值 ARR取值[0,65535]TIM_TimeBaseInitStructure.TIM_Prescaler = 1 - 1;//指定用于划分TIM时钟的预分频器值 PSC取值[0,65535]TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//指定重复计数器的值(高级定时器才用得上,本项目给0)TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//初始化时基单元TIM_ClearFlag(TIM2,TIM_FLAG_Update);//第四步:使能更新中断(在stm32f10x_tim.h文件中查找函数)TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//开启了更新中断到NVIC的通路//第五步:配置NVICNVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC优先级分组NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//指定中断通道NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;//指定IRQ通道的抢占优先级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//指定IRQ通道的响应优先级NVIC_Init(&NVIC_InitStructure);//第六步:启动定时器(在stm32f10x_tim.h文件中查找函数)TIM_Cmd(TIM2,ENABLE);//至此定时器就可以开始工作了,当产生更新时,就会触发中断}
void TIM2_IRQHandler(void)//当定时器产生更新中断时,这个函数就会被自动执行{if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)//检查中断标志位{Num ++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断标志位}}
uint16_t Timer_GetCounter(void){return TIM_GetCounter(TIM2);}
//在maic.c文件中定义一个全局变量uint16_t Num//中断函数是在Timer模块里,如果在中断函数里写Num++,那么Num就是跨越不同.c文件的变量了-----------------解决方法一如果想跨文件使用变量,可以在使用变量的那个文件顶部用【extern】声明要用的变量extern uint16_t Num;extern声明变量就是告诉编译器我现在有Num这个变量,请求编译器帮忙在全文件中查找-----------------解决方法二直接将Timer.c文件中的中断服务程序函数TIM2_IRQHandler放在main.c的主函数外定义使用,注释掉原来Timer.c的中断函数//对于定时器而言,这个中断函数就是为别的文件服务的,所以中断函数可以放在使用它的地方
void Timer_Init(void);uint16_t Timer_GetCounter(void);//中断函数不用声明,因为中断函数不需要调用,会自动执行
#include "Timer.h"
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计数器的变化情况}}void TIM2_IRQHandler(void){if(TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)//检查中断标志位{Num ++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//清除中断标志位}}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。