抽空寫了些模塊的驅動,順便加深對程序的理解。今天寫了舵機的驅動,這裏記錄學習的過程,以及收穫。
- 舵機簡介
- 程序編寫
舵機簡介
我這次用到的舵機其中之一是SG90,另外一個黑色的舵機應該是MG90,看圖:
要實現舵機的控制,我覺得最重要的是理解STM32的時鐘。查閱資料很容易就可以知道,要使舵機正常工作,首先要輸入20ms的週期信號。STM32F4是通過對自動重裝載值和分頻係數的設置完成這個週期信號的輸出的。舵機部分詳細介紹可以參考 _pray 的博客,寫得非常棒。
程序編寫
舵機配置部分,我把說明寫在了函數裏面的註釋,應該比較容易理解,畢竟就是用到PWM輸出的原理。
/*****************************************************************************
函數功能:利用通用定時器輸出PWM波控制舵機轉動角度,舵機轉動角度範圍:0`-180`
舵機分析:舵機接收PWM頻率爲50Hz,由f=1/T,當f=50時,T=0.02s,即20ms,
因此可通過配置通用定時器輸出週期爲20ms的PWM波來使舵機工作
相關配置:定時器選取通用定時器3,通道選取通道2,GPIO口輸出爲PB5
參數設置:自動裝載值:2000,定時器分頻係數:900,根據公式:
計數頻率:90M/900=0.1M,PWM頻率:0.1M/2000=50Hz
個人總結:輸出的方波週期就是自動重裝載值的值(us爲單位),佔空比 = compare / arr
*****************************************************************************/
#include "duoji.h"
TIM_HandleTypeDef TIM3_Handler;
TIM_OC_InitTypeDef TIM3_CH2_Handler;
//舵機初始化函數,這裏使用到的是定時器3通道2輸出PWM
void duoji_init(u16 arr,u16 psc)
{
TIM3_Handler.Instance=TIM3;//選取通用定時器3
TIM3_Handler.Init.Prescaler=psc;//定時器分頻
TIM3_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;//向上計數模式
TIM3_Handler.Init.Period=arr;//自動重裝載值
TIM3_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//
HAL_TIM_PWM_Init(&TIM3_Handler);//初始化PWM配置
TIM3_CH2_Handler.OCMode=TIM_OCMODE_PWM1;//選取模式1
TIM3_CH2_Handler.Pulse=arr/2;//設置比較值,確定佔空比
TIM3_CH2_Handler.OCNPolarity=TIM_OCPOLARITY_LOW;//輸出比較極性爲低
HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CH2_Handler,TIM_CHANNEL_2);//配置TIM3通道2
HAL_TIM_PWM_Start(&TIM3_Handler,TIM_CHANNEL_2);//開啓PWM通道2
}
//回調函數
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_TIM3_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_Initure.Pin=GPIO_PIN_5;//PB5
GPIO_Initure.Mode=GPIO_MODE_AF_PP;//複用推輓輸出
GPIO_Initure.Pull=GPIO_PULLUP;//上拉
GPIO_Initure.Speed=GPIO_SPEED_HIGH;//高速
GPIO_Initure.Alternate=GPIO_AF2_TIM3;//複用爲TIM3_CH2
HAL_GPIO_Init(GPIOB,&GPIO_Initure);//初始化GPIOB
}
//設置 TIM 通道 4 的佔空比
//compare:比較值
void TIM_SetTIM3Compare2(u32 compare)
{
TIM3->CCR2=compare;
}
在主函數部分,爲了方便自己調試角度,就把控制邏輯也就是佔空比的配置註釋掉了,用原子提供的usmart調試。這裏就得誇一下原子哥了,usmart真心好用,省時省力。代碼寫得很簡單,湊合着看吧。。。(要是需要修改後的usmart程序可以找我要)
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "usmart.h"
#include "duoji.h"
//自定義函數,供usmart_config.c調試調用
void led_set(u8 sta)
{
LED0=sta;
}
int main(void)
{
HAL_Init(); //初始化HAL庫
Stm32_Clock_Init(360,25,2,8); //設置時鐘,180Mhz
delay_init(180);
uart_init(115200);
LED_Init();
duoji_init(2000-1,900-1);//50Hz頻率
usmart_dev.init(90);//初始化usmart
while(1)
{
//TIM_SetTIM3Compare2(162);//居中
//TIM_SetTIM3Compare2(110);//左滿
//TIM_SetTIM3Compare2(200);//右滿
}
}
要注意的是,算出來的角度和實際測出來的角度是存在一定的誤差的,所以最好還是自己調角度。
這是調的幾個佔空比的具體波形,就是在串口裏面輸入TIM_SetTIM3Compare1()加具體數值就行了: