09、硬件定时器

定义

设置等待时间,到达后则执行指定操作的硬件。

STM32F407 的定时器有以下特征

具有基本的定时功能,也有 PWM 输出(灯光亮度控制、电机的转速)、脉冲捕获功能(红外捕捉)。

2 个高级控制定时器、10 个通用定时器和 2 个基本定时器
高级控制定时器(TIM1 和 TIM8)
    具有 16 位定时器功能,也具有 PWM 输出高级控制功能,一个定时器支持多路的 PWM 输出。
通用定时器(TIM2 到 TIM5)
    具有 16 位定时功能,也具有 PWM 输出控制功能,一个定时器支持 1 路的 PWM 输出。
通用定时器(TIM9 到 TIM14)
    具有 16 位定时功能,也具有 PWM 输出控制功能,一个定时器支持 1 路的 PWM 输出。
基本定时器(TIM6 和 TIM7)
    具有 16 位定时功能。

注:
1)TIM 是 TIMER 英文的缩写。

2)通用定时器与高级控制定时器

1.硬件定时器的外部晶振额定频率是168MHz,它分为高级设备总线1(低速总线1)和高级设备总线2(低速总线2)
    
    高级设备总线1:168Mhz/4=42MHz,在进行第一次分频时,其计数值(分频频率)为:42MHz*2=84MHz/硬件时钟频率(10000)-1
    高级设备总线1:168Mhz/2=84MHz,在进行第一次分频时,其计数值(分频频率)为:84MHz*2=168MHz/硬件时钟频率(10000)-1


若定时器3的硬件时钟频率为10000Hz,最大的定时时间?

1000ms     Tmax
------- = ------- 
10000      65536

#include <stdio.h>
#include "stm32f4xx.h"
#include "sys.h"


static GPIO_InitTypeDef		GPIO_InitStruct;
static TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

static NVIC_InitTypeDef		NVIC_InitStructure;

void delay_us(uint32_t nus)
{

	SysTick->CTRL = 0;							// 关闭系统定时器
	SysTick->LOAD = nus*(SystemCoreClock/1000000); 	// nus *1us延时,这个计数值
	SysTick->VAL = 0; 							// 清空标志位
	SysTick->CTRL = 5; 							// 使能系统定时器工作,时钟源为系统时钟168MHz
	while ((SysTick->CTRL & 0x00010000)==0);	// 检查CTRL寄存器的16bit是否置1,若置1,就代表计数完毕
	SysTick->CTRL = 0; 							// 关闭系统定时器	
}

void delay_ms(uint32_t nms)
{

	while(nms--)
	{
	
		SysTick->CTRL = 0;							// 关闭系统定时器
		SysTick->LOAD = (SystemCoreClock/1000); 	// 1ms延时,这个计数值
		SysTick->VAL = 0; 							// 清空标志位
		SysTick->CTRL = 5; 							// 使能系统定时器工作,时钟源为系统时钟168MHz
		while ((SysTick->CTRL & 0x00010000)==0);	// 检查CTRL寄存器的16bit是否置1,若置1,就代表计数完毕
		SysTick->CTRL = 0; 							// 关闭系统定时器	
	
	}
}


void tim1_init(void)
{

	//使能定时器1硬件时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
	

	
	TIM_TimeBaseStructure.TIM_Period = (10000/10)-1;			//定时时间的配置,也就是配置计数值
	TIM_TimeBaseStructure.TIM_Prescaler = 16800-1;				//配置分频值,确定定时器的时钟频率
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;	//向上计数,0->TIM_Period就会触发中断请求
	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
	

	
	//使能定时器中断
	TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
	
	
	//配置定时器优先级			
	NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;	//定时器1的中断号
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	//抢占优先级0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;			//响应优先级1
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//使能
	NVIC_Init(&NVIC_InitStructure);
	
	
	//使能定时器工作
	TIM_Cmd(TIM1,ENABLE);
}

void tim3_init(void)
{

	//使能定时器3硬件时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
	

	
	TIM_TimeBaseStructure.TIM_Period = (10000/2)-1;				//定时时间的配置,也就是配置计数值
	TIM_TimeBaseStructure.TIM_Prescaler = 8400-1;				//配置分频值,确定定时器的时钟频率
	//TIM_TimeBaseStructure.TIM_ClockDivision = 0;				//时钟分频(第二次分频),但F407是没有该分频
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;	//向上计数,0->TIM_Period就会触发中断请求
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
	

	
	//使能定时器中断
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
	
	
	//配置定时器优先级			
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;				//定时器3的中断号
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;	//抢占优先级0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;			//响应优先级1
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//使能
	NVIC_Init(&NVIC_InitStructure);
	
	
	//使能定时器工作
	TIM_Cmd(TIM3,ENABLE);
}


//主函数
int main(void)
{
	
	//使能端口F的硬件时钟,端口F才能工作,说白了就是对端口F上电
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);	
	

	//配置硬件,配置GPIO,端口F,第9 10个引脚
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_10;			//第9 10个引脚
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_OUT;		//输出模式
	GPIO_InitStruct.GPIO_Speed=GPIO_High_Speed;		//引脚高速工作,收到指令立即工作;缺点:功耗高
	GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;		//增加输出电流的能力
	GPIO_InitStruct.GPIO_PuPd=GPIO_PuPd_NOPULL;		//不需要上下拉电阻
	GPIO_Init(GPIOF,&GPIO_InitStruct);

	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	//tim3_init();
	
	tim1_init();
	
	PFout(9)=PFout(10)=1;
	
	while(1)
	{
		//PFout(9)^=1;
		//delay_ms(2000);
		
	}
}

void TIM1_UP_TIM10_IRQHandler(void)
{

	//检查定时器1是否有时间更新中断
	if(TIM_GetITStatus(TIM1,TIM_IT_Update) == SET)
	{
	
		PFout(9)^=1;
		
		//清空标志位
		TIM_ClearITPendingBit(TIM1,TIM_IT_Update);	
	
	}
}


void TIM3_IRQHandler(void)
{

	//检查定时器3是否有时间更新中断
	if(TIM_GetITStatus(TIM3,TIM_IT_Update) == SET)
	{
	
	
		
		//清空标志位
		TIM_ClearITPendingBit(TIM3,TIM_IT_Update);	
	
	}
}
原文地址:https://www.cnblogs.com/lp06/p/12002631.html