1.定時器概述
定時器分為基本定時器,通用定時器,進階定時器。
例如:STM32F10x系列包含4個通用定時器(TIM2~TIM5但是STM32F103Rx系列隻有3個通用定時器(TIM2~TIM4))。這些通用定時器是完全獨立的,不共享任何資源。每個定時器都包含一個16位的計數器(計算範圍:0~65535),并且這些定時器都可以通過預配置設定器來對輸入的時鐘源進行分頻(分頻就是降低計數頻率),來滿足更長的的計時要求。通用定時器除了基本的定時功能以外,還具有輸入捕獲(測量輸入信号脈沖長度)、輸出比較(産生輸出波形)等功能。
2.特征對比
基本定時器 | 通用定時器 | |
計數器 | 16位自動重裝在遞增計數器 | 16位自動重裝載遞增、遞減或先增後減計數器 |
預分頻器 | 輸入的時鐘源進行分頻 | |
自動重裝載計數器 | 放計數器計數周期的最大值(決定了計數器在一個工作周期内的計數次數 | |
上三者組成定時器時基單元 | ||
時鐘源 | 内部時鐘源CK_INT | 内部時鐘源CK_INT 内部觸發輸入(定時器級聯) 外部時鐘模式1(來自TIx的邊緣檢測信号,用于霍爾電機測速) 外部時鐘模式2(來源外部觸發輸入ETR) |
功能 | 定時延時 觸發DAC驅動電路,為DAC提供驅動時鐘 産生中斷或DMA請求 | 定時、延時 輸入捕獲、輸出比較、PWM、單脈沖輸出(隻輸出一個周期) 産生中斷或DMA請求 支援霍爾傳感器電路進行電機轉速檢測等應用。 |
通道 | 單通道 | 四個通道 |
産生中斷或DMA請求條件 | 更新事件 | 更新事件、觸發事件、輸入捕獲以及輸出比較 |
3.框圖對比與解釋
1)基本定時器
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLiAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHLwUERPBTQq5UMRpHW4Z0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL3kDO0UTNwATM4IjMwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
向自動重裝在計數器寫入計數周期(即計數器最大值),向預分頻計數器寫入分頻系數(多久記一次數)。計數器從0開始計數(假設向上計數),當計數達到我們寫入的最大值時候,會産生一個更新事件 和 中斷或者DMA請求。
為什麼要産生更新事件?對于程式設計人員來說,我們能通路上層寄存器,這個上層寄存器對于CPU來說是通路不到的,CPU能通路的是影子寄存器。是以我們要将上層寄存器和影子寄存器進行關聯。更新事件的作用就是:将自動重裝載計數器和預分頻計數器的值寫入影子寄存器,以達到CPU可以通路的目的。當然每次産生更新事件都要更新一下影子寄存器。
2)通用定時器
都在圖裡
4.通用定時器時鐘源
- 内部時鐘(CK_INT):定時器的輸入時鐘源來源于晶片内部系統總線時鐘,頻率為72M。
- 外部時鐘模式1:定時器的輸入時鐘源來源于外部輸入管腳(TIx)上的邊緣輸入信号(x:TI1FP1、TI2FP2)。霍爾傳感電路檢測電機轉速
- 外部時鐘模式2:定時器的輸入時鐘源來源于外部觸發輸入(ETR)上的定時器外部觸發管腳(TIMx_ETR)上的外部輸入信号。
- 内部觸發輸入(ITRx):定時器的輸入時鐘源來源于一個定時器的内部輸出(TRGO)到ITRx的輸入時鐘信号(x:ITR0~3)。 定時器級聯
5.通用定時器輸出比較
輸出比較工作流程:先輸出比較寄存器CCRx寫入數值(類似重裝載值),CNT開始計數,通過CNT數值與CCRx值比較==>輸出有效電平、無效電平、電平反轉等。當CNT的值大于CCRx,會産生對應的中斷和标志位。
1)強制輸出
通用定時器的輸出直接由軟體将輸出比較信号(OxRef和OCx)強制設定為有效電平、無效電平或者輸出不變。無需考慮捕獲/比較寄存器(CCRx)和計數器(CNT)之間的任何比較結果
2)比較輸出
比較輸出模式的輸出結果和捕獲/比較寄存器(CCRx)和計數器(CNT)之間比較結果相關,當這兩個值相等的時候,輸出結果為有效電平、無效電平或者電平翻轉。如果計數器(CNT)的值大于或等于捕獲/比較寄存器(CCRx)中的值時,會産生對應的标志或者中斷。而輸出比較模式在四個通道可以産生的頻率不同.CCRx決定初相位
3)PWM輸出
PWM輸出模式是輸出比較的一個特例,輸出結果和捕獲/比較寄存器(CCRx)和計數器(CNT)之間的比較值影響,輸出結果為有效電平、無效電平。pwm模式在對應定時器上的四個通道産生的頻率是同步的
6.通用定時器配置流程
- 時鐘使能
- 配置GPIO口
STM32--基本定時器&&通用定時器1.定時器概述2.特征對比3.框圖對比與解釋4.通用定時器時鐘源5.通用定時器輸出比較6.通用定時器配置流程7.代碼 - 配置定時器公共計數器子產品:定時器時鐘源(内部、外部、觸發)、計數方式(加、減、先加後減)、計數頻率(預分頻)、是否循環、計數周期(重裝載值)等。
- 配置定時PWM比較輸出模式: PWM模式、具體有效電平、通道工作模式、占空比等。
- 使能定時器輸出以及使能定時器子產品。
7.代碼
舵機的控制一般需要一個20Ms左右的時基脈沖,該脈沖的高電平部分一般為0.5Ms~2.5Ms範圍内的角度控制脈沖部分,總間隔為2Ms。
以180°舵機為例,對應的控制關系如下:
0.5Ms————0° 1.0Ms————45° 1.5Ms————90° 2.0Ms————135° 2.5Ms————180°
360°舵機與其他普通舵機不同,它實際相當于無極變速的減速電機,可以控制速度和方向,但是沒有0-360°角度控制的功能。控制方向和一般舵機的控制信号相同:
0.5Ms————正向最大轉速 1.5Ms————速度為0 2.5Ms————反向最大轉速
//PB0 -- pwm--TIM3_CH3---20ms時基---72000-1分頻---arr:20000-1 == 20ms
//不分頻:定時1s需要計數器加72*10^9
//72000-1分頻: 定時1s需要計數器加1*10^6 減一:計數器時鐘頻率 = f_ckpsc / (psc[15:0]+1)
//20ms就是計數器計數:20000-1 減一:如果想計數100次則寫99,因為99加一次就是0剛好100
// PWM_Init1(20000-1,72);
void PWM_Init1(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO口,相當于GPIOB_Pin_初始化
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
//置定時器時鐘(CK_INT)頻率與數字濾波器(ETR,TIx)使用的采樣頻率之間的分頻比例的(與輸入捕獲相關),0表示濾波器的頻率和定時器的頻率是一樣的。
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler = psc * 1000 - 1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
//TIM_RepetitionCounter 是再次重裝載值,正常情況下當計數溢出後清零進入中斷,該寄存器配置1後,就是計數器溢出兩次才進入中斷
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);//初始化定時器
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//CNT < CCRX 輸出有效電平
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 開啟OC*輸出到對應引腳
TIM_OCInitStructure.TIM_Pulse = 0; // TIM3->CCR32 = TIM_OCInitStruct->TIM_Pulse = TIM_SetCompare3(TIM3,800); 此值決定電機轉速
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//輸出極性:有效電平是高電平
/***********進階定時器********************/
// TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; // 互補輸出使能。開啟OC*N輸出到對應的引腳
// TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; //互補輸出極性 高
// TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set; //在空閑狀态下的TIM輸出比較引腳的狀态。僅供TIM1和TIM8有效 高
// TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset; //在空閑時互補輸出 低
TIM_OC3Init(TIM3,&TIM_OCInitStructure);//TIM3通道3初始化
TIM_ARRPreloadConfig(TIM3,ENABLE); //初始化預裝載值。
TIM_Cmd(TIM3, ENABLE); //使能TIM3定時器
}