舵機詳解

在這裏插入圖片描述

  舵機,是指在自動駕駛儀中操縱飛機舵面(操縱面)轉動的一種執行部件。分有:
①電動舵機,由電動機、傳動部件和離合器組成。接受自動駕駛儀的指令信號而工作,當人工駕駛飛機時,由於離合器保持脫開而傳動部件不發生作用。
②液壓舵機,由液壓作動器和旁通活門組成。當人工駕駛飛機時,旁通活門打開,由於作動器活塞兩邊的液壓互相連通而不妨害人工操縱。此外,還有電動液壓舵機,簡稱“電液舵機”。
  舵機的大小由外舾裝按照船級社的規範決定,選型時主要考慮扭矩大小。如何審慎地選擇經濟且合乎需求的舵機,也是一門不可輕忽的學問。
[百度百科]

  舵機是一種位置(角度)伺服的驅動器,適用於那些需要角度不斷變化並可以保持的控制系統。在高檔遙控玩具,如飛機、潛艇模型,遙控機器人中已經得到了普遍應用。
  舵機是船舶上的一種大甲板機械。舵機的大小由外舾裝按照船級社的規範決定,選型時主要考慮扭矩大小。
  在航天方面,舵機應用廣泛。航天方面,導彈姿態變換的俯仰、偏航、滾轉運動都是靠舵機相互配合完成的。舵機在許多工程上都有應用,不僅限於船舶。

結構

在這裏插入圖片描述
  舵機在機器人技術中非常有用。如上圖所示,這些馬達體積很小,它們內置了控制電路。標準舵機系統,如Futaba S-148有42盎司/英寸的扭矩(相當於1.2千克的扭矩), 對於它的體積來說,已經非常強大了 。它還可以根據負載的變化調整功率。因此,負載較輕的舵機系統不會消耗太多的能量。舵機的內部結構如上圖所示。你可以看到控制電路,馬達,一組齒輪,還有外殼。你還可以看到連接外部的3根連線。

伺服電機的比例控制

  那麼,舵機是如何工作的呢?舵機有一些控制電路和一個電位器(一個可變電阻),連接到輸出軸。在上面的圖片中,可以看到可變電阻在電路板的左邊,三根紅線連接處。可變電阻允許控制電路監控伺服電機的電流角度。如果軸的角度正確,則電機關閉。如果電路發現角度不正確,將電機轉到正確的方向,直到角度正確。伺服系統的輸出軸可以移動180度左右 。

在這裏插入圖片描述

如何控制伺服電機的角度?

  如何控制伺服電機轉向的角度呢?控制線用來傳達角度信號。角度是由施加在控制導線上的脈衝的持續時間決定的。這叫做脈衝編碼調製。伺服系統期望每20毫秒看到一個脈衝(.02秒)。脈衝的長度將決定電機轉多遠距離。

例如,1.5毫秒的脈衝將使電機轉到90度位置(通常稱爲中性位置)。如果脈衝小於1.5 ms,則電機將軸向接近0度。如果脈衝大於1.5ms,則軸向180度方向旋轉。

詳細可查閱:舵機角度的控制原理
在這裏插入圖片描述

如上圖所示,脈衝的持續時間決定了輸出軸的角度。注意這裏的時間是說明性的,實際的時間取決於電機制造商。然而,原理是一樣的。

在這裏插入圖片描述

stm32驅動舵機程序

stm32舵機驅動源程序如下:

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "timer.h"



u16 led0pwmval;
int main(void)
{               

        delay_init();                     //延時函數初始化         
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);          //設置NVIC中斷分組2:2位搶佔優先級,2位響應優先級
        uart_init(115200);         //串口初始化爲115200
         LED_Init();                             //LED端口初始化
         TIM2_PWM_Init(1999,719);        //100Khz的計數頻率,計數到2000爲20ms   
          while(1)
                        {
           LED1=0;         
         


            
                                                                                 TIM_SetCompare3(TIM2,50);
                    delay_ms(5000);                                         //延時多久很重要,自己一點點試。
                                                               
                                                       //延時多久很重要,自己一點點試。
                                                                                                

               
        }
      

                        }

main函數程序

#include "timer.h"
#include "led.h"
#include "usart.h"

//V1.1 20120904
//1,增加TIM3_PWM_Init函數。
//2,增加LED0_PWM_VAL宏定義,控制TIM3_CH2脈寬                                                                          
//////////////////////////////////////////////////////////////////////////////////  
            
//通用定時器3中斷初始化
//這裏時鐘選擇爲APB1的2倍,而APB1爲36M
//arr:自動重裝值。
//psc:時鐘預分頻數
//這裏使用的是定時器3!
void TIM3_Int_Init(u16 arr,u16 psc)
{
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //時鐘使能

        TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器週期的值         計數到5000爲500ms
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作爲TIMx時鐘頻率除數的預分頻值  10Khz的計數頻率  
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //設置時鐘分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上計數模式
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據TIM_TimeBaseInitStruct中指定的參數初始化TIMx的時間基數單位

        TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中斷,允許更新中斷

        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中斷
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先佔優先級0級
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //從優先級3級
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //根據NVIC_InitStruct中指定的參數初始化外設NVIC寄存器

        TIM_Cmd(TIM3, ENABLE);  //使能TIMx外設
                                                         
}
//定時器3中斷服務程序
void TIM3_IRQHandler(void)   //TIM3中斷
{
        if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //檢查指定的TIM中斷髮生與否:TIM 中斷源
                {
                TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中斷待處理位:TIM 中斷源
                LED1=!LED1;
                }
}




//TIM3 PWM部分初始化
//PWM輸出初始化
//arr:自動重裝值
//psc:時鐘預分頻數
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);        //使能定時器3時鐘
         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外設和AFIO複用功能模塊時鐘
        
//GPIO_PinRemapConfig(GPIO_PartialRemap_TIM2, ENABLE); //Timer3部分重映射  TIM3_CH2->PB5   

   //設置該引腳爲複用輸出功能,輸出TIM3 CH2的PWM脈衝波形        GPIOB.5
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //TIM_CH2
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //複用推輓輸出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO

   //初始化TIM3
        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的時間基數單位
        
        //初始化TIM3 Channel2 PWM模式         
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //選擇定時器模式:TIM脈衝寬度調製模式2
         TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比較輸出使能
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //輸出極性:TIM輸出比較極性高
        TIM_OC3Init(TIM2, &TIM_OCInitStructure);  //根據T指定的參數初始化外設TIM3 OC2

        TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的預裝載寄存器

        TIM_Cmd(TIM2, ENABLE);  //使能TIM3
        

}

32代碼引自>>單片機論壇»論壇›電子技術分類討論區›資料共享›stm32舵機驅動例程http://www.51hei.com/bbs/dpj-150290-1.html

arduino驅動舵機程序

#include <Servo.h>

Servo myservo;  // 定義Servo對象來控制
int pos = 0;    // 角度存儲變量

void setup() {
  myservo.attach(9);  // 控制線連接數字9
}

void loop() {
  for (pos = 0; pos <= 180; pos ++) { // 0°到180°
    // in steps of 1 degree
    myservo.write(pos);              // 舵機角度寫入
    delay(10);                       // 等待轉動到指定角度
  }
  for (pos = 180; pos >= 0; pos --) { // 從180°到0°
    myservo.write(pos);              // 舵機角度寫入
    delay(10);                       // 等待轉動到指定角度
  }
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章