STM32 定時器2 CH1 CH2 PWM輸出 產生呼吸燈效果
阿新 • • 發佈:2019-01-10
PWM一般用來驅動電機(控制速度),控制LED亮度,驅動開關電源電路等等,本例項通過改變PWM佔空比的方式來驅動LED燈,形成呼吸燈的效果。用這種方式來學習STM32 TIM2輸出PWM的配置。
以STM32F103C8T6為例,從其資料手冊中可以看到,PA0、PA1的複用功能(Default alternate functions)分別是定時器2的CH1和CH2。
由圖2 TIM2_REMP重對映控制表可以看到,TIM2_CH1_ETR表示,PA0既可以復位為TIM2_CH1,也可以複用為TIM2_ETR功能,我們這裡將PA0當做TIM2_CH1使用。
圖1 TIM2 CH1、CH2引腳
(圖來自資料手冊)
由圖2可以看到TIM2的CH1、CH2沒有重映像時指向PA0和PA1,所以我們這裡不進行重對映配置,在配置PA0、PA1埠時,配置為複用推輓輸出即可。
圖2 TIM2_REMP重對映控制表
配置步驟
1. PWM時鐘配置
l TIM2時鐘
l GPIOA時鐘
2. 初始化TIM2,設定ARR(週期),PSC(主時鐘分頻係數)
3. 設定TIM2_CH1, TIM2_CH2的PWM模式,使能TIM2_CH1和TIM2_CH2輸出。
4. 使能TIM2
Small Tips
- 讀取當前計數器計數值,讀取暫存器 [ TIM2->CNT ]的值
- 改變定時器輸出PWM佔空比,使用函式[ TIM_SetCompare1(TIM2, DUTY) ; ]
程式碼實現
下列為STM32應用程式碼,已經驗證能夠穩定使用。
timer.c
void TIM2_PWM_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //使能定時器2時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //使能GPIO外設時鐘 //引腳功能配置 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1; //TIM2_CH1 TIM2_CH2 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //複用推輓輸出!! GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化TIM2 TIM_TimeBaseStructure.TIM_Period = arr; //設定在下一個更新事件裝入活動的自動重灌載暫存器週期的值 TIM_TimeBaseStructure.TIM_Prescaler =psc; //設定用來作為TIMx時鐘頻率除數的預分頻值 TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設定時鐘分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的引數初始化TIMx的時間基數單位 //初始化TIM2 Channel1、Channel2 PWM模式 TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈衝寬度調製模式2 TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能 TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高 TIM_OC1Init(TIM2, &TIM_OCInitStructure); //根據T指定的引數初始化外設TIM2 OC1 TIM_OC2Init(TIM2, &TIM_OCInitStructure); //根據T指定的引數初始化外設TIM2 OC2 TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能TIM2在CCR2上的預裝載暫存器 TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能TIM2在CCR2上的預裝載暫存器 TIM_Cmd(TIM2, ENABLE); //使能TIM2 }
timer.h
#ifndef __TIMER_H
#define __TIMER_H
#include "sys.h"
void TIM2_PWM_Init(u16 arr,u16 psc); //arr-定時器週期,psc--定時器時鐘分頻
#endif
main.h (部分) 實現呼吸燈效果,在PA0和PA1外接LED燈
//微控制器標頭檔案
#include "stm32f10x.h"
#include "delay.h"
#include "usart.h"
#include "timer.h"
//C庫
#include <string.h>
int main(void)
{
unsigned int pulse = 0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中斷控制器分組設定
Delay_Init(); //Systick初始化,用於普通的延時
DelayMs(200); //等待電源穩定
TIM2_PWM_Init(100,719); //720分頻,72000_000/720 = 100Khz的計數頻率,計數到100為1KHz
while(1)
{
pulse = 0;
for(i = 0; i < 100;i ++)
{
pulse += 1;
TIM_SetCompare1(TIM2, pulse) ;
TIM_SetCompare2(TIM2, pulse) ;
DelayMs(50);
}
for(i = 0; i < 100;i ++)
{
pulse -= 1;
TIM_SetCompare1(TIM2, pulse) ;
TIM_SetCompare2(TIM2, pulse) ;
DelayMs(50);
}
}
}