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

猜你喜欢

转载自www.cnblogs.com/lp06/p/12002631.html