STM32一共有8個都為16位的定時器。其中TIM6、TIM7是基本定時器;TIM2、TIM3、TIM4、TIM5是通用定時器;TIM1和TIM8是高級定時器。這些定時器使STM32具有定時、信號的頻率測量、信號的PWM測量、PWM輸出、三相6步電機控制及編碼器接口等功能,都是專門為工控領(lǐng)域量身訂做的。
基本定時器:具備最基本的定時功能,下面是它的結(jié)構(gòu):
啟動代碼:
void TIM2_Configuration(void)
{基本定時器TIM2的定時配置的結(jié)構(gòu)體(包含定時器配置的所有元素例如:TIM_Period = 計數(shù)值)
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;
設(shè)置TIM2_CLK為72MHZ (即TIM2外設(shè)掛在APB1上,把它的時鐘打開。)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
設(shè)置計數(shù)值位1000
TIM_TimeBaseStructure.TIM_Period=1000;
將TIM2_CLK為72MHZ 除以72 = 1MHZ為定時器的計數(shù)頻率
TIM_TimeBaseStructure.TIM_Prescaler= 71;
這個TIM_ClockDivision是設(shè)置時鐘分割,這里不分割還是1MHZ的計數(shù)頻率
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
設(shè)置為向上計數(shù)模式;(計數(shù)模式有向上,向下,中央對齊1,中央對齊2,中央對齊3)
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
將配置好的設(shè)置放進stm32f10x-tim.c的庫文件中
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
清除標志位
TIM_ClearFlag(TIM2, TIM_FLAG_Update);
使能TIM2中斷
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
使能TIM2外設(shè)
TIM_Cmd(TIM2, ENABLE);
}
通用定時器:就比基本定時器復(fù)雜得多了。除了基本的定時,它主要用在測量輸入脈沖的頻率、脈沖寬與輸出PWM脈沖的場合,還具有編碼器的接口。
如何生成PWM脈沖
通用定時器可以利用GPIO引腳進行脈沖輸出,在配置為比較輸出、PWM輸出功能時,捕獲/比較寄存器TIMx_CCR被用作比較功能,下面把它簡稱為比較寄存器。
這里直接舉例說明定時器的PWM輸出工作過程:若配置脈沖計數(shù)器TIMx_CNT為向上計數(shù),而重載寄存器TIMx_ARR被配置為N,即TIMx_CNT的當前計數(shù)值數(shù)值X在TIMxCLK時鐘源的驅(qū)動下不斷累加,當TIMx_CNT的數(shù)值X大于N時,會重置TIMx_CNT數(shù)值為0重新計數(shù)。
而在TIMxCNT計數(shù)的同時,TIMxCNT的計數(shù)值X會與比較寄存器TIMx_CCR預(yù)先存儲了的數(shù)值A(chǔ)進行比較,當脈沖計數(shù)器TIMx_CNT的數(shù)值X小于比較寄存器TIMx_CCR的值A(chǔ)時,輸出高電平(或低電平),相反地,當脈沖計數(shù)器的數(shù)值X大于或等于比較寄存器的值A(chǔ)時,輸出低電平(或高電平)。
如此循環(huán),得到的輸出脈沖周期就為重載寄存器TIMx_ARR存儲的數(shù)值(N+1)乘以觸發(fā)脈沖的時鐘周期,其脈沖寬度則為比較寄存器TIMx_CCR的值A(chǔ)乘以觸發(fā)脈沖的時鐘周期,即輸出PWM的占空比為 A/(N+1)。
如果不想看的可以直接看我標注的紅色字體,就大體可以理解。
具體代碼:
void TIM3_GPIO_Config(void)
{配置TIM3復(fù)用輸出PWM的IO
GPIO_InitTypeDef GPIO_InitStructure;
打開TIM3的時鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
打開GPIOA和GPIOB的時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB, ENABLE);
配置PA6.PA7的工作模式
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
配置PB0.PB1的工作模式
GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0 | GPIO_Pin_1;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
void TIM3_Mode_Config(void)
{
TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;//初始化TIM3的時間基數(shù)單位
TIM_OCInitTypeDefTIM_OCInitStructure;//初始化TIM3的外設(shè)
u16 CCR1_Val = 500;
u16 CCR2_Val = 375;
u16 CCR3_Val = 250;
u16 CCR4_Val = 125;//PWM信號電平跳變值(即計數(shù)到這個數(shù)值以后都是低電平之前都是高電平)
TIM3的時間基數(shù)單位設(shè)置(如計數(shù)終止值:999,從0開始 ;計數(shù)方式:向上計數(shù))
TIM_TimeBaseStructure.TIM_Period = 999;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM3的外設(shè)的設(shè)置
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//TIM脈沖寬度調(diào)制模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//這個暫時不知道,stm32固件庫里沒有搜到。應(yīng)該是定時器輸出聲明使能的意思
TIM_OCInitStructure.TIM_Pulse = CCR1_Val;//設(shè)置了待裝入捕獲比較寄存器的脈沖值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;//TIM輸出比較極性高
TIM_OC1Init(TIM3, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);//使能或者失能TIMx在CCR1上的預(yù)裝載寄存器
下面3路PWM輸出和上面的一樣不再解說
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR2_Val;
TIM_OC2Init(TIM3, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR3_Val;
TIM_OC3Init(TIM3, &TIM_OCInitStructure);
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = CCR4_Val;
TIM_OC4Init(TIM3, &TIM_OCInitStructure);
TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM3, ENABLE);//使能TIM3重載寄存器ARR
TIM_Cmd(TIM3, ENABLE);//使能TIM3
}
程序達到的4路PWM的效果:
可以看到明顯占空比不同的4路pwm波。
這一節(jié)終于講完,個人覺得敲一遍代碼學(xué)起來還是蠻容易懂的。希望看到的人也能搞懂。
最后補充一點pwm具體能干什么?特別是對廣大電子DIY愛好者的應(yīng)用:
智能小車的電機控制:我們可以利用pwm來控制我們的智能小車的車速;
機器人:給“機器人關(guān)節(jié)”舵機周期一定(我以前玩過具體多少毫秒忘記了)pwm波就可以控制舵機的轉(zhuǎn)動角度了;
呼吸燈:輸入不同的pwm波就可以達到明暗漸明漸暗的效果。