1.接線
SG90帶有一個3P的接頭
根據(jù)顏色分為
- 黃線(信號線)
- 紅線(電源線)
- 棕色 (地線)
舵機的工作電壓在4.8V-6V,接在STM32系統(tǒng)板上驅(qū)動不了,所以需要接電源模塊單獨的5V供電,我使用的是如圖所示的電源模塊
注:
如果STM32系統(tǒng)板供電和舵機供電不為同一模塊,則需要共地,否則控制不成功!??!
2.舵機的控制
舵機的控制需要一個20ms左右的時基脈沖,該脈沖的高電平部分0.5ms到2.5ms控制舵機轉(zhuǎn)動角度0°-180°呈線性變化。
控制原理:舵機內(nèi)部有一個基準電路,產(chǎn)生周期20ms,寬度1.5ms的基準信號,通過比較器,將外加信號與基準信號相比較,判斷出方向和大小,從而產(chǎn)生電機的轉(zhuǎn)動信號。
知道原理之后,讓我們來編寫驅(qū)動代碼,首先需要一個總周期為20ms的時基脈沖,這里采用TIM3CH2(定時器3通道2)對應的GPIOB5作為輸出控制信號
首先是PWM的基礎(chǔ)配置
void TIM3_PWM_Init(u16 arr,u16 psc)//GPIOB5
{
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);//RCC配置GPIO,復用時鐘 ->APB2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//TIM3->APB1
//GPIO初始化
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//GPIOB5
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;//復用推挽輸出
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//設(shè)置部分重映射
//初始化TIM3
TIM_TimeBaseStruct.TIM_Period=arr;//定時器周期
TIM_TimeBaseStruct.TIM_Prescaler=psc;//預分頻系數(shù)定時器周期
TIM_TimeBaseStruct.TIM_CounterMode=TIM_CounterMode_Up;//向上計數(shù)
TIM_TimeBaseStruct.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStruct);
//設(shè)置比較通道CH2
/*
PWM模式2- 在向上計數(shù)時,一旦TIMx_CNT<TIMx_CCR1時通道1為無效電平,否則為
有效電平;在向下計數(shù)時,一旦TIMx_CNT>TIMx_CCR1時通道1為有效電平,否則為無效電平。
PWM模式1- 在向上計數(shù)時,一旦TIMx_CNT<TIMx_CCR1時通道1為有效電平,否則為
無效電平;在向下計數(shù)時,一旦TIMx_CNT>TIMx_CCR1時通道1為無效電平,否則為有效電平。
*/
//PWM1極性高 向上記數(shù) CNT小于CCR為高電平
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1; //PWM輸出模式選擇
TIM_OCInitStruct.TIM_Pulse=0; //通道比較值設(shè)定,可以自己設(shè)定
TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High; //極性選擇 (有效電平為高/低)
TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;//輸出狀態(tài)使能
TIM_OC2Init(TIM3,&TIM_OCInitStruct); //通道CH2 GPIOB5
//使能預裝載寄存器
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //通道CH2 GPIOB5
//定時器使能
TIM_Cmd(TIM3,ENABLE);
}
然后根據(jù)需要的周期設(shè)置總記數(shù)值以及分頻系數(shù)
void Sg90_Init(void){
//舵機控制總周期要求為20ms
//通過改變脈寬0.5ms-2.5ms代表0-180°
TIM3_PWM_Init(2000-1,720-1);
//2000*720/72M = 20000us = 20ms
}
然后通過改變比較值來改變舵機轉(zhuǎn)動的角度
void SetAngle(int angle){
//angle 范圍為0-180
if(angle >= 0 || angle <= 180){
//總記數(shù)值為2000 比較值50-250代表0°-180°
TIM_SetCompare2(TIM3,50+(200*angle/180));//修改定時器3通道2的比較值
}
}
附帶一個測試函數(shù)
void Sg90_Test(void){//運行一次角度+10° 大于180°時重新從0開始
static int n = 0;
n += 10;
SetAngle(n%180);
}
main.c
sys.h為官方庫函數(shù)文件
#include "sys.h"
#include "delay.h"
#include "led.h"
#include "sg90.h"
int main()
{
delay_init();
LedInit();
Sg90_Init();
while(1)
{
delay_ms(500);
LED1 = ~LED1;
Sg90_Test();
}
}
這里使用了板載的LED燈,監(jiān)測運行是否正常。文章來源:http://www.zghlxwxcb.cn/news/detail-776427.html
sg90.c
#include "sg90.h"
/*********
SG90控制
GPIOB5
*********/
void Sg90_Init(void){
//舵機控制總周期要求為20ms
//通過改變脈寬0.5ms-2.5ms代表0-180°
TIM3_PWM_Init(1999,719);
//2000*720/72M = 20000us = 20ms
}
void TIM3_PWM_Init(u16 arr,u16 psc)//GPIOB5
{
GPIO_InitTypeDef GPIO_InitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);//RCC配置GPIO,復用時鐘 ->APB2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//TIM3->APB1
//GPIO初始化
GPIO_InitStruct.GPIO_Pin=GPIO_Pin_5;//GPIOB5
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;//復用推挽輸出
GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStruct);
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//設(shè)置部分重映射
//初始化TIM3
TIM_TimeBaseStruct.TIM_Period=arr;//定時器周期
TIM_TimeBaseStruct.TIM_Prescaler=psc;//預分頻系數(shù)定時器周期
TIM_TimeBaseStruct.TIM_CounterMode=TIM_CounterMode_Up;//向上計數(shù)
TIM_TimeBaseStruct.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStruct);
//設(shè)置比較通道CH2
/*
PWM模式2- 在向上計數(shù)時,一旦TIMx_CNT<TIMx_CCR1時通道1為無效電平,否則為
有效電平;在向下計數(shù)時,一旦TIMx_CNT>TIMx_CCR1時通道1為有效電平,否則為無效電平。
PWM模式1- 在向上計數(shù)時,一旦TIMx_CNT<TIMx_CCR1時通道1為有效電平,否則為
無效電平;在向下計數(shù)時,一旦TIMx_CNT>TIMx_CCR1時通道1為無效電平,否則為有效電平。
*/
//PWM1極性高 向上記數(shù) CNT小于CCR為高電平
TIM_OCInitStruct.TIM_OCMode=TIM_OCMode_PWM1; //PWM輸出模式選擇
TIM_OCInitStruct.TIM_Pulse=0; //通道比較值設(shè)定,可以自己設(shè)定
TIM_OCInitStruct.TIM_OCPolarity=TIM_OCPolarity_High; //極性選擇 (有效電平為高/低)
TIM_OCInitStruct.TIM_OutputState=TIM_OutputState_Enable;//輸出狀態(tài)使能
TIM_OC2Init(TIM3,&TIM_OCInitStruct); //通道CH2 GPIOB5
//使能預裝載寄存器
TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); //通道CH2 GPIOB5
//定時器使能
TIM_Cmd(TIM3,ENABLE);
}
void SetAngle(int angle){
//angle 范圍為0-180
if(angle >= 0 || angle <= 180){
//總記數(shù)值為2000 比較值50-250代表0°-180°
TIM_SetCompare2(TIM3,50+(200*angle/180));//修改定時器3通道2的比較值
}
}
void Sg90_Test(void){//運行一次角度+10° 大于180°時重新從0開始
static int n = 0;
n += 10;
SetAngle(n%180);
}
sg90.h
#ifndef __SG90_H_
#define __SG90_H_
#include "sys.h"
void Sg90_Init(void);
void SetAngle(int angle);
void Sg90_Test(void);
void TIM3_PWM_Init(u16 arr,u16 psc);
#endif //__SG90_H_
led.c
#include "led.h"
void LedInit(void)
{
//庫函數(shù)版本
GPIO_InitTypeDef GPIO_InitStructor;
//開啟硬件時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
//配置IO 推挽輸出,輸出速度
GPIO_InitStructor.GPIO_Pin=GPIO_Pin_13;
GPIO_InitStructor.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructor.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructor);
}
led.h
#ifndef __LED_H_
#define __LED_H_
#include "sys.h"
#define LED1 PCout(13)
void LedInit(void);
#endif //__LED_H_
附帶項目總體文件
點擊下載項目文件
鏈接:https://pan.baidu.com/s/1SlVU4H5foOcHIOLDQ_t5NQ?pwd=6666
提取碼:6666文章來源地址http://www.zghlxwxcb.cn/news/detail-776427.html
到了這里,關(guān)于SG90舵機的使用--STM32F103C8T6的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!