實(shí)驗(yàn)具體內(nèi)容
- 通用定時(shí)器由預(yù)分頻器(PSC)和16位的自動(dòng)裝載寄存器(CNT)構(gòu)成
- 利用內(nèi)部時(shí)鐘產(chǎn)生時(shí)鐘,然后進(jìn)行預(yù)分頻,自動(dòng)裝載寄存器以及計(jì)數(shù)器的配置。計(jì)數(shù)器向上計(jì)數(shù),從0計(jì)數(shù)到100,到100后產(chǎn)生一個(gè)中斷,中斷服務(wù)函數(shù)控制LED燈的翻轉(zhuǎn)。
- 通過定時(shí)器中斷配置,每500ms(溢出時(shí)間)中斷一次,然后中斷服務(wù)函數(shù)中控制LED實(shí)現(xiàn)LED1狀態(tài)取反(閃爍)。
Tout(溢出時(shí)間)=(ARR+1)(PSC+1)/Tclk
Tclk:時(shí)鐘頻率(因?yàn)橛玫南到y(tǒng)時(shí)鐘所以頻率為72M)
Tclk/(PSC+1):定時(shí)器一個(gè)周期的時(shí)間長(zhǎng)度(PSC設(shè)置為7199,這樣定時(shí)器時(shí)鐘即10K,一個(gè)時(shí)鐘周期即為0.1MS)
ARR+1:自動(dòng)裝載值大小(ARR為4999)
時(shí)鐘選擇:

時(shí)鐘計(jì)算方法

除非APB1的分頻系數(shù)是1,否則通用定時(shí)器的時(shí)鐘等于APB1時(shí)鐘的2倍。
默認(rèn)調(diào)用SystemInit函數(shù)情況下:
SYSCLK=72M
AHB時(shí)鐘=72M
APB1時(shí)鐘=36M
所以APB1的分頻系數(shù)=AHB/APB1時(shí)鐘=2
所以,通用定時(shí)器時(shí)鐘CK_INT=2*36M=72M
(這里CK_PSC即為CK_INT)
PSC的預(yù)分頻系數(shù)N是CK_PSC寄存器的值加1的所得
最后分頻得到CK_CNT即為定時(shí)器最后的時(shí)鐘
計(jì)數(shù)器模式舉例
向上計(jì)數(shù)模式(時(shí)鐘分頻因子=1:即CK_PSC=CK_CNT)

首先使能定時(shí)器CNT_EN
使能之后計(jì)數(shù)器開始計(jì)數(shù),假設(shè)自動(dòng)裝載值為36,計(jì)數(shù)到36后會(huì)產(chǎn)生一個(gè)溢出,然后會(huì)有一個(gè)更新事件,產(chǎn)生一個(gè)更新中斷標(biāo)志,這時(shí)如果使能了中斷就可以執(zhí)行中斷服務(wù)函數(shù),定時(shí)器繼續(xù)從0開始計(jì)數(shù)。
重要寄存器
-
計(jì)數(shù)器當(dāng)前值寄存器CNT
-
預(yù)分頻寄存器TIMx_PSC
-
自動(dòng)重裝載寄存器(TIMx_ARR)
-
控制寄存器1(TIMx_CR1)
-
DMA中斷使能寄存器(TIMx_DIER)
常用庫(kù)函數(shù)
- 定時(shí)器參數(shù)初始化:
void TIM _TimeBaseInit(TIM_TypeDef*TIMx,TIM_TimeBaseInitTypeDef*TIM_TimeBaseInitStruct);
typedef struct
{
uint16_t TIM_Prescaler; //預(yù)分頻系數(shù)
uint16_t TIM_CounterMode; //計(jì)數(shù)模式
uint16_t TIM_Period; //自動(dòng)裝載值
uint16_t TIM_ClockDivision;
uint8_t TIM_RepetitionCounter;
} TIM_TimeBaseInitTypeDef;
- 定時(shí)器使能函數(shù):(操作CR1寄存器的位0來使能定時(shí)器)
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)
- 定時(shí)器中斷使能函數(shù)(操作DIER寄存器位0使能更新中斷):
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
- 狀態(tài)標(biāo)志位獲取和清除:
FlagStatus TIM_GetFlagStatus(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
void TIM_ClearFlag(TIM_TypeDef* TIMx, uint16_t TIM_FLAG);
ITStatus TIM_GetITStatus(TIM_TypeDef* TIMx, uint16_t TIM_IT);
void TIM_ClearITPendingBit(TIM_TypeDef* TIMx, uint16_t TIM_IT);
定時(shí)器中斷實(shí)現(xiàn)的步驟
- 使能定時(shí)器時(shí)鐘。
RCC_APB1PeriphClockCmd(); - 初始化定時(shí)器,配置ARR,PSC。
TIM_TimeBaseInit(); - 開啟定時(shí)器中斷,配置NVIC。
void TIM_ITConfig();
NVIC_Init();//在主函數(shù)中設(shè)置中斷優(yōu)先級(jí)分組 - 使能定時(shí)器。
TIM_Cmd(); - 編寫中斷服務(wù)函數(shù)。
TIMx_IRQHandler();
實(shí)驗(yàn)代碼
- timer.h
#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h"
void TIM3_Int_Init(u16 arr,u16 psc);
#endif
- timer.c
#include "timer.h"
#include "led.h"
//通用定時(shí)器中斷初始化
//這里時(shí)鐘選擇為APB1的2倍,而APB1為36M
//arr:自動(dòng)重裝值。
//psc:時(shí)鐘預(yù)分頻數(shù)
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //時(shí)鐘使能
TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在下一個(gè)更新事件裝入活動(dòng)的自動(dòng)重裝載寄存器周期的值 計(jì)數(shù)到5000為500ms
TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置用來作為TIMx時(shí)鐘頻率除數(shù)的預(yù)分頻值 10Khz的計(jì)數(shù)頻率
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計(jì)數(shù)模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時(shí)間基數(shù)單位
TIM_ITConfig( //使能指定的TIM中斷
TIM3, //TIM3
TIM_IT_Update ,//更新中斷
ENABLE //使能
);
//設(shè)置中斷優(yōu)先級(jí)
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占優(yōu)先級(jí)0級(jí)
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //從優(yōu)先級(jí)3級(jí)
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根據(jù)NVIC_InitStruct中指定的參數(shù)初始化外設(shè)NVIC寄存器
TIM_Cmd(TIM3, ENABLE); //使能TIM3外設(shè)
}
//中斷服務(wù)函數(shù)
void TIM3_IRQHandler(void) //TIM3中斷
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) //檢查指定的TIM中斷發(fā)生與否:TIM 中斷源 ,=1
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx的中斷待處理位:TIM 中斷源
LED1=!LED1;
}
}
- main.c
#include "delay.h"
#include "sys.h"
#include "timer.h"
int main(void)
{
delay_init(); //延時(shí)函數(shù)初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 設(shè)置中斷優(yōu)先級(jí)分組2
LED_Init(); //初始化與LED連接的硬件接口
TIM3_Int_Init(4999,7199);//10Khz的計(jì)數(shù)頻率,計(jì)數(shù)到5000為500ms
while(1)
{
LED0=!LED0;
delay_ms(200);
}
}




