【51单片机快速入门指南】3.2.1:PWM、呼吸灯与舵机

目录

  • 硬知识
    • PWM(脉冲宽度调制)
      • 基本原理
      • 脉宽调制分类
  • 上机实战
    • 呼吸灯
      • main.c
      • 中断服务函数
      • 修改TIM.c中的中断服务函数
      • 效果
        • 开发板电路分析
    • 舵机控制
      • 舵机控制方法
      • main.c
      • 中断服务函数
      • 修改中断服务函数
      • 舵机测试程序
        • main.c
      • 效果

普中51-单核-A2
STC89C52
Keil uVision V5.29.0.0
PK51 Prof.Developers Kit Version:9.60.0.0


硬知识

PWM(脉冲宽度调制)

摘自百度百科。

基本原理

       控制方式就是逆变电路开关器件的通断进行控制,使输出端得到一系列幅值相等但宽度不一致的脉冲,用这些脉冲来代替正弦波或所需要的波形。按一定的规则对各脉冲的宽度进行调制,既可改变逆变电路输出电压的大小,也可改变输出频率。
在这里插入图片描述

       (SPWM)例如,把正弦半波波形分成N等份,就可把正弦半波看成由N个彼此相连的脉冲所组成的波形。这些脉冲宽度相等,都等于 π/n ,但幅值不等,且脉冲顶部不是水平直线,而是曲线,各脉冲的幅值按正弦规律变化。如果把上述脉冲序列用同样数量的等幅而不等宽的矩形脉冲序列代替,使矩形脉冲的中点和相应正弦等分的中点重合,且使矩形脉冲和相应正弦部分面积(即冲量)相等,就得到一组脉冲序列,这就是PWM波形。可以看出,各脉冲宽度是按正弦规律变化的。根据冲量相等效果相同的原理,PWM波形和正弦半波是等效的。对于正弦的负半周,也可以用同样的方法得到PWM波形。
在这里插入图片描述
       (SPWM)在PWM波形中,各脉冲的幅值是相等的,要改变等效输出正弦波的幅值时,只要按同一比例系数改变各脉冲的宽度即可,因此在交-直-交变频器中,PWM逆变电路输出的脉冲电压就是直流侧电压的幅值。

脉宽调制分类

       从调制脉冲的极性看,PWM又可分为单极性双极性控制模式两种。
       产生单极性PWM模式的基本原理如图6.2所示。首先由同极性的三角波载波信号ut。与调制信号ur,比较 (图6.2中( a )),产生单极性的PWM脉冲 (图6.2中( b ));然后将单极性的PWM脉冲信号与图6.2中( c )所示的倒相信号UI相乘,从而得到正负半波对称的PWM脉冲信号Ud,如图6.2中(d)所示。
在这里插入图片描述
       双极性PWM控制模式采用的是正负交变的双极性三角载波ut与调制波ur,如图6.3所示,可通过ut与ur,的比较直接得到双极性的PWM脉冲,而不需要倒相电路。
在这里插入图片描述

上机实战

呼吸灯

       此处为最容易实现的三角波呼吸灯。
       定时器的介绍和配置源码见【51单片机快速入门指南】3.2:定时器/计数器

main.c

       配置定时器0为16位定时器模式,周期为100us,晶振频率为11.0592MHz,采用6T模式,故初始化时频率设为22118400L。

#include <REGX52.H>
#include "intrins.h"
#include "stdint.h"
#include "TIM.h"void main(void)
{	Timer_Init(TIMER_0, TIMER_MODE_1, GATE_DISABLE, CLK_Internal, 22118400L, 100, STC_TIM_Priority_Lowest);while(1){}
}

中断服务函数

       翻转P2.0以供测试。

void TIM0_Callback() interrupt 1 //定时器0中断函数
{TL0 = TL0_Save;TH0 = TH0_Save;				//定时器赋初值P2_0 = !P2_0;				//翻转P2.0以供测试
}

       如图逻辑分析仪测得P2.0脉宽为110.1us,误差为10.1%
在这里插入图片描述

修改TIM.c中的中断服务函数

       (为方便计算,下面还是以周期是100us计算)
       配置P2.0、P2.1以相反的方式输出,由于中断周期为100us,PWM的分辨率由TIM0_Counter控制,设为100,则PWM的周期为100us × 100 = 10 ms,即100Hz。
       设呼吸频率为1s,则一次呼吸经历1s/100us=100001s/100us=100001s/100us=10000次中断,其中5000次为上升段,5000次为下降段,则可修改出如下程序,并令P2.0、P2.1产生相反的波形。

void TIM0_Callback() interrupt 1 //定时器0中断函数
{static uint16_t TIM0_Counter = 0;static int16_t PWM = 0;static int8_t k = 1;TL0 = TL0_Save;TH0 = TH0_Save;				//定时器赋初值PWM += k;if(PWM >= 5000 || PWM <= 0)k *= -1;if(TIM0_Counter < PWM / 50){P2_0 = 0;P2_1 = 1;}else{P2_0 = 1;P2_1 = 0;}if(++TIM0_Counter == 100)	TIM0_Counter = 0;
}

效果

       下载程序:
在这里插入图片描述
       逻辑分析仪测得对应波形:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

开发板电路分析

       上图左LED DA1的电路分析:
       DA1由P2.1控制:
       当 P2.1 输出 0V0 V0V时,DAC1处自然为0V0V0V
       当 P2.1 输出 5V5 V5V时,由于运放的虚短特性,LM358的第2脚也为5V5V5V,又由于运放的虚断特性,流经第2脚的电流为000,故流经R28的电流 = 流经R29的电流,设LM358输出1脚电压为U1U1U1,LM358 2脚电压为U2=5VU2 = 5VU2=5V,则有(U1−U2)/R29=U2/R28(U1-U2)/R29 = U2/R28(U1U2)/R29=U2/R28,其中U2=5V,R28=R29=470RU2 = 5V,R28 = R29 = 470RU2=5VR28=R29=470R,解得U1=10VU1 = 10VU1=10V
在这里插入图片描述
       但由于LM358的供电为VCC仅为5V,则此时运放早已工作在非线性区,由手册查得LM358最大输出为Vcc−1.5VVcc - 1.5VVcc1.5V,开发板上Vcc=5VVcc = 5VVcc=5V,则其最大输出应为Vcc−1.5V=3.5VVcc - 1.5V = 3.5VVcc1.5V=3.5V
在这里插入图片描述
       实测为3.358V3.358V3.358V,误差4.064.064.06%。
在这里插入图片描述
       输出段,流经R30的电流 = 流经R33的电流 + 流经R32的电流,一般红色LED压降为1.8V1.8V1.8V,若运放输出端为3.5V3.5V3.5V,则有 (3.5V−VDAC1)/R30=VDAC1/R33+(VDAC1−1.8V)/R32(3.5V - V_{DAC1})/R30 = V_{DAC1}/R33 + (V_{DAC1}-1.8V)/R32(3.5VVDAC1)/R30=VDAC1/R33+(VDAC11.8V)/R32,解得VDAC1≈2.69VV_{DAC1} ≈ 2.69 VVDAC12.69V,则DA1上的电流为(VDAC1−1.8V)/R32≈2mA(V_{DAC1}-1.8V)/R32≈2mA(VDAC11.8V)/R322mA
在这里插入图片描述

舵机控制

舵机控制方法

摘自舵机详解 —— 弘毅
       舵机的伺服系统由可变宽度的脉冲来进行控制,控制线是用来传送脉冲的。脉冲的参数有最小值,最大值,和频率。一般而言,舵机的基准信号都是周期为20ms,宽度为1.5ms。这个基准信号定义的位置为中间位置。舵机有最大转动角度,中间位置的定义就是从这个位置到最大角度与最小角度的量完全一样。最重要的一点是,不同舵机的最大转动角度可能不相同,但是其中间位置的脉冲宽度是一定的,那就是1.5ms。如下图:
在这里插入图片描述
       角度是由来自控制线的持续的脉冲所产生。这种控制方法叫做脉冲调制。脉冲的长短决定舵机转动多大角度。例如:1.5毫秒脉冲会到转动到中间位置(对于180°舵机来说,就是90°位置)。当控制系统发出指令,让舵机移动到某一位置,并让他保持这个角度,这时外力的影响不会让他角度产生变化,但是这个是由上限的,上限就是他的最大扭力。除非控制系统不停的发出脉冲稳定舵机的角度,舵机的角度不会一直不变。

       当舵机接收到一个小于1.5ms的脉冲,输出轴会以中间位置为标准,逆时针旋转一定角度。接收到的脉冲大于1.5ms情况相反。不同品牌,甚至同一品牌的不同舵机,都会有不同的最大值和最小值。一般而言,最小脉冲为1ms,最大脉冲为2ms。如下图:
在这里插入图片描述

main.c

       定时器的介绍和配置源码见【51单片机快速入门指南】3.2:定时器/计数器

       设最终PWM的分辨率为200,则50Hz的PWM每次中断的周期为1s/50/200=100us1s/50/200=100us1s/50/200=100us

       配置定时器0为8位定时器自动重装载模式,周期为100us,晶振频率为11.0592MHz,采用6T模式,故初始化时频率设为22118400L。

#include <REGX52.H>
#include "intrins.h"
#include "stdint.h"
#include "TIM.h"void main(void)
{	Timer_Init(TIMER_0, TIMER_MODE_2, GATE_DISABLE, CLK_Internal, 22118400L, 100, STC_TIM_Priority_Lowest);while(1){}
}

中断服务函数

翻转P2.0以供测试:

void TIM0_Callback() interrupt 1 //定时器0中断函数
{P2_0 = !P2_0;
}

如图,脉宽为100.4us,误差0.4%
在这里插入图片描述

修改中断服务函数

PWM的分辨率为200,频率为50Hz,周期为1s/50=20ms1s/50=20ms1s/50=20ms,则1ms对应10次中断,2ms对应20次中断。

uint8_t Servo_PWM = 15;
void TIM0_Callback() interrupt 1 //定时器0中断函数
{static uint16_t TIM0_Counter = 0;if(TIM0_Counter < Servo_PWM)P2_0 = 1;elseP2_0 = 0;if(++TIM0_Counter == 200)	TIM0_Counter = 0;
}

如图1.5ms的脉宽实测如下,误差0.13%
在这里插入图片描述

舵机测试程序

main.c

设置P2.0每0.5s切换一次占空比。

#include <REGX52.H>
#include "intrins.h"
#include "stdint.h"
#include "TIM.h"void Delay500ms()		//@22.1184MHz
{unsigned char i, j, k;_nop_();i = 8;j = 1;k = 243;do{do{while (--k);} while (--j);} while (--i);
}extern uint8_t Servo_PWM;
void main(void)
{	Timer_Init(TIMER_0, TIMER_MODE_2, GATE_DISABLE, CLK_Internal, 22118400L, 100, STC_TIM_Priority_Lowest);while(1){Servo_PWM = 10;Delay500ms();Servo_PWM = 20;Delay500ms();}
}

效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/400479.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oracle常用查看表结构命令

转载自:http://blog.520591.com/1301 获取表&#xff1a; select table_name from user_tables; //当前用户的表 select table_name from all_tables; //所有用户的表 select table_name from dba_tables; //包括系统表 select table_name from dba_tables where owner’用户名…

Centos7 安装oracle数据库

参考的内容&#xff1a; http://docs.oracle.com/cd/E11882_01/install.112/e24325/toc.htm#CHDCBCJF http://www.cnblogs.com/yingsong/p/6031452.html http://www.cnblogs.com/yingsong/p/6031235.html 步骤主要是有&#xff1a; 1、安装依赖的 软件包 2、创建用户和目录&…

ABAP常见面试问题

ABAP常见面试问题 1. What is the typical structure of an ABAP program? 2. What are field symbols and field groups.? Have you used "component idx of structure" clause with field groups? 3. What should be the approach for writing a BDC program? …

车牌识别之车牌定位(方案总结)

尊敬原作者&#xff0c;转自:http://blog.csdn.net/hqw7286/article/details/5810353 一直研究车牌识别算法&#xff0c;主要关注车牌定位和字符识别。我想分享一下我对车牌定位的看法。 从根本上讲&#xff0c;车牌定位的算法分为三类&#xff0c;一类是基于边缘的&#xff0c…

Proteus仿真单片机:51单片机的仿真

目录新建工程调试在Proteus中编写程序导入Keil生成的Hex程序Windows 10 20H2 Proteus 8 Frofessional v8.9 SP2 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 新建工程 设置名称和路径 下一步 下一步 选择系列、控制器和编译器 双击MCU设置主频 …

CentOS多网卡重命名配置

CentOS多网卡重命名配置在CentOS7中我安装了3块网卡&#xff0c;但是名字是enoxxxxx的格式&#xff0c;让我这个有强迫症的***座很是不爽&#xff0c;以下是我配置网卡并且重命名为ethx的详细步骤前提工作要做好&#xff1a;1.查看网卡UUID# nmcli con show名称 UUID …

Linux 命令行输入

这几天刚刚接触到Linux&#xff0c;在windows上安装的VMWare虚拟机&#xff0c;Centos7。安装什么都是贾爷和办公室的同事帮忙搞定的。 在虚拟机界面&#xff0c;按快捷键CtrlAltEnter&#xff0c;可以全屏显示Linux界面&#xff0c;再按一次则退出全屏。 如何在Linux里输入命令…

【51单片机快速入门指南】2.5:并行I/O扩展与8255A

目录硬知识单片机I/O扩展基础知识I/O接口电路的功能速度协调输出数据锁存数据总线隔离数据转换增强驱动能力单片机并行扩展总线并行扩展总线的组成80C51单片机并行扩展总线I/O编址技术可编程并行接口芯片82558255硬件逻辑结构口电路总线接口电路A组和B组控制电路中断控制电路82…

24小时制时间格式和12小时制时间格式

yyyy-MM-dd HH:mm:ss -------24 yyyy-MM-dd hh:mm:ss -------12转载于:https://www.cnblogs.com/hbhzz/p/3165370.html

win 下 apache2.4 +tomcat7 集群

为什么80%的码农都做不了架构师&#xff1f;>>> 反正每次来做一个不熟悉的东西&#xff0c;就是各种的search ,前一次去做过一个apache的东西&#xff0c;各种蛋疼&#xff0c;各种不能用。好多的东西也是比较旧了的咯。 这次结合前辈的各种东借西拿&#xff0c;总…

Proteus常见电平状态

目录高态其他低态Windows 10 20H2 Proteus 8 Frofessional v8.9 SP2 摘自proteus常见状态 —— 山科董国正 高态 PHI 电源高态&#xff1a;电源高逻辑SHl 强电高态&#xff1a;主动输出高逻辑WHI 弱电高态&#xff1a;被动输出高逻辑 其他 FLT 悬空态&#xff1a;悬空输出…

简单理解正则表达式

我理解的正则表达式&#xff1a; 正则表达式就是用于字符&#xff08;串&#xff09;匹配时的一种描述字符串的表达式。 关于正则表达式&#xff1a; 预定义的字符类 用\d可以匹配一个数字&#xff1b;用\D表示非数字字符[^\d]用\w可以匹配一个字母或数字&#xff1b;用\W表示非…

最后一行数据

最后一行数据 设计要点&#xff1a;导入外部数据、SQL、数据源、汇总行 秀秀&#xff1a;既然你说第一行的数据那么重要&#xff0c;那俺觉得最后一行数据也很重要。 阿金&#xff1a;为什么&#xff1f; 秀秀&#xff1a;因为最后一行数据往往是汇总行&#xff0c;一般引用数据…

Proteus仿真单片机:PIC18单片机的仿真

目录新建工程ProteusMPLAB X IDE调试Windows 10 20H2 Proteus 8 Frofessional v8.9 SP2 MPLAB X IDE v5.45 新建工程 Proteus 下一步 下一步 选择芯片、编译器 搭建实验电路 MPLAB X IDE MPLAB X IDE 新建工程 选择独有项目 选择芯片 选择编译器 配置工程名称、路…

Realm学习总结

参考博客: http://www.jianshu.com/p/096bec929f2a http://www.cnblogs.com/ilyy/p/5648051.html 参考的博客介绍很详细,我就不写了..写了一个简单的学习的demo. GitHub地址: https://github.com/PengSiSi/RealmDemo 代码如下: // // ViewController.m // RealmDemo // // C…

with(nolock)的用法

with(nolock)的介绍 大家在写查询时,为了性能,往往会在表后面加一个nolock,或者是with(nolock),其目的就是查询是不锁定表,从而达到提高查询速度的目的。 当同一时间有多个用户访问同一资源,并发用户中如果有用户对资源做了修改&#xff0c;此时就会对其它用户产生某些不利的影…

干支表

原文地址&#xff1a;http://114.xixik.com/tiangandizhi/ 天干 12345678910甲乙丙丁戊己庚辛壬癸地支 123456789101112子丑寅卯辰巳午未申酉戌亥六十年甲子&#xff08;干支表&#xff09; 12345678910甲子乙丑丙寅丁卯戊辰己巳庚午辛未壬申癸酉11121314151617181920甲戌乙亥丙…

【PIC18单片机学习笔记】一、程序的烧录

目录编程器烧录软件烧录准备程序main.cpic18.h烧录效果Windows 10 20H2 PICkit 3 v3.10 MPLAB X IDE v5.45 PIC18F46J50 编程器 所用编程器为PICkit 3.5 按图示连接好编程器和开发板 烧录软件 所用烧录软件为PICkit 3 v3.10 初次使用需要给编程器更新固件&#xff0c…

ASIHttpRequest:创建队列、下载请求、断点续传、解压缩

ps&#xff1a;本文转载自网络&#xff1a;http://ryan.easymorse.com/?p12 感谢作者 工程完整代码下载地址&#xff1a;RequestTestDownload1 可完成&#xff1a; 下载指定链接的zip压缩文件存放在Documents目录下支持断点续传显示下载进度解压到指定目录—————————…

UIControl-IOS开发

UIKit提供了一组控件&#xff1a;UISwitch开关、UIButtonbutton、UISegmentedControl分段控件、UISlider滑块、UITextField文本字段控件、 UIPageControl分页控件。 控件是对UIView派生类的有用增强及补充&#xff0c;并能够直接附着于导航栏、表格单元&#xff0c;甚至更大的对…