舵机的控制信号为周期是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 charunsigned 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; //串口工作方式1REN = 1;  //允许串口接收EA = 1;        //开总中断ES = 1;      //开串口中断TMOD |= 0x20;//定时器1 8位自动重装模式TH1 = 0xfd;TL1 = 0xfd;    //9600波特率TR1 = 1;  //开定时器1ET1 = 0;    //禁止定时器1中断
}
/*定时器0初始化*/
void Timer0_Init()
{TMOD |= 0x01;   //定时器0工作方式模式1TH0 = 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;}
}

51单片机控制SG90舵机、MG90S舵机相关推荐

  1. 51单片机控制SG90 9g舵机

    目录 1.工具准备 2.接线 3.写代码并生成hex文件 4.用烧录软件烧录  1.工具准备 一个51开发板(51开发板型号为:51mini  开发板芯片型号:STC98C52) 一个舵机(舵机型号为 ...

  2. 51单片机控制sg90舵机

    1.PWM PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进行调制,等效出所需要的波形(包含形状以及幅值),对模拟信号电平进行数字编码,也就 ...

  3. 51单片机控制的数字温度计 PROTEUS 和51单片机教程

    51单片机控制的数字温度计 总览部分 MCU部分 显示部分 开仿真以后实时显示温度 因为这个程序比较简单,我就直接上代码了,有不明白的请看我以前的文章,谢谢哦! 参考代码如下: #include &q ...

  4. 51单片机控制步进电机-电路连接

    51单片机控制步进电机-电路连接 概要:本案例讲解的内容是51单片机控制步进电机硬件连接部分.后续会分别讲解单片机程序,S曲线加减速方法,上位机等相关内容 硬件清单: 1.51单片机控制板一个 2.二 ...

  5. 51单片机控制二相四线步进电机

    步进电机按定子上绕组来分,有二相.三相和五相等系列.最受欢迎的是两相混合式步进电机,约占97%以上的市场份额,其原因是性价比高,配上细分驱动器后效果良好.该种电机的基本步距角为1.8°/步,配上半步驱 ...

  6. 51单片机控制TB6600驱动器驱动42步进电机

    51单片机控制TB6600驱动器驱动42步进电机 第一次 功能实现目标 硬件简介 硬件连接 程序代码 第一次 以前总是看别人写的博客,通过别人的博客解决了我很多问题,从中也学到了各种知识,虽然不是很系 ...

  7. 51单片机控制LCD1602模块

    51单片机控制LCD1602模块 视频播放:LCD1602视频 (1)LCD1602概述 先来看看LCD1602什么意思?Liquid Crystal Display(LCD)表示液晶显示,1602 ...

  8. 51单片机控制DHT11温湿度传感器,并使用OLED屏幕显示

    目录 前言 一.MCU主控选型 二.DHT11温湿度传感器 1.模块介绍 2.软件实现 DHT11.c DHT11.h 三.OLED显示屏 1.模块介绍 2.软件实现 OLED.c OLED.h OL ...

  9. 遥控51单片机控制42步进电机(TB6600驱动)控制方向、速度

    遥控51单片机控制步进电机控制方向.速度 控制开发板自带步进电机 遥控控制 控制42步进电机 大二在做srtp时做到了这部分内容,感觉C51控制起来挺简单的,之后有做关于MSP430的魂斗罗游戏和st ...

最新文章

  1. class 与 原型链 解析
  2. S - 母牛的故事(递推)
  3. 分页请求json数据_pyspider抓取虎嗅网文章数据
  4. CUDA:根据本地电脑的NVIDIA显卡驱动版本去正确匹配待安装的CUDA版本之详细攻略
  5. MVP+WCF+三层结构搭建项目框架(上)
  6. 如何将自己的代码放到github上
  7. python2.7 end=号报错_python2 post 上传压缩文件编码报错
  8. php实现身份证号码获取归属地地址的实列教程,含完整全国地区归属数据!
  9. Delphi TStream 详细介绍
  10. 智慧讲台接收画板协议规划
  11. python数值类型和序列类型_Python基础(一):数值类型,序列类型
  12. 【Python】32 个常用入门 Python 实现
  13. 经典面试题 之 JVM调优
  14. java压_JAVA背压
  15. 一周XX思考(第12期)
  16. linux下迅雷的替代
  17. 获取店铺商品详情和订单详情
  18. Mybatis复杂映射映射文件
  19. BatchNorm和LayerNorm的区别
  20. ALSA子系统(一)------Frames Periods

热门文章

  1. so 对XXX未定义的引用
  2. IntelliJ IDEA出现Tomcat服务器启动不了解决办法
  3. foxmail和outlook2007邮件如何互相导入?
  4. ubuntu16.04安装网易云音乐方法出现问题及解决方法(桌面图标打不开、不能输入中文等问题)
  5. IoT 设备数据实时接入与分析实现方案
  6. Linux系统编程 复习笔记
  7. MSM8974 上DeviceTree
  8. 小傻蛋的妹妹跟随小甲鱼学习Python的第十七节017
  9. 安卓玩机搞机技巧综合资源-----查看手机硬件全部参数 隐藏参数 多个软件【十七】
  10. android 方法技巧