標題:
STM32通用定時器(TIM2-5)PWM輸出
[打印本頁]
作者:
51黑黑黑
時間:
2016-2-12 22:20
標題:
STM32通用定時器(TIM2-5)PWM輸出
本帖最后由 51黑黑黑 于 2016-2-12 22:21 編輯
STM32的定時器是個強大的模塊,定時器使用的頻率也是很高的,定時器可以做一些基本的定時,還可以做PWM輸出或者輸入捕獲功能。從系統(tǒng)框架圖下看,名為TIMx的有八個,其中TIM1和TIM8掛在APB2總線上,而TIM2-TIM7則掛在APB1總線上。其中TIM1&TIM8稱為高級控制定時器(advancedcontroltimer).他們所在的APB2總線也比APB1總線要好。APB2可以工作在72MHz下,而APB1最大是36MHz。
由上圖可知,當APB1的預分頻系數(shù)為1 時,這個倍頻器不起作用,定時器的時鐘頻率等于APB1的頻率;當APB1的預分頻系數(shù)為其它數(shù)值(即預分頻系數(shù)為2、4、8 或16)時,這個倍頻器起作用,定時器的時鐘頻率等于APB1的頻率兩倍。也就是,當APB1不分頻,TIM3的時鐘速度為36MHz,當2分頻是,APB1變成18MHz,但是TIM又會倍頻,即TIM時鐘等于18*2=36MHz。這里我們用向上計數(shù)的方式,即TIMx_CNT中的計數(shù)值達到TIMx_ARR中的值時,產(chǎn)生中斷,TIMx_CNT又從0開始計。
按以下步驟編程:
1.系統(tǒng)初始化,主要初始化時鐘等。
2.GPIO初始化,用于LED,有了燈就便于觀察了。
3.TIM3的配置。
4.NVIC的配置。
5.編寫中斷服務函數(shù)。
void GPIO_PA_Init()
{//PA8管腳配置
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_DeInit(GPIOA);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽輸出
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);//使能端口時鐘A
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
void TIMER3_Init()
{
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
TIM_DeInit(TIM3);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
TIM_TimeBaseStructure.TIM_Period=10000;//ARR的值
TIM_TimeBaseStructure.TIM_Prescaler=7200-1;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上計數(shù)模式
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM3, ENABLE); //開啟時鐘
}
void NVIC_Configuration()
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // 搶占式優(yōu)先級別
NVIC_InitStructure.NVIC_IRQChannel =TIM3_IRQChannel;//指定中斷源
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;// 指定響應優(yōu)先級別1
NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
int main(void)
{
Stm32_Clock_Init(9); //系統(tǒng)時鐘設置
delay_init(72); //延時初始化
GPIO_PA_Init();
TIMER3_Init();
NVIC_Configuration();
while(1);
}
void TIM3_IRQHandler()
{
if(TIM_GetITStatus(TIM3 , TIM_IT_Update) ==SET)
{
TIM_ClearITPendingBit(TIM3 ,TIM_FLAG_Update);
if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_8))GPIO_ResetBits(GPIOA, GPIO_Pin_8);
else GPIO_SetBits(GPIOA,GPIO_Pin_8);
}
}
脈沖寬度調(diào)制
(PWM)
,是英文“
Pulse WidthModulation
”的縮寫,簡稱脈寬調(diào)制,是利用微處理器的數(shù)字輸出來對模擬電路進行控制的一種非常有效的技術。簡單一點,就是對脈沖寬度的控制。一般用來控制步進電機的速度等等。
STM32
的定時器除了
TIM6
和
TIM7
之外,其他的定時器都可以用來產(chǎn)生
PWM
輸出,其中高級定時器
TIM1
和
TIM8
可以同時產(chǎn)生
7
路的
PWM
輸出,而通用定時器也能同時產(chǎn)生
4
路的
PWM
輸出。
PWM
輸出模式
STM32
的
PWM
輸出有兩種模式,模式
1
和模式
2
,由
TIMx_CCMRx
寄存器中的
OCxM
位確定的(“
110
”為模式
1
,“
111
”為模式
2
)。模式
1
和模式
2
的區(qū)別如下:
110
:
PWM
模式
1
-在向上計數(shù)時,一旦
TIMx_CNT<TIMx_CCR1
時通道
1
為有效電平,否則為無效電平;在向下計數(shù)時,一旦
TIMx_CNT>TIMx_CCR1
時通道
1
為無效電平
(OC1REF=0)
,否則為有效電平
(OC1REF=1)
。
111
:
PWM
模式
2
-在向上計數(shù)時,一旦
TIMx_CNT<TIMx_CCR1
時通道
1
為無效電平,否則為有效電平;在向下計數(shù)時,一旦
TIMx_CNT>TIMx_CCR1
時通道
1
為有效電平,否則為無效電平。
由此看來,模式
1
和模式
2
正好互補,互為相反,所以在運用起來差別也并不太大。
而從計數(shù)模式上來看,
PWM
也和
TIMx
在作定時器時一樣,也有向上計數(shù)模式、向下計數(shù)模式和中心對齊模式,關于
3
種模式的具體資料,可以查看《
STM32
參考手冊》的“
14.3.9 PWM
模式”一節(jié),在此就不詳細贅述了。
PWM
輸出管腳
PWM
的輸出管腳是確定好的,具體的引腳功能可以查看《
STM32
參考手冊》的“
8.3.7
定時器復用功能重映射”一節(jié)。在此需要強調(diào)的是,不同的
TIMx
有分配不同的引腳,但是考慮到管腳復用功能,
STM32
提出了一個重映像的概念,就是說通過設置某一些相關的寄存器,來使得在其他非原始指定的管腳上也能輸出
PWM
。但是這些重映像的管腳也是由參考手冊給出的。比如說
TIM3
的第
2
個通道,在沒有重映像的時候,指定的管腳是
PA.7
,如果設置部分重映像之后,
TIM3_CH2
的輸出就被映射到
PB.5
上了,如果設置了完全重映像的話,
TIM3_CH2
的輸出就被映射到
PC.7
上了。
PWM
輸出信號
PWM
輸出的是一個方波信號,信號的頻率是由
TIMx
的時鐘頻率和
TIMx_ARR
預分頻器所決定的,具體設置方法在前面一個學習筆記中有詳細的交代。而輸出信號的占空比則是由
TIMx_CRRx
寄存器確定的。其公式為“占空比
=(TIMx_CRRx/TIMx_ARR)*100%
”,因此,可以通過向
CRR
中填入適當?shù)臄?shù)來輸出自己所需的頻率和占空比的方波信號。
按以下步驟配置:
1.
設置
RCC
時鐘;
2.
設置
GPIO
時鐘;
3.
設置
TIMx
定時器的相關寄存器;
4.
設置
TIMx
定時器的
PWM
相關寄存器;
第1步設置RCC時鐘已經(jīng)在前文中給出了詳細的代碼,在此就不再多說了。需要注意的是通用定時器TIMx是由APB1提供時鐘,而GPIO則是由APB2提供時鐘。注意,如果需要對PWM的輸出進行重映像的話,還需要開啟引腳復用時鐘AFIO
。
第2步設置GPIO時鐘時,GPIO模式應該設置為復用推挽輸出GPIO_Mode_AF_PP,如果需要引腳重映像的話,則需要用GPIO_PinRemapConfig()函數(shù)進行設置。
第3步設置TIMx定時器的相關寄存器時,和前一篇學習筆記一樣,設置好相關的TIMx的時鐘和技術模式等等。
第4步設置PWM相關寄存器,首先要設置PWM模式(默認情況下PWM是凍結(jié)的),然后設置占空比(根據(jù)前面所述公式進行計算),再設置輸出比較極性:當設置為High時,輸出信號不反相,當設置為Low時,輸出信號反相之后再輸出。最重要是是要使能TIMx的輸出狀態(tài)和使能TIMx的PWM輸出使能。相關設置完成之后,就可以通過TIM_Cmd()來打開TIMx定時器,從而得到PWM輸出了。
以下是我寫的參考程序:
void GPIO_PA_Init()
{//PA13管腳配置
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_DeInit(GPIOA);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//復用推挽輸出
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);//使能端口時鐘A
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
void TIMER3_Init()
{
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
TIM_DeInit(TIM3);
TIM_InternalClockConfig(TIM3);
TIM_TimeBaseStructure.TIM_Period=10000-1;//ARR的值周期10K
TIM_TimeBaseStructure.TIM_Prescaler=0;
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上計數(shù)模式
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
}
void TIMER3_PWM_Init()
{
TIM_OCInitTypeDef TIMOCInitStructure;
TIMOCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//PWM模式1輸出
TIMOCInitStructure.TIM_Pulse=0;//占空比=(CCRx/ARR)*100%
TIMOCInitStructure.TIM_OCPolarity =TIM_OCPolarity_High;//TIM輸出比較極性高
TIMOCInitStructure.TIM_OutputState =TIM_OutputState_Enable;//使能輸出狀態(tài)
TIM_OC2Init(TIM3,&TIMOCInitStructure);//TIM3的CH2輸出
TIM_CtrlPWMOutputs(TIM3,ENABLE);//設置TIM3的PWM輸出為使能
TIM_Cmd(TIM3, ENABLE); //開啟時鐘
}
作者:
dgwg
時間:
2016-2-14 20:33
很不錯
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1