一、前言
SG90舵機的工作原理主要是基于PWM(脈沖寬度調制)信號來控制。 SG90舵機內部有一個基準電壓,微處理器產(chǎn)生的PWM信號通過信號線進入舵機,產(chǎn)生直流偏置電壓,與舵機內部的基準電壓做比較獲得電壓差輸出。電壓差的正負輸出到電機驅動芯片上,從而決定電機的正反轉。當舵機開始旋轉的時候,舵機內部通過急聯(lián)減速齒輪帶動電位器旋轉,使得電壓差為零,電機停止轉動。
SG90舵機還分為180度和360度的類型,以及模擬舵機和數(shù)字舵機。模擬舵機需要不斷的發(fā)送PWM信號才能旋轉到指定的位置,而數(shù)字舵機只需要給一個目的地的PWM信號,就可以轉動到指定的位置。
在控制SG90舵機時,PWM波形的頻率是50HZ,即周期為20毫秒。在這個周期內,通過控制高電平的時長,就能夠控制舵機旋轉的角度。例如,高電平為0.5毫秒時,舵機旋轉到0度;高電平為2毫秒時,旋轉到135度;高電平為1.5毫秒時,旋轉到90度。
視頻講解:
STM32驅動SG90舵機實操(寫代碼實測)
SG90舵機的工作原理是通過接收PWM信號,控制電機的轉動,從而帶動舵機的旋轉,實現(xiàn)精確的角度控制。
下面是180°的SG90舵機商家給出的說明:寫了高電平時間與轉動的角度對應關系。
什么樣的波形是PWM波形? 下面的圖片就是一個解釋。
對于舵機的驅動原理: 只需要產(chǎn)生一個周期為20ms,高電平寬度為0.5ms-2.5ms的PWM方波就能驅動舵機。
180°舵機 是一次PWM波形就可以轉到指定的角度。
360°舵機需要持續(xù)發(fā)送PWM波形才可以轉動。
一個完整的PWM是由高電平和低電平組成的。 也就是一個周期內,也就是這個20ms內。 可以自由分配 高低電平的占用時間。
這個分配 高低電平的占用時間的過程就叫:調整占空比。
只需要控制這個20ms的周期內。高電平的時間在 0.5ms-2.5ms 范圍的內的PWM波形。 就可以任意控制舵機轉動。 那么 0.5ms-2.5ms 之間不同的值是有什么不同的效果? 對于: 90°舵機、180°的舵機 是不一樣的。
我當前是采用STM32F103單片機驅動的SG90舵機,采用的定時器1的通道1和通道4產(chǎn)生PWM波形,控制2個SG90轉動。
定時器1的CCR1寄存器就是比較寄存器,定時器1的CNT寄存器在定時器啟動之后就會不斷的自增或自減(具體看配置),簡單的說就是,CNT寄存器是一個時間基準;而輸出的PWM占空比就是依靠CNT寄存器的值與CCR1寄存器的值進行相互比較。 比誰大誰小,從而控制當前的電平是低電平還是高電平,這個過程就是控制占空比的過程。 具體的代碼表現(xiàn)形式就是: TIM1->CCR1=xxx
。
STM32F103RCT6單片機定時器的運行頻率是72MHZ; 如果我的定時器分頻為720,重裝載值填2000,這樣的配置,輸出的一個PWM周期就是50HZ,也就一個周期的總時間是20ms。
那么如何在代碼里,如何實現(xiàn)控制 0.5ms-2.5ms 這個范圍的高電平?
如果設置為: TIM1->CCR1=1860; 就表示 2000 -1860 = 140 = 1.4ms高電平。
如果設置為: TIM1->CCR1=1880; 就表示 2000 -1880= 120 = 1.2ms高電平。
…
…
…
二、程序開發(fā)
2.1 邏輯分析儀測試
寫好代碼之后,可以先用邏輯分析儀檢測一下單片機IO口輸出的PWM情況。
如果設置為: TIM1->CCR1=1860; 就表示 2000 -1860 = 140 = 1.4ms高電平。
看下面的邏輯分析儀測量的結果:
2.2 舵機的驅動問題
SG90舵機驅動的時候,要給外部電源。 如果采用開發(fā)板USB供電,是帶不動2個以及2個以上的SG90舵機,需要外接穩(wěn)壓電源提供足夠的電流才可以正常驅動舵機轉動。 這個一定要注意。
2.3 完整代碼
#include "stm32f10x.h"
#include "delay.h"
#include "usart.h"
#include <string.h>
#include "timer.h"
#include <string.h>
#include <stdlib.h>
/*
STM32F103C8T6可以用的IO口:PA0-PA15, PB0-PB15, PC13-PC15
STM32F103C8T6最小系統(tǒng)板的IO口。
PB11 PB10 PB1 PB0 PA7 PA6 PA5 PA4 PA3 PA2 PA1 PA0 PC15 PC14 PC13
PB12 PB13 PB14 PB15 PA8 PA9 PA10 PA11 PA12 PA15 PB3 PB4 PB5 PB6 PB7 PB8 PB9
PA13(SWDIO)和PA14(SWCLK): 用作STLNK-V2下載器的-SW模式的下載口。
【】攝像頭云臺舵機
GND----------->GND
VC------------->5V
PA8------------>IO(上下控制舵機)-定時器1的PWM-CH1
PA11---------->IO (左右控制舵機)-定時器1的PWM-CH4
*/
//舵機停止
void motor_Ctrl_Up_Down_stop(void)
{
TIM1->CCR1=1850; //改變占空比
}
//舵機停止
void motor_Ctrl_Left_Right_stop(void)
{
TIM1->CCR4=1850; //改變占空比
}
//舵機開始轉動: 正向
void motor_Ctrl_Up_Down_1(void)
{
TIM1->CCR1=1860; //改變占空比
}
//舵機開始轉動: 反向
void motor_Ctrl_Up_Down_2(void)
{
TIM1->CCR1=1840; //改變占空比
}
//舵機開始轉動: 正向
void motor_Left_Right_Down_1(void)
{
TIM1->CCR4=1860; //改變占空比
}
//舵機開始轉動: 反向
void motor_Left_Right_Down_2(void)
{
TIM1->CCR4=1840; //改變占空比
}
//JTAG模式設置,用于設置JTAG的模式
//mode:jtag,swd模式設置;00,全使能;01,使能SWD;10,全關閉;
#define JTAG_SWD_DISABLE 0X02
#define SWD_ENABLE 0X01
#define JTAG_SWD_ENABLE 0X00
void JTAG_Set(u8 mode)
{
u32 temp;
temp=mode;
temp<<=25;
RCC->APB2ENR|=1<<0; //開啟輔助時鐘
AFIO->MAPR&=0XF8FFFFFF; //清除MAPR的[26:24]
AFIO->MAPR|=temp; //設置jtag模式
}
void set_pwm_1(float ms)
{
if(ms >20)
{
ms=20;
}
TIM1->CCR1=2000-(ms*100);
}
void set_pwm_4(float ms)
{
if(ms >20)
{
ms=20;
}
TIM1->CCR4=2000-(ms*100);
}
int main()
{
//開啟STLINK_SWD下載模式
JTAG_Set(SWD_ENABLE);
//串口1初始化,用于打印
USART1_Init(115200);
printf("STM32串口1初始化成功.rn");
//初始化定時器1,輸出PWM,通道1、4,控制SG90舵機
//一個周期20ms
TIM1_PWM_Init(2000,720); //計數(shù)頻率 單脈沖+重復計數(shù)模式
//轉動到0°
set_pwm_1(0.5);
set_pwm_4(0.5);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
while(1)
{
//轉動到90°
set_pwm_1(1.5); //第一個先轉90
set_pwm_4(2.5); //第二個再轉180
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
set_pwm_1(0.5); //之后第一個再轉到0。
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
set_pwm_1(1.5); //然后第一個再賺到90。
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
set_pwm_4(0.5);//然后第二個再占到零。
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
set_pwm_1(0.5); //然后第一個在轉到零。
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
delay_ms(1000);
}
}