一、SG90舵機介紹
SG90是一種微型舵機,也被稱為伺服電機。它是一種小型、低成本的直流電機,通常用于模型和機器人控制等應(yīng)用中。SG90舵機可以通過電子信號來控制其精確的位置和速度。它具有體積小、重量輕、響應(yīng)快等特點,因此在各種小型機械設(shè)備上得到了廣泛應(yīng)用。
SG90舵機通常用于各種小型機械設(shè)備中,例如:
模型控制:SG90舵機可以用于遙控汽車、飛機、船只和其他模型的轉(zhuǎn)向、加速和剎車等控制。
機器人控制:SG90舵機也廣泛應(yīng)用于機器人領(lǐng)域,例如可以控制機器人的頭部旋轉(zhuǎn)、臂部移動等。
相機云臺:SG90舵機可以用于控制相機的運動,例如實現(xiàn)云臺的左右旋轉(zhuǎn)和上下移動。
自動化系統(tǒng):在一些自動化系統(tǒng)中,SG90舵機可以用來控制小型機械臂或手指的運動。
總之,SG90舵機適用于需要精確定位和緊湊設(shè)計的應(yīng)用場景。
二、普通IO口模擬PWM驅(qū)動SG90舵機
以下是一個簡單的示例代碼,用于通過PB5普通IO口產(chǎn)生模擬PWM信號來控制SG90舵機正向旋轉(zhuǎn)和反向旋轉(zhuǎn):
#include "stm32f10x.h"
#define PWM_FREQ 50 // 設(shè)置PWM信號頻率為50Hz
#define SERVO_MIN_PULSE_WIDTH 500 // 舵機最小脈寬500us
#define SERVO_MAX_PULSE_WIDTH 2500 // 舵機最大脈寬2500us
void delay_us(uint32_t us) {
uint32_t count = us * (SystemCoreClock / 1000000) / 9;
while(count--);
}
void servo_rotate(uint16_t pulse_width) {
GPIO_SetBits(GPIOB, GPIO_Pin_5); // 設(shè)置PB5輸出高電平
delay_us(pulse_width); // 延時等待脈寬結(jié)束
GPIO_ResetBits(GPIOB, GPIO_Pin_5); // 設(shè)置PB5輸出低電平
delay_us(20000 - pulse_width); // 延時保持50Hz的PWM周期
}
int main(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能GPIOB時鐘
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; // PB5口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 最大輸出頻率為50Mhz
GPIO_Init(GPIOB, &GPIO_InitStructure);
while(1) {
// 控制舵機正向旋轉(zhuǎn)360°
for (int i = SERVO_MIN_PULSE_WIDTH; i <= SERVO_MAX_PULSE_WIDTH; i += 10) {
servo_rotate(i);
}
for (int i = SERVO_MAX_PULSE_WIDTH; i >= SERVO_MIN_PULSE_WIDTH; i -= 10) {
servo_rotate(i);
}
// 控制舵機反向旋轉(zhuǎn)360°
for (int i = SERVO_MAX_PULSE_WIDTH; i >= SERVO_MIN_PULSE_WIDTH; i -= 10) {
servo_rotate(i);
}
for (int i = SERVO_MIN_PULSE_WIDTH; i <= SERVO_MAX_PULSE_WIDTH; i += 10) {
servo_rotate(i);
}
}
}
在這個代碼中,我們首先定義了PWM頻率以及舵機的最小和最大脈寬。然后,我們實現(xiàn)了一個延時函數(shù)delay_us()
,用于產(chǎn)生指定微秒數(shù)的延時。接下來,我們實現(xiàn)了一個servo_rotate()
函數(shù),用于控制舵機的旋轉(zhuǎn)。
在servo_rotate()
函數(shù)中,我們將PB5口設(shè)置為高電平,并延時等待一段時間,使得舵機旋轉(zhuǎn)到相應(yīng)的角度;然后將PB5口設(shè)置為低電平,延時保持PWM周期的長度,以達(dá)到模擬PWM信號的效果。
在主函數(shù)中,我們通過循環(huán)控制舵機旋轉(zhuǎn)360度,并在正向和反向旋轉(zhuǎn)之間進(jìn)行切換。具體來說,我們通過循環(huán)執(zhí)行servo_rotate()
函數(shù),并改變脈寬的值,實現(xiàn)舵機的旋轉(zhuǎn)。
需要注意的是,這個示例代碼只是一個簡單的演示,實際使用中可能需要根據(jù)舵機的具體型號和應(yīng)用場景進(jìn)行調(diào)整。同時,由于使用的是延時產(chǎn)生模擬PWM信號,因此控制的精度可能會受到其他因素的影響,如果需要更高的控制精度,可以考慮使用硬件定時器來產(chǎn)生PWM信號。
三、通過定時器輸出PWM控制SG90舵機
(1)配置定時器4的通道1為PWM模式,并且設(shè)置頻率為50Hz,占空比為5%~10%。
代碼如下:
// 開啟TIM4時鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
// 定時器4 PWM模式配置
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = 1999; // 72M / (2*2000) = 18KHz
TIM_TimeBaseStructure.TIM_Prescaler = 35; // 分頻系數(shù)36
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
// 定時器4通道1 PWM輸出配置
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 100; // 初始值
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM4, &TIM_OCInitStructure);
// 開啟定時器4
TIM_Cmd(TIM4, ENABLE);
(2)使用定時器4的通道1輸出PWM信號,使舵機正向旋轉(zhuǎn)360°,即將占空比由5%10%逐漸增加至12.5%2.5%。代碼如下:
for (int i = 100; i <= 250; i += 10) {
TIM_SetCompare1(TIM4, i);
delay_ms(50);
}
(3)使用定時器4的通道1輸出PWM信號,使舵機反向旋轉(zhuǎn)360°,即將占空比由12.5%2.5%逐漸減小至5%10%。代碼如下:
for (int i = 250; i >= 100; i -= 10) {
TIM_SetCompare1(TIM4, i);
delay_ms(50);
}
在上面的代碼中,delay_ms()函數(shù)是一個簡單的延時函數(shù),用于控制每次占空比變化后等待一段時間再進(jìn)行下一步操作。需要自己實現(xiàn)這個函數(shù)。
另外,SG90舵機正向旋轉(zhuǎn)和反向旋轉(zhuǎn)的具體占空比可能有所不同,需要根據(jù)實際情況調(diào)整代碼中的占空比值。