一、簡介
*定時器可以對輸入的時鐘進行計數,并在計數值達到設定值時觸發中斷
*16位計數器、預分頻器、自動重裝寄存器的時基單元,在72MHz計數時鐘下可以實現最大59.65s的定時?
*不僅具備基本的定時中斷功能,而且還包含內外時鐘源選擇、輸入捕獲、輸出比較、編碼器接口、主從觸發模式等多種功能
*根據復雜度和應用場景分為了高級定時器、通用定時器、基本定時器三種類型
二、定時器區別
1.通用定時器的特點描述
1.位于ABP1低速總線上
2.16位向下,向上/向下(中心對齊模式)計數模式,自動重裝載計數器(TIMx_CNT)
3.16位可編程(可以實現修改)預分頻器(TIMx_PSC),計數器時鐘頻率的分頻系數為1~65535任意數值
4.四個獨立通道(TIMx_CH1~4),通道用來支持:
①輸入捕獲
②輸出比較
③PWM生成
④單脈沖模式輸出
2.通用定時器的計數器模式
STM32通用定時器 可以向上,向下,向上/向下雙向計數模式 :
① 向上計數模式:計數值從0 計數到自動加載值(TIM_ARR),產生一個計數溢出事件,然后重新從0開始計數
②向下計數模式:計數器從自動裝入的值(TIM_ARR)開始向下計數到0,產生一個計數溢出事件,然后從計數裝入值重新開始。
③中央對齊模式:計數器從0開始到(自動裝入值-1),產生計數溢出事件,然后向下計數到1,產生定時器溢出事件,然后從0開始計數。
預分頻器可以將計數器的時鐘頻率按1到65536之間的任意值分頻。
ARR是自動重裝載值(自己設定的)
CNT計數當前值(0到自動重裝載值中間的某個值)
CCRX比較寄存器值
PSC是預分頻系數
內部時鐘源(CK_INT)
三、計數器時鐘計算方法
預分頻寄存器 :分頻系數 ? ?(PSC+1) / N = CNT?
定時器配置LED每秒閃爍一次:
Tout = ? ?[ ?重裝載值(ARR+1) * 分頻系數(PSC+1)]? /Tclk
Tout = ?100000(9999+1) *7200(分頻系數 ?7199+1) ??/72M(72 000 000)
計數器計數頻率:CK_CNT = CK_PSC / (PSC + 1)
計數器溢出頻率:CK_CNT_OV = CK_CNT / (ARR + 1) ??= CK_PSC / (PSC + 1) / (ARR + 1)
四、輸入PWM模式
PWM模式1:
向上計數時,一旦TIMx_CNT<TIMx_CCR1時通道1為有效電平,否則為無效電平;
向下計數時,一旦TIMx_CNT>TIMx_CCR1時通道1為無效電平,否則為有效電平。
PWM模式2:
向上計數時,一旦TIMx_CNT<TIMx_CCR1時通道1為無效電平,否則為有效電平;
向下計數時,一旦TIMx_CNT>TIMx_CCR1時通道1為有效電平,否則為無效電平。
五、代碼
PWM:
?
void motor_init(void)
{TIM_TimeBaseInitTypeDef TIM_MotorInitStruct;GPIO_InitTypeDef Motor_init;TIM_OCInitTypeDef TIMPWMMotorinit;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);//結構體配置 (需要放在前面) //gpio.hMotor_init.GPIO_Mode =GPIO_Mode_AF_PP; //推挽復用輸出Motor_init.GPIO_Pin =GPIO_Pin_6;Motor_init.GPIO_Speed =GPIO_Speed_50MHz;GPIO_Init(GPIOA,&Motor_init);Motor_init.GPIO_Mode =GPIO_Mode_AF_PP; //推挽復用輸出Motor_init.GPIO_Pin =GPIO_Pin_5|GPIO_Pin_0|GPIO_Pin_1;Motor_init.GPIO_Speed =GPIO_Speed_50MHz;GPIO_Init(GPIOB,&Motor_init);TIM_MotorInitStruct.TIM_ClockDivision=TIM_CKD_DIV1; // 設置時鐘分割 不分頻TIM_MotorInitStruct.TIM_CounterMode= TIM_CounterMode_Up; //TIM向上計數模式TIM_MotorInitStruct.TIM_Period= 200-1; //ARR(199+1)TIM_MotorInitStruct.TIM_Prescaler=7200-1; //PSC(7199+1)TIM_TimeBaseInit(TIM3, &TIM_MotorInitStruct);TIMPWMMotorinit.TIM_OCMode =TIM_OCMode_PWM2; //選擇定時器模式1TIMPWMMotorinit.TIM_OutputState =TIM_OutputState_Enable; //比較輸出使能1TIMPWMMotorinit.TIM_OCPolarity =TIM_OCPolarity_High; //預裝載寄存器 選擇有效輸出極性//TIM_OC1Init(TIM3, &TIMPWMMotorinit);
// TIM_OC1PreloadConfig(TIM3,TIM_OCPreload_Enable ); //tim3 1TIM_OC2Init(TIM3, &TIMPWMMotorinit);TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable ); //2TIM_OC3Init(TIM3, &TIMPWMMotorinit);TIM_OC3PreloadConfig(TIM3,TIM_OCPreload_Enable ); //tim3 TIM_OC4Init(TIM3, &TIMPWMMotorinit);TIM_OC4PreloadConfig(TIM3,TIM_OCPreload_Enable ); //tim4TIM_Cmd(TIM3, ENABLE);}?
定時器:
void tim_config(void)
{TIM_TimeBaseInitTypeDef timInit;//定義初始化定時器結構體名NVIC_InitTypeDef NVICInit; //定義中斷的結構體名//1.使能時鐘 定時器時鐘RCC_APB1PeriphClockCmd( RCC_APB1Periph_TIM2, ENABLE);TIM_InternalClockConfig(TIM2); // 配置定時器2為內部時鐘模式TIM_ClearFlag(TIM2, TIM_FLAG_Update);// 清除更新時的中斷標志位,防止更新時程序直接進入中斷TIM_ITConfig(TIM2, TIM_IT_Update,ENABLE); //定時器中斷配置//2.配置tim的結構體timInit.TIM_Period = 10000-1; //設置自動重裝載值timInit.TIM_CounterMode = TIM_CounterMode_Up; //配置計數模式 為向上timInit.TIM_Prescaler = 7200 -1 ; //配置分頻系數的值(計數器時鐘的分頻系數)timInit.TIM_ClockDivision = TIM_CKD_DIV1; //(內部時鐘分頻)設置分頻系數為1,不分頻TIM_TimeBaseInit(TIM2, &timInit); //調用初始化函數//定時時間=(重裝載值+1)*(計數器分頻系數的值+1)/定時器的時鐘:10000*7200/72000000(72M)//3.打開定時器中斷,配置中斷結構體NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //配置優先級組,才可以進行搶占優先級和響應優先級設置NVICInit.NVIC_IRQChannel = TIM2_IRQn;NVICInit.NVIC_IRQChannelPreemptionPriority = 1;NVICInit.NVIC_IRQChannelSubPriority = 1;NVICInit.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVICInit);TIM_Cmd(TIM2, ENABLE);//4.中斷服務函數
}