一、定時器
1. 定義
設置等待時間,到達后則執行指定操作的硬件。
2. STM32F407的定時器有以下特征
具有基本的定時功能,也有PWM輸出(燈光控制、電機的轉速)、脈沖捕獲功能(紅外捕捉)。
2個高級控制定時器、10個通用定時器和2個基本定時器
高級控制定時器(TIM1和TIM8)
具有16位定時器功能,也具有PWM輸出高級控制功能
通用定時器(TIM2到TIM5)
具有16位定時功能,也具有PWM輸出控制功能
通用定時器(TIM9到TIM14)
具有16位定時功能,也具有PWM輸出控制功能
基本定時器(TIM6和TIM7)
具有16位定時功能
二、定時器初始化
1. 選擇時鍾源,並初始化定時器分頻值與定時時間
/* TIM3 clock enable ,定時器3時鍾使能*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* Time base configuration ,定時器基本配置*/ TIM_TimeBaseStructure.TIM_Period = (10000/1000)-1; //定時時間的設置[非常重要],中斷頻率為1000Hz,也就是定時時間為1ms TIM_TimeBaseStructure.TIM_Prescaler = 8400-1; //預分頻值 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //時鍾分頻,也稱之為二次分頻,當前是1分頻,說白了不分頻,不降低頻率 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上計數的方法 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //初始化
涉及部分寄存器參考如下



1. 中斷的配置
/* TIM Interrupts enable,使能定時器3更新中斷事件,也代表說定時已經到達的事件 */ TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); /* TIM3 enable counter,使能定時器3工作 */ TIM_Cmd(TIM3, ENABLE);
2. 中斷服務函數的編寫
void TIM3_IRQHandler(void) { static uint32_t cnt=0; //是否已經有更新中斷事件 if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) { //添加用戶代碼 cnt++; if(cnt>=500) { cnt =0; PFout(9)^=1; } //清空標志位,告訴CPU我已經完成中斷處理 TIM_ClearITPendingBit(TIM3, TIM_IT_Update); } }
TIM3
#include <stdio.h> #include "stm32f4xx.h" #include "sys.h" GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; void tim3_init(void) { /* TIM3 clock enable ,定時器3時鍾使能*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); /* Enable the TIM3 gloabal Interrupt ,使能定時器3全局中斷*/ NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Time base configuration ,定時器基本配置*/ TIM_TimeBaseStructure.TIM_Period = (10000/1000)-1; //定時時間的設置[非常重要],中斷頻率為1000Hz,也就是定時時間為1ms TIM_TimeBaseStructure.TIM_Prescaler = 8400-1; //預分頻值 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //時鍾分頻,也稱之為二次分頻,當前是1分頻,說白了不分頻,不降低頻率 TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上計數的方法 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //初始化 /* TIM Interrupts enable,使能定時器3更新中斷事件,也代表說定時已經到達的事件 */ TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); /* TIM3 enable counter,使能定時器3工作 */ TIM_Cmd(TIM3, ENABLE); } int main(void) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); /* 配置PF9引腳為輸出模式 */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //第9根引腳 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; //設置輸出模式 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽模式,增加驅動電流 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //設置IO的速度為100MHz,頻率越高性能越好,頻率越低,功耗越低 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //不需要上拉電阻 GPIO_Init(GPIOF, &GPIO_InitStructure); PFout(9)=1; //定時器3初始化 tim3_init(); while(1) { } } void TIM3_IRQHandler(void) { static uint32_t cnt=0; //是否已經有更新中斷事件 if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) { //添加用戶代碼 cnt++; if(cnt>=500) { cnt =0; PFout(9)^=1; } //清空標志位,告訴CPU我已經完成中斷處理 TIM_ClearITPendingBit(TIM3, TIM_IT_Update); } }
tim1238_irq
#include "stm32f4xx.h" #include "stdio.h" #include "bitband.h" GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; void tim1_init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //定時時間為100ms 168000000/16800=10000Hz TIM_TimeBaseStructure.TIM_Period = (10000/10)-1; TIM_TimeBaseStructure.TIM_Prescaler = 16800-1; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE); TIM_Cmd(TIM1, ENABLE); } void tim2_init(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //定時時間為200ms 84000000/84000=10000Hz TIM_TimeBaseStructure.TIM_Period = (10000/5)-1; TIM_TimeBaseStructure.TIM_Prescaler = 8400-1; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); TIM_Cmd(TIM2, ENABLE); } void tim3_init(void) { RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //定時時間為500ms 84000000/84000=10000Hz TIM_TimeBaseStructure.TIM_Period = (10000/2)-1; TIM_TimeBaseStructure.TIM_Prescaler = 8400-1; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); TIM_Cmd(TIM3, ENABLE); } void tim8_init(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); //定時時間為2秒 168000000/168000=10000Hz TIM_TimeBaseStructure.TIM_Period = (10000*2)-1; TIM_TimeBaseStructure.TIM_Prescaler = 16800-1; TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure); TIM_ITConfig(TIM8, TIM_IT_Update, ENABLE); TIM_Cmd(TIM8, ENABLE); } int main(void) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF | RCC_AHB1Periph_GPIOE, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOF, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(GPIOE, &GPIO_InitStructure); PFout(9) = 1; PFout(10) = 1; PEout(13) = 1; PEout(14) = 1; tim1_init(); tim2_init(); tim3_init(); tim8_init(); while(1) { } } void TIM1_UP_TIM10_IRQHandler(void) { if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET) { PFout(9) ^= 1; TIM_ClearITPendingBit(TIM1, TIM_IT_Update); } } void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { PFout(10) ^= 1; TIM_ClearITPendingBit(TIM2, TIM_IT_Update); } } void TIM3_IRQHandler(void) { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) { PEout(13) ^= 1; TIM_ClearITPendingBit(TIM3, TIM_IT_Update); } } void TIM8_UP_TIM13_IRQHandler(void) { if (TIM_GetITStatus(TIM8, TIM_IT_Update) != RESET) { PEout(14) ^= 1; TIM_ClearITPendingBit(TIM8, TIM_IT_Update); } }
