數字舵機 vs 模擬舵機 “數字舵機區別于傳統的模擬舵機,模擬舵機需要給它不停的發送PWM信號,才能讓它保持在規定的位置或者讓它按照某個速度轉動,數字舵機則只需要發送一次PWM信號就能保持在規定的某個位置。”
"到底模擬舵機與數碼舵機在實際使用中有什么區別呢?我自己總結大致有以下幾點:
1 數碼舵機在位置準確度方面要高于模擬舵機。
2 在同樣標稱1.6公斤的舵機面前數碼舵機在實際表現中會感覺更加“力氣大”而模擬舵機就會“肉”點。
3 模擬舵機由于控制芯片是模擬電路,所以即便是相同型號的舵機會存在小小的性能差異,而數碼舵機在一致性方面就非常好。
4 數碼舵機一般均采用PID優化算法,所以,線性要好過模擬舵機。
5 對于高靈敏度的控制,建議選擇數碼舵機,如直升機的控制,高速固定翼飛機,高速滑翔機,比賽用車膜型,云臺的控制等
6 對于不是特別需要靈敏度的場合,如低速固定翼(二戰飛機,練習機,低速滑翔機等),船模,娛樂用車模等。可以考慮模擬舵機。
"(http://www.321mx.com/blog/548.html)
基本上參考《STM32不完全手冊——庫函數版本》
pwm.c 初始化函數
[cpp]?view plaincopy
????????void?TIM_PWM_Init(u16?arr,u16?psc)??{????????GPIO_InitTypeDef?GPIO_InitStructure;??????TIM_TimeBaseInitTypeDef??TIM_TimeBaseStructure;??????TIM_OCInitTypeDef??TIM_OCInitStructure;????????RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2?|?RCC_APB1Periph_TIM3?|?RCC_APB1Periph_TIM4,?ENABLE);??????RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA?|?RCC_APB2Periph_GPIOB?,?ENABLE);?????????????????????????????????????????????????????????????????????????????????????????????GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_2?|?GPIO_Pin_3;???????GPIO_InitStructure.GPIO_Mode?=?GPIO_Mode_AF_PP;????????GPIO_InitStructure.GPIO_Speed?=?GPIO_Speed_50MHz;??????GPIO_Init(GPIOA,?&GPIO_InitStructure);????????????GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_0?|?GPIO_Pin_1?|?GPIO_Pin_8?|?GPIO_Pin_9;?????GPIO_Init(GPIOB,&GPIO_InitStructure);???????????????????TIM_TimeBaseStructure.TIM_Period?=?arr;???????TIM_TimeBaseStructure.TIM_Prescaler?=psc;???????TIM_TimeBaseStructure.TIM_ClockDivision?=?0;???????TIM_TimeBaseStructure.TIM_CounterMode?=?TIM_CounterMode_Up;??????????????TIM_TimeBaseInit(TIM2,?&TIM_TimeBaseStructure);???????TIM_TimeBaseInit(TIM3,?&TIM_TimeBaseStructure);???????TIM_TimeBaseInit(TIM4,?&TIM_TimeBaseStructure);????????????TIM_OCInitStructure.TIM_OCMode?=?TIM_OCMode_PWM1;???????TIM_OCInitStructure.TIM_OutputState?=?TIM_OutputState_Enable;???????TIM_OCInitStructure.TIM_Pulse?=?0;???????TIM_OCInitStructure.TIM_OCPolarity?=?TIM_OCPolarity_High;?????????TIM_OC3Init(TIM2,?&TIM_OCInitStructure);????????TIM_OC3PreloadConfig(TIM2,?TIM_OCPreload_Enable);??????TIM_OC4Init(TIM2,?&TIM_OCInitStructure);????????TIM_OC4PreloadConfig(TIM2,?TIM_OCPreload_Enable);??????TIM_OC3Init(TIM3,?&TIM_OCInitStructure);????????TIM_OC3PreloadConfig(TIM3,?TIM_OCPreload_Enable);??????TIM_OC4Init(TIM3,?&TIM_OCInitStructure);????????TIM_OC4PreloadConfig(TIM3,?TIM_OCPreload_Enable);????????TIM_OC3Init(TIM4,?&TIM_OCInitStructure);????????TIM_OC3PreloadConfig(TIM4,?TIM_OCPreload_Enable);??????TIM_OC4Init(TIM4,?&TIM_OCInitStructure);????????TIM_OC4PreloadConfig(TIM4,?TIM_OCPreload_Enable);????????????????????TIM_ARRPreloadConfig(TIM2,?ENABLE);???????TIM_CtrlPWMOutputs(TIM2,ENABLE);??????????TIM_Cmd(TIM2,?ENABLE);????????TIM_ARRPreloadConfig(TIM3,?ENABLE);???????TIM_CtrlPWMOutputs(TIM3,ENABLE);??????????TIM_Cmd(TIM3,?ENABLE);????????TIM_ARRPreloadConfig(TIM4,?ENABLE);???????TIM_CtrlPWMOutputs(TIM4,ENABLE);??????????TIM_Cmd(TIM4,?ENABLE);????}??
int main(void)
{?
u16 pwmval1=749;//1.5ms->90度
delay_init(); //延時函數初始化?
TIM_PWM_Init(9999,143);//不分頻。PWM 頻率=72*10^6/(9999+1)/(143+1)=50Hz
while(1)
{
//調節占空比pwmval1/(9999+1)
TIM_SetCompare3(TIM2,pwmval1);TIM_SetCompare4(TIM2,pwmval1);
TIM_SetCompare3(TIM3,pwmval1);TIM_SetCompare4(TIM3,pwmval1);
TIM_SetCompare3(TIM4,pwmval1);TIM_SetCompare4(TIM4,pwmval1);
}
}
以下轉自:http://www.cnblogs.com/ghdnui/articles/3429732.html
[html]?view plaincopy
void?TIM_Configuration(void)??{??????TIM_TimeBaseInitTypeDef??TIM_TimeBaseStructure;??????TIM_OCInitTypeDef??TIM_OCInitStructure;??????GPIO_InitTypeDef????GPIO_InitStructure;??????RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA?|?RCC_APB2Periph_GPIOB,?ENABLE);??????RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3?|?RCC_APB1Periph_TIM4?,?ENABLE);??????????????????GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_6?|?GPIO_Pin_7;?//TIM3的1、2通道????,產生PWM??????GPIO_InitStructure.GPIO_Mode?=?GPIO_Mode_AF_PP;??????GPIO_InitStructure.GPIO_Speed?=?GPIO_Speed_50MHz;??????GPIO_Init(GPIOA,&GPIO_InitStructure);???????//PA的6,7口對應TIM3的1、2通道,設置為復用推挽輸出????????GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_6?|?GPIO_Pin_7?|?GPIO_Pin_8?|?GPIO_Pin_9;?//TIM4的1、2、3、4通道??????GPIO_Init(GPIOB,&GPIO_InitStructure);?????//B口的6,7,8,9對應TIM4的1、2、3、4通道,設置為復用推挽輸出????????TIM_TimeBaseStructure.TIM_Period?=9999;???????????//自動重載周期值??????TIM_TimeBaseStructure.TIM_Prescaler?=143;??????????//預分頻值?,這里是50HZ??????TIM_TimeBaseStructure.TIM_ClockDivision?=?0x0;????????//時鐘分割??????TIM_TimeBaseStructure.TIM_CounterMode?=?TIM_CounterMode_Up;??????//計數摸式為向上計數??????TIM_TimeBaseInit(TIM3,?&TIM_TimeBaseStructure);??????TIM_TimeBaseInit(TIM4,?&TIM_TimeBaseStructure);?????????//TIM3,和TIM4用的相同配置,寫入配置??,PWM頻率為50HZ??????????????????????????????????????????????????????????????????????????????//設定占空比????????????TIM_OCStructInit(&?TIM_OCInitStructure);??????//恢復初始??????TIM_OCInitStructure.TIM_OCMode?=?TIM_OCMode_PWM1;??//定時器模式為pwm模式1??????TIM_OCInitStructure.TIM_Pulse?=0;??????????????//脈沖值,即輸出都是低電平??????TIM_OCInitStructure.TIM_OutputState?=?TIM_OutputState_Enable;??????TIM_OCInitStructure.TIM_OCPolarity?=?TIM_OCPolarity_High;?????//極性為高????????????TIM_OC1Init(TIM3,?&TIM_OCInitStructure);?????//將配置數據寫入TIM3的通道1??????TIM_OC1PreloadConfig(TIM3,?TIM_OCPreload_Enable);????//預裝載使能??????TIM_OC2Init(TIM3,?&TIM_OCInitStructure);??????TIM_OC2PreloadConfig(TIM3,?TIM_OCPreload_Enable);????????TIM_OC1Init(TIM4,?&TIM_OCInitStructure);??????TIM_OC1PreloadConfig(TIM4,?TIM_OCPreload_Enable);??????TIM_OC2Init(TIM4,?&TIM_OCInitStructure);??????TIM_OC2PreloadConfig(TIM4,?TIM_OCPreload_Enable);??????TIM_OC3Init(TIM4,?&TIM_OCInitStructure);??????TIM_OC3PreloadConfig(TIM4,?TIM_OCPreload_Enable);??????TIM_OC4Init(TIM4,?&TIM_OCInitStructure);??????TIM_OC4PreloadConfig(TIM4,?TIM_OCPreload_Enable);//TIM4的4個通道都用相同的配置??????TIM_Cmd(TIM3,?ENABLE);??????TIM_CtrlPWMOutputs(TIM3,?ENABLE);??????TIM_Cmd(TIM4,?ENABLE);??????TIM_CtrlPWMOutputs(TIM4,?ENABLE);??????????//使能PWM模式??}??
[html]?view plaincopy
void?SetJointAngle(u8?ID,?float?angle)??{??????switch(ID)??????{??????????case?0:??????????????????????????????????????//-90°~90°?????????????????angle=angle+90.0;????????????????????????????????????angle=(u16)(50.0*angle/9.0+249.0);???????????????????TIM_SetCompare1(TIM3,angle);??????????????????????break;???????????????????????????????????????????????????//0°~180°??????????case?1:??????????????angle=(u16)(4.175*angle+409.25);??????????????TIM_SetCompare2(TIM3,angle);????????????????????????break;??????????????case?2:????????????????????????????????????//-150°~0°??????????????angle=-angle;??????????????angle=(u16)(4.175*angle+480.0);??????????????TIM_SetCompare1(TIM4,angle);??????????????break;????????????case?3:??????????????angle=-180-angle;??????????????angle=-angle;??????????????angle=(u16)(4.175*angle+315.0);??????????????????????????TIM_SetCompare2(TIM4,angle);??????????????break;????????????????????????????????????????????????//-90°~90°??????????case?4:??????????????angle=90.0+angle;??????????????angle=(u16)(249.0+50.0*angle/9.0);??????????????TIM_SetCompare3(TIM4,angle);??????????????????????????break;???????????????default:?break;??????}??????}??
舵機原理:http://blog.csdn.net/a2009374138/article/details/8772432
1、什么是舵機
? ? ? ?舵機是一種位置(角度)伺服的驅動器,適用于那些需要角度不斷變化并可以保持的控制系統。目前在高檔遙控玩具,如航模,包括飛機模型,潛艇模型;遙控機器人中已經使用得比較普遍。舵機是一種俗稱,其實是一種伺服馬達。
? ? ? ??
2、工作原理
? ? ? ?控制信號由接收機的通道進入信號調制芯片,獲得直流偏置電壓。它內部有一個基準電路,產生周期為20ms,寬度為1.5ms的基準信號,將獲得的直流偏置電壓與電位器的電壓比較,獲得電壓差輸出。最后,電壓差的正負輸出到電機驅動芯片決定電機的正反轉。當電機轉速一定時,通過級聯減速齒輪帶動電位器旋轉,使得電壓差為0,電機停止轉動。當然我們可以不用去了解它的具體工作原理,知道它的控制原理就夠了。就象我們使用晶體管一樣,知道可以拿它來做開關管或放大管就行了,至于管內的電子具體怎么流動是可以完全不用去考慮的。
3、舵機的控制
? ? ? ? 舵機的控制一般需要一個20ms左右的時基脈沖,該脈沖的高電平部分一般為0.5ms~2.5ms范圍內的角度控制脈沖部分。以180度角度伺服為例,那么對應的控制關系是這樣的:
? ? ? 0.5ms----------- ? ?0度
? ? ? 1.0ms----------- ?45度
? ? ? 1.5ms----------- ?90度
? ? ? 2.0ms-----------135度
? ? ? 2.5ms-----------180度
? ? ??
? ? ? 小型舵機的工作電壓一般為4.8V或6V,轉速也不是很快,一般為0.22/60度或0.18/60度,所以假如你更改角度控制脈沖的寬度太快時,舵機可能反應不過來。如果需要更快速的反應,就需要更高的轉速了。
? ? ? 舵機上有三根線,分別為VCC、GND、信號線。而不需要另外接驅動模塊,直接用單片機的管腳控制就行了。控制信號一般要求周期為20ms的PWM信號。
? ? ? 如果要更為精確的控制舵機(轉動角度差<=1度),則需要控制輸出PWM信號的占空比,
? ? ? 例如:我可以把0~180分為1024份(可以任取,決定與定時器的時鐘頻率),范圍為0.5ms~2.5ms
? ? ? ? ? ? ? ? ? 則可以得到0.09度/us,因此可以由 PWM=0.5+N*0.09(N是角度)控制舵機轉動0~180度間的任意角度。
轉自:http://blog.csdn.net/gtkknd/article/details/39296151
首先,本人雖然初學STM32但極力反對一種誤人子弟的觀點:“對于STM32這樣級別的MCU,有庫函數就不用去看寄存器怎么操作的了!”
好了,言歸正傳,最近總看到很多朋友對于PWM這個實驗有很多的疑惑,看到原子也在極力的回復也挺累的(體諒一下幸苦的原子大神,(*^__^*) ),所以我打算寫這么一篇文字來闡述一下我個人對STM32的PWM的理解。
首先來說,你要使用PWM模式你得先選擇用那個定時器來輸出PWM吧!除了TIM6、TIM7這兩個普通的定時器無法輸出PWM外,其余的定時器都可以輸出PWM,每個通用定時器可以輸出4路PWM,高級定時器TIM1、TIM8每個可輸出7路PWM,這里為了方便起見,我們選擇與實驗相同的TIM3的通道2來說明。選好定時器及通道后,下一步就是要使能定時器的時鐘,根據需要看看是否需要重映射IO,然后就是配置輸出PWM的IO及定時器,到這里原子的視頻及例程都有詳細的介紹,這里只需要提一點有些網友疑惑的TIM_TimeBaseStructure.TIM_ClockDivision = 0;這句話是什么作用?其實仔細看過技術手冊后發現這句話與PWM輸出實驗其實是沒關系的,這句話是設置定時器時鐘(CK_INT)頻率與數字濾波器(ETR,TIx)使用的采樣頻率之間的分頻比例的(與輸入捕獲相關),0表示濾波器的頻率和定時器的頻率是一樣的。至于其余部分,我就不再贅述。做完這些準備工作后,我就針對大多數朋友疑惑的地方——PWM模式的初始化設置做一個詳細的闡述:先貼代碼
?????1???????TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //選擇定時器模式:TIM脈沖寬度調制模式2
?????2???????TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
?????3???????TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高
?????4???????TIM_OC2Init(TIM3, &TIM_OCInitStructure); ? //根據T指定的參數初始化外設TIM3 OC2
?????5???????TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);?//使能TIM3在CCR2上的預裝載寄存器,即TIM3_CCR2的預裝載值在更新事件到來時才能被傳送至當前寄存器中。
?????6???????TIM_Cmd(TIM3, ENABLE);? //使能TIM3
這6句話就把PWM的通道配置好了,一句句來解釋:
這里原子選擇的PWM2模式,為什么選擇的是PWM2模式呢?為什么不選擇PWM1模式呢?兩者又有什么區別呢?下面我們就一探究竟,PWM1和PWM2模式是由CCMR1的OC1M和OC2M來決定的,因為我們選擇的是是通道2,所以設置的是OC2M,再看相關介紹
OC1M[2:0]:輸出比較1模式(Output compare 1 enable)
110:PWM模式1- 在向上計數時,一旦TIMx_CNT<TIMx_CCR1時通道1為有效電平,否則為
無效電平;在向下計數時,一旦TIMx_CNT>TIMx_CCR1時通道1為無效電平(OC1REF=0),否
則為有效電平(OC1REF=1)。
111:PWM模式2- 在向上計數時,一旦TIMx_CNT<TIMx_CCR1時通道1為無效電平,否則為
有效電平;在向下計數時,一旦TIMx_CNT>TIMx_CCR1時通道1為有效電平,否則為無效電
平。
?看到紅色的“有效電平”了吧,那么這又是誰定義的呢?別急,再看手冊,可知它是由CCER這個寄存器的CCxP來決定的這里是通道2,所以是CC2P,繼續看介紹
CC1P:輸入/捕獲1輸出極性(Capture/Compare 1 output polarity)? 位1?
CC1通道配置為輸出:
0:OC1高電平有效
1:OC1低電平有效
現在很清楚了吧,又因為第3句,TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高,所以這里我們設置的CC2P是0,也就是默認的OC2高電平有效。這樣第3句話也捎帶著解釋了,哈哈!由于我們的戰艦板的LED是低電平亮,而剛開始的給CC2P用來設置占空比的led0pwmval為0它是小于等于TIM3_CNT的,也就符合TIMx_CNT>=TIMx_CCR1時通道2輸出有效電平,也就是高電平,所以你把原子的例程原封不動的Down到板子里,會看到剛上電,LED燈是不亮的。現在這塊明白了吧!若你覺得還是不爽,我就非得用PWM1模式,那也可以,就像有個網友說“我拿原子的PWM Code就改了一個PWM1模式,按原子講的PWM1和PWM2的輸出是相反的啊,可是我上電發現LED是常亮的啊?怎么回事啊,求解釋啊。。。”我們來分析一下這位朋友的代碼,他把PWM2改成了PWM1,別的什么都沒動,那么現在符合“PWM模式1- 在向上計數時,一旦TIMx_CNT<TIMx_CCR1時通道1為有效電平”
,否則為無效電平。“結果必然是就是LED長亮嘍,要想得到跟原代媽一樣的效果,那就把CC2P設置成1,OC2低電平有效,這樣就可以了,有興趣的朋友可以動手試試!(實踐出真知嗎!)
好了,廢了這么多話,也不早了 洗洗睡吧!希望這篇文字對PWM有疑惑的朋友有所幫助!希望大家共同進步!分享是一種快樂,歡迎批評指正!
?遺漏了一點,第5句還沒解釋呢,
5?????? TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM3在CCR2上的預裝載寄存器,即TIM3_CCR2的預裝載值在更新事件到來時才能被傳送至當前寄存器中。
這句話是說,CCR2中的預裝載值何時被傳送到當前的CNT寄存器中,這里我們選擇的是當更新事件到來的時候才裝載,追蹤寄存器的設置可知,原來設置的是CCMR1的OC2PE,其實還有一種方式是立即裝載看手冊:
OC1PE:輸出比較1預裝載使能(Output compare 1 preload enable)? 位3?
0:禁止TIMx_CCR1寄存器的預裝載功能,可隨時寫入TIMx_CCR1寄存器,并且新寫入的數
值立即起作用。
1:開啟TIMx_CCR1寄存器的預裝載功能,讀寫操作僅對預裝載寄存器操作,TIMx_CCR1的
預裝載值在更新事件到來時被傳送至當前寄存器中。
注意:
舵機供電得特別注意;供電電流必須能夠驅動舵機呢。 否則 結果不如人意。舵機的電一般是單獨提
總結
以上是生活随笔為你收集整理的stm32控制360度舵机和180度舵机的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。