51单片机STC89C52RC——19.1 SG90舵机(伺服电机)

目的/效果

独立按键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%

控制通断时间比例,占空比。如下图

我在这里用定时计数器来控制占空比

cpp 复制代码
  /**
   * 函    数:定时器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 度。

cpp 复制代码
(180/(Max-Min))*(Compare-Min)

三,创建Keil项目

详细参考:51单片机STC89C52RC------创建Keil项目-CSDN博客

四,代码

完整代码参考《https://gitee.com/oopxiajun/STC89C52

main.c

cpp 复制代码
#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博客

相关推荐
LN花开富贵5 分钟前
单片机中为什么要使用5v转3.3v,不直接使用3.3V电压
笔记·单片机·嵌入式硬件·学习·物联网工程
Abaaba+25 分钟前
【STM32】VOFA+上位机 PID调参
stm32·单片机·嵌入式硬件
兔帮大人36 分钟前
点亮第一盏LED灯 3), LED灯GPIO引脚设置
单片机·嵌入式硬件
极客小张43 分钟前
基于OpenCV与MQTT的停车场车牌识别系统:结合SQLite和Flask的设计流程
arm开发·人工智能·单片机·opencv·物联网·flask·毕业设计
only_print1 小时前
linux网络编程——UDP编程
linux·网络·嵌入式硬件
LN花开富贵1 小时前
RZ7888电机驱动芯片
笔记·单片机·嵌入式硬件·学习·iot
人间一缕风十万八千梦1 小时前
51单片机+proteus+学习3(串口、矩阵按键)
学习·51单片机·proteus
人间一缕风十万八千梦2 小时前
51单片机+proteus+实验(I2C和蜂鸣器)
嵌入式硬件·51单片机·proteus
AhPhong2 小时前
获取STM32 MCU的唯一ID
stm32·单片机·嵌入式硬件
人间一缕风十万八千梦4 小时前
proteus+51单片机+实验(LCD1620、定时器)
嵌入式硬件·51单片机·proteus