51单片机控制SG90舵机、MG90S舵机

2023-11-09

        舵机的控制信号为周期是20ms 的脉宽调制(PWM)信号,其中脉冲宽度从0.5ms-2.5ms,相对应舵盘的位置为0—180度,呈线性变化。也就是说,给它提供一定的脉宽,它的输出轴就会保持在一个相对应的角度上,无论外界转矩怎样改变,直到给它提供一个另外宽度的脉冲信号,它才会改变输出角度到新的对应的位置上。舵机内部有一个基准电路,产生周期20ms,宽度1.5ms的基准信号,有一个比较器,将外加信号与基准信号相比较,判断出方向和大小,从而产生电机的转动信号。其舵机输出转角与信号脉冲宽度的关系见下图。

       

       最近在使用STC89C52单片机控制SG90舵机和MG90S舵机的过程中,为了保证脉冲信号宽度的精准性,采用了定时器中断来调节占空比产生PWM信号,也就是在定时器中断函数中去调节高低电平持续的时间,博主在此处选择定时器0中断来产生PWM信号,每0.1ms中断一次,在实际编写代码的过程中,由于定时器0中断的中断频率过高,导致主函数内其他功能代码的运行出现了较大的偏差,例如DS18B20温度传感器要求每次读取温度都要等待750ms以上,但是定时器0中断在每次读取温度数据的时候进入中断就会导致所读取的温度值不准确,因而需要在每次控制完舵机转动指定角度后就关闭定时器0。

        在实际编写代码测试发现,如果是在向舵机发送完20ms的pwm脉冲之后就立马关闭定时器的话,则会导致舵机无法转动指定角度,反之如果不关闭定时器的话,pwm脉冲信号就会不断的反复发送,舵机就能转动到指定角度,针对这个现象,博主不断编写代码测试发现,在持续发送pwm脉冲信号一段时间后再关闭定时器,仍能达到控制舵机转动指定角度,且能保证主函数内其他代码块的正常运行,直到下一次通过发送控制指令到单片机时再开启定时器来产生pwm信号,反复如此,经测试,在7个脉冲周期(每个周期20ms)后关闭定时器(共140ms)可保证舵机的正常运行,且不影响主函数其他代码块运行,具体代码如下:

#include <reg52.h>

#define uint unsigned int
#define uchar unsigned char

unsigned char SEH_count = 5;//舵机转动角度,5-0度,10-45度,15-90度
unsigned char count = 0;//脉宽长度计数

unsigned char T0RH = 0xff;  //T0重载的高字节
unsigned char T0RL = 0xa4;  //T0Ö载的低字节
unsigned char RxdByte = 0;  //串口接收到的数据
sbit SEH_PWM = P1^0; //舵机PWM脉冲信号数据口
uchar UartDataIsResolve = 0;//串口数据是否已处理标志位,0-未处理,1-已处理
uchar timer_count = 0;//舵机20ms脉冲发送次数
uchar flag0 = 0; //舵机转动位置标志位,0-90度,1-0度

//串口初始化
void UARTInit()
{
    SM0 = 0;
    SM1 = 1;	//串口工作方式1
    REN = 1;	//允许串口接收
    EA = 1;		//开总中断
    ES = 1;		//开串口中断
    TMOD |= 0x20;//定时器1 8位自动重装模式
    TH1 = 0xfd;
    TL1 = 0xfd;	//9600波特率
    TR1 = 1;	//开定时器1
    ET1 = 0;	//禁止定时器1中断
}
/*定时器0初始化*/
void Timer0_Init()
{
    TMOD |= 0x01;   //定时器0工作方式模式1
    TH0 = T0RH;     //初值装填
    TL0 = T0RL;
    ET0 = 1;        //开定时器0中断
    TR0 = 1;        //开定时器0
}

void PWM(unsigned char x)
{
    SEH_count = x;
}

void main(){
    Timer0_Init();//初始化定时器0,并将舵机复位至0°位置
    UARTInit();
    while(1){
			switch(RxdByte){
				case '0':{
					if(!UartDataIsResolve){//通过串口发送字符'0'控制舵机转动到0°位置或90°位置,确保每次串口中断数据只处理一次
						UartDataIsResolve = 1;
						if(flag0 == 1){
							flag0 = 0;
							PWM(5);
						}else{
							flag0 = 1;
							PWM(15);
						}
						TR0 = 1;//每次控制舵机转动时再开定时器。
					}

				};
				break;
			}
    }

}
/* 串口中断函数*/
void InterruptUART() interrupt 4
{
    EA = 0;
    if(RI)  
    {
        RI = 0;  
        RxdByte = SBUF;  
        UartDataIsResolve = 0;//串口数据处理标志
    }
    EA = 1;
}


/*定时器0中断函数,0.1ms中断一次*/
void InterruptTimer0() interrupt 1
{
    TH0 = T0RH;  //重新装填重载值
    TL0 = T0RL;
    TR0 = 0;//关闭定时器
    if(count <= SEH_count)
		{
				SEH_PWM = 1;
		}
		else
		{
				SEH_PWM = 0;
		}
		TR0 = 1;//开启定时器
		count++;
		if(count >= 200){
				count = 0;
				timer_count++;
		}
		//7个脉冲周期后关闭定时器
		if(timer_count == 7){
			timer_count = 0;
			TR0 = 0;
		}
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

51单片机控制SG90舵机、MG90S舵机 的相关文章

随机推荐

  • CPU 风扇清理灰尘加油全过程图解

    主机电源风扇由于使用时间长 风扇轴承的润滑油耗尽 导致风扇转速下降或是不转 引起电源热量无法有效排除而造成电脑经常死机 解决办法有几种 现图解说明最简单省钱的办法如下 1 把电源从主机上拆下 如下图再取出电源背面的4个固定镙丝 2008 5
  • EasyAR4.0使用说明(Unity3D)(七)----稀疏空间地图

    稀疏空间地图的对应用环境的要求和平面图像识别可以比照理解 周围环境需要足够丰富 不能有大片的单色区域 透明区域 此外 光照 角度都会对建立地图和定位产生影响 官方给出了建立地图和定位地图的建议 https help easyar cn Ea
  • rgss加密文件解包器_Galgame汉化中的逆向 (一):文本加密(压缩)与解密

    本文为看雪论坛优秀文章 看雪论坛作者ID devseed 0x0 前言 看到关于游戏汉化相关的逆向教程挺少的 作为某汉化组的成员也帮过别的汉化组 于是就想把我见到的几个典型的例子整理分析一下 还是挺有意思的 此教程和我在贴吧和隔壁发的一样
  • 时序预测

    时序预测 Python实现NARX DNN空气质量预测 目录 时序预测 Python实现NARX DNN空气质量预测 效果一览 基本介绍 研究内容 程序设计 参考资料 效果一览 基本介绍 时序预测 Python实现NARX DNN空气质量预
  • 如何使a==1&&a==2&&a==3表达式成立?

    前几天闲着无聊 玩手机无意中发现一个题 觉得挺有意思的 就顺手记录一下 题目 a 1 a 2 a 3 true 思考 我思考了一会 这让一个值既是1又是2又是3的 不可能吧 这肯定是一个伪命题 但突然我灵光一现 对象属性不是可以拦截吗 我能
  • Flex 构建路径

    然libs文件夹是构建路径的一部分 但它并不总是SWC的理想存放位置 当多个项目同时使用相同的SWC时 就不能都存放在libs文件夹中 在这种情况下 SWC可以保持在中心位置 众所周知 SWC路径可以被添加到构建路径中 虽然这意味着需要建立
  • 问题 G: 用递归的方法求值

    题目描述 求1 2 3 4 5 n的值 输入格式 一个n n不大于10000 输出格式 输出1到n的累加和 输入样例 复制 2 输出样例 复制 3 这道题比较简单 边界是n 0 核心代码为 if n 0 return 0 else retu
  • C++ template 模板的模板参数(5.4节)

    有时 让模板参数本身成为模板是很有用的 我们将继续以stack类模板作为例子 来说明模板的模板参数的用途 在Stack的例子中 如果要使用一个和缺省值不同的内部容器 程序员必须两次指定元素类型 也就是说 为了指定内部容器的类型 你需要同时传
  • java实现文件的上传和下载

    文件的上传 upload 文件上传 客户端通过表单的文件域file 把客户端的文件 上传保存到服务器的硬盘上 页面 首先对上传的表单有以下要求 必须有文件域 input type file 表单提交方式 method post 表单的 en
  • 【剑指Offer】35.复杂链表的复制(JS实现)

    题目描述 请实现 copyRandomList 函数 复制一个复杂链表 在复杂链表中 每个节点除了有一个 next 指针指向下一个节点 还有一个 random 指针指向链表中的任意节点或者 null 示例1 输入 head 7 null 1
  • 图灵机模拟程序功能设计

    图灵机由无限长的纸带 读写头 状态寄存器 控制规则等四部分组成 纸带上的符号可以是 0 1 空格 要利用图灵机求解一个问题 需要自己设计图灵机 程序 即定义一些状态 其中包括初始状态和结束状态 设计给出控制规则 并进行图灵机初始化 设定初始
  • chrome/Edge搜索技巧

    1 剔除干扰项搜索 搜索内容 不想要的关键词 排除干扰项 2 特定搜索 给关键词加引号 关键词 只搜索引号里面的字 3 指定网站内搜索 site 域名 关键词 4 指定格式搜索 filetype 文件格式 关键词 可以制定pdf doc p
  • series not exists. Legend data should be same with series name or data name.

    normal删除
  • php+vscode+xdebug搭建php调试环境

    php vscode xdebug搭建php调试环境 开发环境 windows 10 php 8 0 23 xdebug 3 1 6 配置xdebug 查看php版本信息 cmd exe php version 可看到 我的版本信息为8 0
  • 阿里云maven 仓库地址配置

    参考 https help aliyun com document detail 102512 html spm a2c40 aliyun maven repo 0 0 36183054erKD4V 配置指南 maven配置指南 打开mav
  • 深度学习之生成对抗网络(7)WGAN原理

    深度学习之生成对抗网络 7 WGAN原理 1 JS散度的缺陷 2 EM距离 3 WGAN GP WGAN算法从理论层面分析了GAN训练不稳定的原因 并提出了有效的解决方法 那么是什么原因导致了GAN训练如此不稳定呢 WGAN提出是因为JS散
  • Best Cow Fences (前缀和 + 二分)

    描述 Farmer John s farm consists of a long row of N 1 lt N lt 100 000 fields Each field contains a certain number of cows
  • java Timer(定时调用、实现固定时间执行)

    最近需要用到定时调用的功能 可以通过java的Timer类来进行定时调用 下面是有关Timer的一些相关知识 其实就Timer来讲就是一个调度器 而TimerTask呢只是一个实现了run方法的一个类 而具体的TimerTask需要由你自己
  • caffe_master windows下的安装编译

    一 安装配置 caffe master包 https pan baidu com s 1kI2TcOX3Ak kNGGzsTYRBA 其它有需要请留言2602721630 qq com 本文在windows下使用visual studio2
  • 51单片机控制SG90舵机、MG90S舵机

    舵机的控制信号为周期是20ms 的脉宽调制 PWM 信号 其中脉冲宽度从0 5ms 2 5ms 相对应舵盘的位置为0 180度 呈线性变化 也就是说 给它提供一定的脉宽 它的输出轴就会保持在一个相对应的角度上 无论外界转矩怎样改变 直到给它