目的/效果
独立按键K1,K2 实现加舵机减角度增减,LCD1602显示舵机转角度数(上电默认90度)
一,STC单片机模块
二,SG90舵机
2.1 简介
舵机只是我们通俗的叫法,它的本质是一个伺服电机,也可以叫做位置(角度)伺服驱动器。一般被应用在那些需要控制角度变化的系统中,可以方便的实现转动任意的角度,实现控制角度的变化。
应用场景航模、智能小车的转向
航模:在很多的航模中,sg90舵机都被用于两翼的位置控制,从而实现航模的转向,倾斜之类的。因为航模本身的要求,需要尽量的控制航模的自重,而sg90舵机的重量本身就很轻,扭矩也大,所以能很好的满足要求。
智能小车的转向:因为sg90舵机的精准角度控制,所以在很多的智能小车类中被用作转向控制。
2.2 舵机的工作原理
SG90舵机模块内有控制电路,控制信号通过信号线输入到内部的控制电路中,调制芯片将输入的信号进行调制,获得直流偏置电压。然后再由内部的基准电路产生周期为20ms,宽度为1.5ms的基准信号,将直流偏置电压和电位器电压进行比较,从而获得输出的电压差。由电压差控制舵机的转动,这个电压差的正负控制舵机正反转。
舵机的控制需要MCU产生一个周期为20ms的脉冲信号,以0.5ms到2.5ms的高电平来控制舵机转动的角度。
以180度角度伺服为例,那么对应的控制关系是这样的:
0.5ms--------------0度;
1.0ms------------45度;
1.5ms------------90度;
2.0ms-----------135度;
2.5ms-----------180度;
占空比: 一个脉冲周期内,高电平的时间与整个周期时间的比例
单位: % (0%-100%)
表示方式:20%
控制通断时间比例,占空比。如下图
我在这里用定时计数器来控制占空比
/**
* 函 数:定时器0初始化,100微秒 @12.000MHz
* 参 数:无
* 返 回 值:无
*/
void Timer0_Init(void)
{
TMOD |= 0x01; //设置定时器模式
TL0 = 0xB0; //设置定时初始值
TH0 = 0xFF; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1; //允许时钟1中断
EA=1; //打开总中断
}
有关定时器和系统中断请参考
《51单片机STC89C52RC——6.1 中断系统_stc89c52rc的中断系统-CSDN博客》
《51单片机STC89C52RC——6.2 定时器_stc89c52rc定时器-CSDN博客》
《51单片机STC89C52RC——6.3 定时器/计数器 实现计时功能》
注意:为了真实项目控制得更精准,我们可以将定时器的中断设置为1us一次,极值宽度设置为500us-2500us,把每次按键加减值控制的更细。
2.3 接线方法
红-------------------------VCC
棕色----------------------GND
橙色----------------------信号线 ,我这里选用P20针脚
2.4 转角度数计算
舵机的角度控制是通过改变舵机脉冲宽度来实现的。舵机脉冲宽度与舵机角度之间的关系如下:
角度 = 180/(最大脉冲宽度 - 最小脉冲宽度)*(脉冲宽度 - 最小脉冲宽度)
脉冲宽度为 500 微秒时,舵机角度为 0 度。
脉冲宽度为 1500 微秒时,舵机角度为 90 度。
脉冲宽度为 2500 微秒时,舵机角度为 180 度。
(180/(Max-Min))*(Compare-Min)
三,创建Keil项目
详细参考:51单片机STC89C52RC——创建Keil项目-CSDN博客
四,代码
完整代码参考《https://gitee.com/oopxiajun/STC89C52》
main.c
#include <REGX52.H>
#include "Timer0.h"
#include "key.h"
#include "LCD1602.h"
#include "Delay.h"
int Min=5,Max=25;//定义极值时长
unsigned char Counter,//计数器
KeyNum,//按键值
Compare=15;//占空比 7.5%
/**
* 函 数:主函数
* 参 数:无
* 返 回 值:无
*/
void main()
{
Timer0_Init(); //初始化定时器
LCD_Init();
while(1)
{
LCD_ShowNum(1,1,(180/(Max-Min))*(Compare-Min),3);
KeyNum=GetKey();
if(KeyNum==1)
{
Compare-=1;
}
else if(KeyNum==2)
{
Compare+=1;
}
if(Compare<Min)Compare=Min;
if(Compare>Max)Compare=Max;
}
}
/**
* 函 数:定时器0中断函数
* 参 数:无
* 返 回 值:无
*/
void Timer0_Routine() interrupt 1
{
TL0 = 0xB0; //设置定时初始值 每0.1毫秒中断一次
TH0 = 0xFF; //设置定时初始值
Counter++;
Counter%=200; //20ms的脉冲周期
if(Counter>=Compare)
{
P2_0=0;//电机断电
}
else {
P2_0=1;//电机通电
}
}
五,代码编译、下载到51单片机
代码编译请参考
《51单片机STC89C52RC——代码编译-CSDN博客》
代码下载请参考
《51单片机STC89C52RC——STCAI-ISP代码下载-CSDN博客》