一模塊來源
模塊實物展示:
資料鏈接:https://pan.baidu.com/s/1QsTIKnoQsOTCkeYLLTTjTA?pwd=8889
資料提取碼:8889
二規(guī)格參數(shù)
驅(qū)動電壓:3V~7.2V
工作扭矩:1.6KG/CM
控制方式:PWM
轉(zhuǎn)動角度:180度
以上信息見廠家資料文件
三移植過程
我們的目標(biāo)是將例程移植至CW32F030C8T6開發(fā)板上【能夠控制舵機(jī)旋轉(zhuǎn)的功能】。首先要獲取資料,查看數(shù)據(jù)手冊應(yīng)如何實現(xiàn)讀取數(shù)據(jù),再移植至我們的工程。
3.1查看資料
在購買時,需要分清楚你的舵機(jī)可以轉(zhuǎn)180度,還是360度。360度的舵機(jī)是無法控制角度的,只可以控制旋轉(zhuǎn)速度。
180度舵機(jī)
360度舵機(jī)
SG90的舵機(jī)轉(zhuǎn)速不是很快,一般為0.22/60 度或0.18/60 度,所以假如你更改角度控制脈沖的寬度太快時,舵機(jī)可能反應(yīng)不過來。如果需要更快速的反應(yīng),就需要更高的轉(zhuǎn)速了。
3.2引腳選擇
模塊接線圖
3.3移植至工程
移植步驟中的導(dǎo)入.c和.h文件與【CW32模塊使用】DHT11溫濕度傳感器相同,只是將.c和.h文件更改為bsp_sg90.c與bsp_sg90.h。這里不再過多講述,移植完成后面修改相關(guān)代碼。
在文件bsp_sg90.c中,編寫如下代碼。
/*
* Change Logs:
* Date Author Notes
* 2024-06-25 LCKFB-LP first version
*/
#include "bsp_sg90.h"
unsigned int Servo_Angle = 0;//舵機(jī)角度
/******************************************************************
* 函 數(shù) 名 稱:SG90_Init
* 函 數(shù) 說 明:PWM配置
* 函 數(shù) 形 參:pre定時器時鐘預(yù)分頻值 per周期
* 函 數(shù) 返 回:無
* 作 者:LC
* 備 注:
配置占空比 范圍 0 ~ (per-1)
// t = 0.5ms——————-舵機(jī)會轉(zhuǎn)動 0 °
// t = 1.0ms——————-舵機(jī)會轉(zhuǎn)動 45°
// t = 1.5ms——————-舵機(jī)會轉(zhuǎn)動 90°
// t = 2.0ms——————-舵機(jī)會轉(zhuǎn)動 135°
// t = 2.5ms——————-舵機(jī)會轉(zhuǎn)動180°
// 1.我該如何計算括號里的數(shù),從而實現(xiàn)我想要的功能?
// 此處以90度為例。
// 答:PWM周期為20ms,所以占空比就應(yīng)該為1.5ms/20ms = 7.5%,
// 所以 TIMx 捕獲比較 1 寄存器值就為period-period*7.5% = 84-84*7.5%=77.7
******************************************************************/
void SG90_Init(void)
{
// 啟用 GPIO 和定時器時鐘
RCC_SIG_GPIO_ENABLE(); // 啟用 GPIO 時鐘
RCC_SIG_TIMER_ENABLE(); // 啟用定時器時鐘
// 初始化 GPIO
GPIO_InitTypeDef GPIO_InitStruct; // GPIO 初始化結(jié)構(gòu)體
GPIO_InitStruct.Pins = GPIO_SIG; // GPIO 引腳
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 推挽輸出模式
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; // 高速
GPIO_AF_SIG_ENABLE(); // 啟用 GPIO 復(fù)用功能
GPIO_Init(PORT_SIG, &GPIO_InitStruct); // 初始化 GPIO
// 初始化定時器 (GTIM3)
GTIM_InitTypeDef GTIM_InitStruct; // 定時器初始化結(jié)構(gòu)體
GTIM_InitStruct.Mode = GTIM_MODE_TIME; // 定時器模式
GTIM_InitStruct.OneShotMode = GTIM_COUNT_CONTINUE; // 連續(xù)計數(shù)模式
GTIM_InitStruct.Prescaler = GTIM_PRESCALER_DIV64; // 預(yù)分頻器 (DCLK = PCLK / 64 = 64 MHz / 64 = 1 MHz)
GTIM_InitStruct.ReloadValue = 20000 - 1; // 重裝載值 (20 ms 周期)
GTIM_InitStruct.ToggleOutState = ENABLE; // 輸出翻轉(zhuǎn)功能
GTIM_TimeBaseInit(BSP_SIG_TIMER, >IM_InitStruct); // 初始化定時器
GTIM_OCInit(BSP_SIG_TIMER, BSP_PWM_CHANNEL, GTIM_OC_OUTPUT_PWM_LOW); // 配置輸出比較通道為低電平有效的 PWM 模式
GTIM_Cmd(BSP_SIG_TIMER, ENABLE); // 啟用定時器
}
/******************************************************************
* 函 數(shù) 名 稱:Set_Servo_Angle
* 函 數(shù) 說 明:設(shè)置角度
* 函 數(shù) 形 參:angle=要設(shè)置的角度,范圍0-180
* 函 數(shù) 返 回:無
* 作 者:LC
* 備 注:無
******************************************************************/
void Set_Servo_Angle(unsigned int angle)
{
if(angle > 180)
{
angle = 180; // 限制角度在0到180度之間
}
// 計算PWM占空比
// 注意:這里的20000是基于GTIM_Period設(shè)置為20000的
// 0.5ms對應(yīng)的計數(shù) = (0.5 / 20) * 20000
// 2.5ms對應(yīng)的計數(shù) = (2.5 / 20) * 20000
// 因此,角度從0到180度時,占空比應(yīng)該從0.5ms到2.5ms線性變化
unsigned int ServoAngle = (unsigned int)((0.5 + (angle / 180.0) * 2.0) / 20.0 * 20000);
GTIM_SetCompare1(BSP_SIG_TIMER, ServoAngle);
}
/******************************************************************
* 函 數(shù) 名 稱:讀取當(dāng)前角度
* 函 數(shù) 說 明:Get_Servo_Angle
* 函 數(shù) 形 參:無
* 函 數(shù) 返 回:當(dāng)前角度
* 作 者:LC
* 備 注:使用前必須確保之前使用過
void Set_Servo_Angle(unsigned int angle)
函數(shù)設(shè)置過角度
******************************************************************/
unsigned int Get_Servo_Angle(void)
{
return Servo_Angle;
}
在文件bsp_sg90.h中,編寫如下代碼。
/*
* Change Logs:
* Date Author Notes
* 2024-06-25 LCKFB-LP first version
*/
#ifndef _BSP_SG90_H
#define _BSP_SG90_H
#include "board.h"
#define RCC_SIG_GPIO_ENABLE() __RCC_GPIOA_CLK_ENABLE()
#define PORT_SIG CW_GPIOA
#define GPIO_SIG GPIO_PIN_6
#define GPIO_AF_SIG_ENABLE() PA06_AFx_GTIM3CH1()
#define RCC_SIG_TIMER_ENABLE() __RCC_GTIM3_CLK_ENABLE()
#define BSP_SIG_TIMER CW_GTIM3 // 定時器
#define BSP_PWM_CHANNEL GTIM_CHANNEL1
void SG90_Init(void);
void Set_Servo_Angle(unsigned int angle);
unsigned int Get_Servo_Angle(void);
void TIM3_PWM_Init_AllChannel(void);
#endif
四移植驗證
在自己工程中的main主函數(shù)中,編寫如下。
/*
* Change Logs:
* Date Author Notes
* 2024-06-25 LCKFB-LP first version
*/
#include "board.h"
#include "stdio.h"
#include "bsp_uart.h"
#include "bsp_sg90.h"
int32_t main(void)
{
int i = 0;
board_init();
uart1_init(115200U);
SG90_Init();
Set_Servo_Angle(180);
delay_ms(1000);
Set_Servo_Angle(0);
delay_ms(1000);
while(1)
{
Set_Servo_Angle(i++);
if( i >= 180 )
{
i = 0;
}
delay_ms(10);
}
}
移植現(xiàn)象:舵機(jī)從0度轉(zhuǎn)到180度后,再從0度重新開始轉(zhuǎn)。
模塊移植成功案例代碼:
鏈接:https://pan.baidu.com/s/1bWrJCuW5w55yN94rDQfZGQ?pwd=LCKF
提取碼:LCKF