三、定時器PWM輸出實(shí)驗(yàn)
1. 通用定時器PWM概述
PWM,英文名Pulse Width Modulation,是脈沖寬度調(diào)制縮寫,它是通過對一系列脈沖的寬度進(jìn)行調(diào)制,等效出所需要的波形(包含形狀以及幅值),對模擬信號電平進(jìn)行數(shù)字編碼,也就是說通過調(diào)節(jié)占空比的變化來調(diào)節(jié)信號、能量等的變化,占空比就是指在一個周期內(nèi),信號處于高電平的時間占據(jù)整個信號周期的百分比,例如方波的占空比就是50%。PWM的功能有很多種,比如控制呼吸燈、控制直流電機(jī)或者舵機(jī)等驅(qū)動原件等等,是單片機(jī)的一個十分重要的功能。
在STM32單片機(jī)中,可以使用定時器的輸出比較功能來產(chǎn)生PWM波:
即PWM模式可以產(chǎn)生一個由TIMx_ARR寄存器確定頻率、由TIMx_CCRx寄存器確定占空比的信號。其框圖如下圖所示:
可見,橫坐標(biāo)是時間變量,縱坐標(biāo)是CNT計數(shù)值,CNT計數(shù)值隨著時間的推進(jìn)會不斷經(jīng)歷從0到ARR,清零復(fù)位再到ARR的這一過程。這之中還有一個數(shù)值是CCRx即比較值,通過比較值和輸出配置可以使之輸出高低電平邏輯,這樣就產(chǎn)生了PWM波形。通過調(diào)節(jié)ARR的值可以調(diào)節(jié)PWM的周期,調(diào)節(jié)CCRx的值大小可以調(diào)節(jié)PWM占空比。
我們以通道1為例,詳細(xì)講解PWM的工作過程,如下圖所示:
從最左邊進(jìn)入的是時鐘源,由內(nèi)部時鐘(CNT)或者外部觸發(fā)時鐘(ETRF)輸入,進(jìn)入輸入模式控制器,通過OCMR1寄存器的OC1M[2:0]位來配置PWM模式,之后進(jìn)入一個選擇器,由CCER寄存器的CC1P位來設(shè)置輸出極性,最后由CCER寄存器的CC1E位來使能輸出,然后通過OC1來輸出PWM波。
CCR1:捕獲比較(值)寄存器(x=1,2,3,4):設(shè)置比較值。
CCMR1: OC1M[2:0]位:對于PWM方式下,用于設(shè)置PWM模式1【110】或者PWM模式2【111】
CCER:CC1P位:輸入/捕獲1輸出極性。0:高電平有效,1:低電平有效。
CCER:CC1E位:輸入/捕獲1輸出使能。0:關(guān)閉,1:打開。
- PWM模式
PWM有PWM模式1和模式2兩種模式,它們之間的區(qū)別用寄存器TIMx_CCMR1的OC1M[2:0]位來分析:
表中紅色框標(biāo)識的地方就是PWM模式1和模式2的定義和區(qū)別,可以簡單理解為:PWM模式1的情況下,當(dāng)前值小于比較值為有效電平;PWM模式2的情況下,當(dāng)前值大于比較值為有效電平。
理解這一點(diǎn)對之后的PWM配置十分重要。
下面是對PWM模式1以及向上計數(shù)配置情況的說明:
** 3.相關(guān)寄存器介紹**
- 捕獲/比較寄存器1(TIMx_CCR1)
這里以寄存器1舉例,其它的三個寄存器(CCR2、CCR3、CCR4)都是一樣的
- 捕獲比較模式寄存器1(TIMx_CCMR1)
可以看到,每個捕獲/比較模式寄存器可以控制兩個通道,這樣的話每個定時器就對應(yīng)兩個捕獲/比較模式寄存器。其最常用的位就是0C1M(OC2M)位了,這兩個位是用來設(shè)置PWM模式的,有模式1和模式2兩種,這就和前面所講的對應(yīng)上了。
- 捕獲/比較使能寄存器(TIMx_CCER)
可以看到,位0(CC1E)和位1(CC1P)是捕獲比較使能寄存器最常用的兩個位,分別控制輸出使能和輸出極性,這就也和剛剛講的對應(yīng)上了。
- 自動重裝載寄存器(TIMx_ARR)
這個寄存器不太常用,下面的庫函數(shù)配置會講解其庫函數(shù)用法。
4. 定時器輸出通道引腳
定時器輸出PWM和定時器中斷不同,定時器中斷只需要開啟這一外設(shè)即可工作,定時器輸出PWM需要在單片機(jī)的引腳上輸出實(shí)實(shí)在在的脈沖信號。
下面是定時器3的通道引腳,可以使用部分映射或者完全映射。其它定時器的引腳可以查看芯片手冊。
5.定時器PWM庫函數(shù)配置
- 輸出庫函數(shù)配置
和定時器中斷實(shí)驗(yàn)不同,在初始化時基單元之后,還需要對輸出通道進(jìn)行初始化:
void TIM_OCxInit(TIM_TypeDef* TIMx, TIM_OCInitTypeDef* TIM_OCInitStruct);
其結(jié)構(gòu)體成員如下:
typedef struct
{
uint16_t TIM_OCMode; //PWM模式1或者模式2
uint16_t TIM_OutputState; //輸出使能 OR失能
uint16_t TIM_OutputNState;
uint16_t TIM_Pulse; //比較值,寫CCRx
uint16_t TIM_OCPolarity; //比較輸出極性
uint16_t TIM_OCNPolarity;
uint16_t TIM_OCIdleState;
uint16_t TIM_OCNIdleState;
} TIM_OCInitTypeDef;
初始化實(shí)例:
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //PWM模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
TIM_OCInitStructure. TIM_Pulse=100;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根據(jù)T指定的參數(shù)初始化外設(shè)TIM3 OC2
設(shè)置比較值函數(shù)
void TIM_SetCompareX(TIM_TypeDef* TIMx, uint16_t Compare2);
- 使能輸出比較預(yù)裝載
-
void TIM_OC2PreloadConfig(TIM_TypeDef* TIMx, uint16_t TIM_OCPreload);
- 使能自動重裝載的預(yù)裝載寄存器允許位
void TIM_ARRPreloadConfig(TIM_TypeDef* TIMx, FunctionalState NewState);
輸出配置步驟
① 使能定時器3和相關(guān)IO口時鐘。
使能定時器3時鐘:RCC_APB1PeriphClockCmd();
使能GPIOB時鐘:RCC_APB2PeriphClockCmd();
② 初始化IO口為復(fù)用功能輸出。函數(shù):GPIO_Init();
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
③ 這里我們是要把PB5用作定時器的PWM輸出引腳,所以要重映射配置,
所以需要開啟AFIO時鐘。同時設(shè)置重映射。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
④ 初始化定時器:ARR,PSC等:TIM_TimeBaseInit();
⑤ 初始化輸出比較參數(shù):TIM_OC2Init();
⑥ 使能預(yù)裝載寄存器:TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
⑦ 使能定時器。TIM_Cmd();
⑧ 不斷改變比較值CCRx,達(dá)到不同的占空比效果:TIM_SetCompare2();
6.實(shí)例
我們使用STM32單片機(jī)的定時器TIM3的PWM功能,輸出占空比可變的PWM波,用來驅(qū)動LED燈,從而達(dá)到LED亮度由暗變亮,又從亮變暗,如此循環(huán)。代碼如下:
//timer.c源文件
#include "timer.h"
#include "led.h"
#include "usart.h"
//TIM3 PWM部分初始化
//PWM輸出初始化
//arr:自動重裝值
//psc:時鐘預(yù)分頻數(shù)
void TIM3_PWM_Init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定時器3時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); //使能GPIO外設(shè)和AFIO復(fù)用功能模塊時鐘
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射 TIM3_CH2->PB5
//設(shè)置該引腳為復(fù)用輸出功能,輸出TIM3 CH2的PWM脈沖波形 GPIOB.5
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //復(fù)用推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO
//初始化TIM3
TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在下一個更新事件裝入活動的自動重裝載寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置用來作為TIMx時鐘頻率除數(shù)的預(yù)分頻值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設(shè)置時鐘分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數(shù)模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時間基數(shù)單位
//初始化TIM3 Channel2 PWM模式
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈沖寬度調(diào)制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高
TIM_OC2Init(TIM3, &TIM_OCInitStructure); //根據(jù)T指定的參數(shù)初始化外設(shè)TIM3 OC2
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的預(yù)裝載寄存器
TIM_Cmd(TIM3, ENABLE); //使能TIM3
}
//timer.h頭文件
#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h"
void TIM3_PWM_Init(u16 arr,u16 psc);
#endif
//main.c源文件
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "timer.h"
int main(void)
{
u16 led0pwmval=0;
u8 dir=1;
delay_init(); //延時函數(shù)初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級,2位響應(yīng)優(yōu)先級
uart_init(115200); //串口初始化為115200
LED_Init(); //LED端口初始化
TIM3_PWM_Init(899,0); //不分頻。PWM頻率=72000000/900=80Khz
while(1)
{
delay_ms(10);
if(dir)led0pwmval++;
else led0pwmval--;
if(led0pwmval>300)dir=0;
if(led0pwmval==0)dir=1;
TIM_SetCompare2(TIM3,led0pwmval);
}
}
總結(jié)
本章從STM32定時器的原理、寄存器介紹、定時器配置以及定時器的幾個常用的功能(如定時器中斷、定時器輸出比較PWM波形)的使用方法來教大家掌握定時器這一外設(shè)。希望讀者能夠仔細(xì)學(xué)習(xí),掌握這一重要的外設(shè)。
-
微控制器
+關(guān)注
關(guān)注
48文章
7489瀏覽量
151051 -
定時器
+關(guān)注
關(guān)注
23文章
3237瀏覽量
114472 -
GPIO
+關(guān)注
關(guān)注
16文章
1196瀏覽量
51919
發(fā)布評論請先 登錄
相關(guān)推薦
評論