項(xiàng)目需求
在制作一個(gè)使用全向輪的機(jī)器人底盤,對于全向輪,電機(jī)的精度是影響效果的重要因素。所以使用了步進(jìn)電機(jī),使用步進(jìn)電機(jī)的優(yōu)點(diǎn)是可以不使用編碼器,開環(huán)控制即可達(dá)到高精度的效果。
調(diào)整占空比或者調(diào)整周期
眾所周知,PWM有兩個(gè)重要參數(shù),周期與占空比。
步進(jìn)電機(jī)的運(yùn)動(dòng)方式是,每收到一個(gè)脈沖,就旋轉(zhuǎn)指定的角度。因此影響電機(jī)速度的唯一參數(shù)就是PWM的頻率。以下附圖兩張來說明調(diào)整占空比與調(diào)整周期的區(qū)別。
周期固定,調(diào)整占空比
上圖中有4個(gè)PWM,它們的周期是一樣的,不同之處是擁有從80%至20%的占空比??梢钥闯?,無論占空比為多少,在1s內(nèi),它們產(chǎn)生的高電平的數(shù)量是一樣的,即無論占空比為多少,PWM的頻率都一致。因此也就無法調(diào)整步進(jìn)電機(jī)的速度。因?yàn)椴竭M(jìn)電機(jī)的速度僅與PWM的頻率有關(guān)。
占空比固定,調(diào)整周期
上圖中有4個(gè)PWM,它們的占空比都固定為50%,卻擁有不同的周期??梢钥闯觯词拐伎毡裙潭?,只要?jiǎng)討B(tài)調(diào)整周期,PWM就能在相同時(shí)間內(nèi)產(chǎn)生數(shù)量不同的脈沖。因此,固定占空比,動(dòng)態(tài)調(diào)整PWM周期,即可達(dá)到控制步進(jìn)電機(jī)速度的效果。
基于STM32的實(shí)現(xiàn)
在STM32F1中,定時(shí)器具有PWM模式,可以用來產(chǎn)生PWM。但是,STM32的PWM模式,只要確定了時(shí)基單元(即確定了PWM周期),改變輸出比較寄存器,僅可改變PWM的占空比。
若需要改變PWM周期,需不停地改變定時(shí)器的時(shí)基單元。但時(shí)基單元與硬件相關(guān),不適合頻繁變更。因此,步進(jìn)電機(jī)的調(diào)速,不適合使用STM32下定時(shí)器的PWM模式來控制。
在多方查找資料后,確定了一種利用輸出比較精確控制PWM周期的方式。
利用輸出比較產(chǎn)生頻率可變的PWM
利用輸出比較產(chǎn)生頻率可變的PWM,原理簡單介紹如下:
首先配置定時(shí)器時(shí)基單元,確定脈沖最小長度單位CK。
然后開啟定時(shí)器的輸出比較,設(shè)置模式為翻轉(zhuǎn)模式,并開啟輸出比較中斷。
將定時(shí)器內(nèi)計(jì)數(shù)器CNT當(dāng)前值,加上脈沖長度X(單位為CK),寫入輸出比較寄存器。
在X個(gè)CK后,將會(huì)觸發(fā)輸出比較中斷。同時(shí)電平翻轉(zhuǎn)。
在中斷中再次將當(dāng)前計(jì)數(shù)器CNT的值,加上脈沖長度X,寫入輸出比較寄存器。
在X個(gè)CK后,將會(huì)觸發(fā)輸出比較中斷。同時(shí)電平翻轉(zhuǎn)。
在中斷中再次將當(dāng)前計(jì)數(shù)器CNT的值,加上脈沖長度X,寫入輸出比較寄存器。
如此往復(fù)……
以此即可得到一個(gè)占空比為50%,周期為2X個(gè)CK的PWM。
確定最小單位CK,配置時(shí)基單元
首先確定一個(gè)最小的間隔CK,規(guī)定PWM的高電平長度和低電平長度的單位都是CK。
即高電平的長度一定是CK的整數(shù)倍。低電平亦然。
然后配置定時(shí)器的時(shí)基單元,通過CK的長度確定預(yù)分頻系數(shù)。
已知STM32F103的主頻為72MHZ,則時(shí)基單元中預(yù)分頻系數(shù)為
PSC = 72M / (1/CK)
例如,rtz所確定的CK長度為10us(0.00001s),即可得出方程。
預(yù)分頻系數(shù)確定為720后,由高速晶振產(chǎn)生的72MHZ的時(shí)鐘信號(hào)被720分頻,得到100000HZ的時(shí)鐘信號(hào)。即時(shí)鐘信號(hào)每秒變動(dòng)100000次。每次10us。同時(shí)可將重裝載值設(shè)定為0XFFFF(16位定時(shí)器的最大值)。因?yàn)楸敬问褂玫妮敵霰容^模式不使用更新中斷,該值可隨意設(shè)置。
TIM_TimeBaseStructure.TIM_Period = 0XFFFF;
TIM_TimeBaseStructure.TIM_Prescaler =720;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
開啟輸出比較通道,設(shè)置輸出比較模式為翻轉(zhuǎn)模式,并配置NVIC,開啟輸出比較中斷,配置輸出比較通道:
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
TIM_OCInitStructure.TIM_Pulse = 500;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
開啟輸出比較中斷,配置NVIC優(yōu)先級(jí):
TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
編寫中斷服務(wù)函數(shù)
在輸出比較中斷中,唯一要做的事情就是把當(dāng)前CNT的值取出,加上脈沖長度X,寫入輸出比較寄存器。
當(dāng)計(jì)數(shù)器達(dá)到0XFFFF(之前設(shè)定的重裝載值)后,再加一會(huì)自動(dòng)變?yōu)?span id="9zdrl7f" class="hljs-number">0.
例如,當(dāng)前CNT值為0XFFFF,脈沖長度為5,很明顯,輸出比較寄存器應(yīng)設(shè)置為0X0004才可觸發(fā)下一次中斷,而不是0X10004,這樣會(huì)造成溢出。
因此將CNT的值與脈沖長度相加后,需要取0XFFFF的余數(shù)后,再寫入輸出比較寄存器。
int t_m=5;//低電平和高電平的長度
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) {
TIM_SetCompare1(TIM2,(TIM2- >CNT+t_m)%0XFFFF);
TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
}
}
動(dòng)態(tài)調(diào)整中斷服務(wù)函數(shù)中的變量t_m,即可達(dá)到修改PWM頻率的效果。
-
機(jī)器人
+關(guān)注
關(guān)注
210文章
28103瀏覽量
205853 -
PWM
+關(guān)注
關(guān)注
114文章
5118瀏覽量
213168 -
電機(jī)
+關(guān)注
關(guān)注
142文章
8875瀏覽量
144860
發(fā)布評(píng)論請先 登錄
相關(guān)推薦
評(píng)論