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,在进行第一次分频时,其计数值(分频频率)为:42MHz2=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);

}
}

posted @ 2019-12-07 17:22  llll5  阅读(893)  评论(0)    收藏  举报