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);
}
}