stm32基本定时器
定時器分類
stm32f1系列,8個定時器,基本定時器(TIM6,7)、通用定時器(TIM2,3,4,5)、高級定時器(TIM1,8)。
基本定時器:16位,只能向上計數的定時器,只能定時,沒有外部IO
通用定時器:16位,可以向上/下計數的定時器,可以定時、輸出比較、輸入捕捉,每個定時器有4個外部IO
高級定時器:16位,可以向上/下計數的定時器,可以定時、輸出比較、輸入捕捉、三相電機互補輸出信號,每個定時器有8個外部IO
基本定時器的功能框圖
時鐘源:定時器時鐘TIMxCLK,即內部時鐘CK_INT,經APB1預分頻器分頻提供。
APB1預分頻系數等于1,頻率不變。
庫函數中APB1預分頻的系數是2,即PCLK1=36M,所以定時器時鐘TIMxCLK=36*2=72M。
計數器時鐘CK_CNT:
定時器時鐘經過PSC預分頻器后,即CK_CNT,用來驅動計數器計數。
PSC是16位的預分頻器,可以對定時器時鐘TIMxCLK進行1~65536之間的任何一個數進行分頻。CK_CNT=TIMxCLK/(PSC+1)。
計數器CNT:
CNT是16位的計數器,只能往上計數,最大計數值為65535。當計數達到自動重裝載寄存器的時候產生更新事件,并清零從頭開始計數。
自動重裝載寄存器ARR:
16位寄存器,這里面裝著計數器能計數的最大數值。當計數到這個值的時候,如果使能了中斷,定時器就產生溢出中斷。
定時時間:
定時器的定時時間等于計數器的中斷周期乘以中斷的次數。
計數器在CK_CNT的驅動下,計一個數的時間,1/(TIMxCLK/(PSC+1))=1/(CK_CNT)
產生一次中斷的時間:1/CK_CNT * ARR
在中斷服務程序里面設置一個變量time來記錄中斷的次數。可以計算出定時時間
定時器初始化
typedef struct {uint16_t TIM_Prescaler; /*預分頻器,時鐘源經該預分頻器才是定時器時鐘,它設定TIMx_PSC 寄存器的值。可設置范圍為 0 至 65535,實現 1 至 65536 分頻 */uint16_t TIM_CounterMode; /*計數模式,基本定時器只能是向上計數,即 TIMx_CNT 只能從 0 開始遞增,并且無需初始化。 */uint16_t TIM_Period; /*定時器周期,設定自動重載寄存器的值,在事件生成時更新到影子寄存器。可設置范圍為 0 至 65535。 */ uint16_t TIM_ClockDivision; /*時鐘分頻,設置定時器時鐘 CK_INT 頻率與數字濾波器采樣時鐘頻率分頻比,基本定時器沒有此功能,不用設置*/uint8_t TIM_RepetitionCounter; /*重復計算器,屬于高級控制寄存器專用寄存器位,利用它可以控制輸出 PWM 的個數。基本定時器不用設置 */ } TIM_TimeBaseInitTypeDef;實驗
利用基本定時器 TIM6/7 定時 1s,1s 時間到 LED 翻轉一次。
#define BASIC_TIM_Period 1000-1 //定時器周期,設定自動重載寄存器的值 #define BASIC_TIM_Prescaler 71//預分頻器,時鐘源經該預分頻器才是定時器時鐘設置自動重裝載寄存器ARR的值為1000,設置時鐘預分頻器為71,驅動計數器的時鐘:CK_CNT = CK_INT / (71+1)=1M
計數器計數一次的時間:1/CK_CNT=1us。
計數器計數到ARR=1000 時,產生一次中斷。中斷一次的時間為:1/CK_CNT*ARR=1ms
#ifndef __BSP_TIMEBASE_H #define __BSP_TIMEBASE_H#include "stm32f10x.h"/********************基本定時器TIM參數定義,只限TIM6、7************/ #define BASIC_TIM6 // 如果使用TIM7,注釋掉這個宏即可#ifdef BASIC_TIM6 // 使用基本定時器TIM6 #define BASIC_TIM TIM6 #define BASIC_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd #define BASIC_TIM_CLK RCC_APB1Periph_TIM6 #define BASIC_TIM_Period 1000-1 #define BASIC_TIM_Prescaler 71 #define BASIC_TIM_IRQ TIM6_IRQn #define BASIC_TIM_IRQHandler TIM6_IRQHandler#else // 使用基本定時器TIM7 #define BASIC_TIM TIM7 #define BASIC_TIM_APBxClock_FUN RCC_APB1PeriphClockCmd #define BASIC_TIM_CLK RCC_APB1Periph_TIM7 #define BASIC_TIM_Period 1000-1 #define BASIC_TIM_Prescaler 71 #define BASIC_TIM_IRQ TIM7_IRQn #define BASIC_TIM_IRQHandler TIM7_IRQHandler#endif /**************************函數聲明********************************/void BASIC_TIM_Init(void);#endif /* __BSP_TIMEBASE_H */定義一個全局變量time,每進一次中斷的時候,讓time記錄進入中斷的次數。
實現一個1s的定時,我們只需要判斷 time 是否等于 1000 即可。
1000*1ms=1s
然后把 time清0,重新計數。
#include "stm32f10x.h" #include "bsp_led.h" #include "bsp_TiMbase.h"volatile uint32_t time = 0; // ms 計時變量 /*** @brief 主函數* @param 無 * @retval 無*/ int main(void) {/* led 端口配置 */ LED_GPIO_Config();BASIC_TIM_Init();while(1)//1s 時間到,LED1翻轉一次,并把 time 清 0{if ( time == 1000 ) /* 1000 * 1 ms = 1s 時間到 */{time = 0;/* LED1 取反 */ LED1_TOGGLE; } } }中斷服務程序的最后,要把相應的中斷標志位清除掉。
void BASIC_TIM_IRQHandler (void) {if ( TIM_GetITStatus( BASIC_TIM, TIM_IT_Update) != RESET ) { time++;TIM_ClearITPendingBit(BASIC_TIM , TIM_FLAG_Update); } }進行定時器中斷優先級配置和基本定時器配置。
// 基本定時器TIMx,x[6,7]定時初始化函數#include "bsp_TiMbase.h" // 中斷優先級配置 static void BASIC_TIM_NVIC_Config(void) {NVIC_InitTypeDef NVIC_InitStructure; // 設置中斷組為0NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // 設置中斷來源NVIC_InitStructure.NVIC_IRQChannel = BASIC_TIM_IRQ ; // 設置主優先級為 0NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 設置搶占優先級為3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure); }/** 注意:TIM_TimeBaseInitTypeDef結構體里面有5個成員,TIM6和TIM7的寄存器里面只有* TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的時候只需初始化這兩個成員即可,* 另外三個成員是通用定時器和高級定時器才有.*-----------------------------------------------------------------------------*typedef struct*{ TIM_Prescaler 都有* TIM_CounterMode TIMx,x[6,7]沒有,其他都有* TIM_Period 都有* TIM_ClockDivision TIMx,x[6,7]沒有,其他都有* TIM_RepetitionCounter TIMx,x[1,8,15,16,17]才有*}TIM_TimeBaseInitTypeDef; *-----------------------------------------------------------------------------*/static void BASIC_TIM_Mode_Config(void) {TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;// 開啟定時器時鐘,即內部時鐘CK_INT=72MBASIC_TIM_APBxClock_FUN(BASIC_TIM_CLK, ENABLE);// 自動重裝載寄存器的值,累計TIM_Period+1個頻率后產生一個更新或者中斷TIM_TimeBaseStructure.TIM_Period = BASIC_TIM_Period; // 時鐘預分頻數為TIM_TimeBaseStructure.TIM_Prescaler= BASIC_TIM_Prescaler;// 時鐘分頻因子 ,基本定時器沒有,不用管//TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;// 計數器計數模式,基本定時器只能向上計數,沒有計數模式的設置//TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; // 重復計數器的值,基本定時器沒有,不用管//TIM_TimeBaseStructure.TIM_RepetitionCounter=0;// 初始化定時器TIM_TimeBaseInit(BASIC_TIM, &TIM_TimeBaseStructure);// 清除計數器中斷標志位TIM_ClearFlag(BASIC_TIM, TIM_FLAG_Update);// 開啟計數器中斷TIM_ITConfig(BASIC_TIM,TIM_IT_Update,ENABLE);// 使能計數器TIM_Cmd(BASIC_TIM, ENABLE); }void BASIC_TIM_Init(void) {BASIC_TIM_NVIC_Config();BASIC_TIM_Mode_Config(); }總結
以上是生活随笔為你收集整理的stm32基本定时器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (set)计算集合的并
- 下一篇: stm32 PWM互补输出