一.定时器定时中断
1.原理
2.硬件
3.程序
此时CK_PSC=72M,定时1s,也就是定时频率为1Hz,所以可以PSC=7200-1,ARR=10000-1。
Timer.c:
#include "stm32f10x.h" // Device headerextern uint16_t Num;//声明跨文件的变量void Timer_Init(void)
{//1.RCC开启时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//2.选择时基单元的时钟源TIM_InternalClockConfig(TIM2);//内部时钟源//3.配置时基单元包括预分频器,自动重装器,计数模式)TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//分频器:1分频TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//计数器:向上计数TIM_TimeBaseInitStructure.TIM_Period = 10000-1;//ARR自动重装器的值TIM_TimeBaseInitStructure.TIM_Prescaler = 7200-1;//PSC预分频器的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器的值(高级定时器才有,我们写0 就好)TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//4.配置输出中断控制,允许更新中断输出到NVICTIM_ClearFlag(TIM2,TIM_FLAG_Update);//清除更新中断标志位,避免刚初始化就进中断TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断,开启更新中断到NVIC的中路//5.配置NVIC,在NVIC中打开定时器中断的通道NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC优先级分组NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//定时器2在NVIC的通道NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);//6.运行控制(启动定时器)TIM_Cmd(TIM2,ENABLE);}void TIM2_IRQHandler(void)//中断函数
{//检查中断标志位:if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET){Num++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}
}
Timer.h:
#ifndef __TIMER_H
#define __TIMER_Hvoid Timer_Init(void);#endif
main.c:
#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:");//显示字符串while(1){OLED_ShowNum(2,1,Num,5);OLED_ShowNum(3,1,TIM_GetCounter(TIM2),5);//看计数器}
}
二.外部定时器中断
1.硬件
2.程序
Timer.c:
#include "stm32f10x.h" // Device headerextern uint16_t Num;//声明跨文件的变量void Timer_Init(void)
{//1.RCC开启时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//2.配置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);//3.选择时基单元的时钟源TIM_ETRClockMode2Config(TIM2,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0x0F);//通过ETR引脚的外部时钟模式2配置//TIM_ExtTRGPSC_OFF:外部触发预分频器:不需要分频//TIM_ExtTRGPolarity_NonInverted:外部触发的极性:不反向,高电平或上升沿有效//0x0F:外部触发滤波器:0x00时CNT变太快(看手册选值)//4.配置时基单元包括预分频器,自动重装器,计数模式)TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;//分频器:1分频TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//计数器:向上计数TIM_TimeBaseInitStructure.TIM_Period = 10-1;//ARR自动重装器的值TIM_TimeBaseInitStructure.TIM_Prescaler = 1-1;//PSC预分频器的值TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;//重复计数器的值(高级定时器才有,我们写0 就好)TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);//5.配置输出中断控制,允许更新中断输出到NVICTIM_ClearFlag(TIM2,TIM_FLAG_Update);//清除更新中断标志位,避免刚初始化就进中断TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//使能中断,开启更新中断到NVIC的中路//6.配置NVIC,在NVIC中打开定时器中断的通道NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//NVIC优先级分组NVIC_InitTypeDef NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//定时器2在NVIC的通道NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);//7.运行控制(启动定时器)TIM_Cmd(TIM2,ENABLE);}uint16_t Timer_GetCounter(void)
{return TIM_GetCounter(TIM2);
}void TIM2_IRQHandler(void)//中断函数
{//检查中断标志位:if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET){Num++;TIM_ClearITPendingBit(TIM2,TIM_IT_Update);}
}
Timer.h:
#ifndef __TIMER_H
#define __TIMER_Hvoid Timer_Init(void);
uint16_t Timer_GetCounter(void);#endif
main.c:
#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);//看计数器}
}