单片机PWM输出原理与实践

2023-05-16

一、什么是PWM?

  PWM(Pulse Width Modulation)脉冲宽度调制,它是通过对一系列脉冲的宽度进行调制,等效出所需要的波形(包含形状以及幅值),对模拟信号电平进行数字编码。   
查看源图像
  通俗的说,就是一个周期内,控制高电平多长时间,低电平多长时间(高电平:5/3.3V,低电平:0V)。通过调节高低电平时间的变化来调节信号、能量等的变化。
图为周期4毫秒的PWM波形
  图为周期4毫秒的PWM波形、占空比为0.25

  • 两个重要的概念,频率、占空比

  频率:是指每秒钟信号从高电平到低电平再回到高电平的次数,为一个PWM波周期的倒数。上图中频率=1/(0.003+0.001)=250 HZ
  占空比:是指高电平持续时间比一个周期持续的时间。上图中占空比=1/(1+3)=25%,所以可以通过控制占空比,来控制输出的等效电压。
  所以对于方波的话,频率和占空比就确定了一个波。

二、怎么能产生一个PWM波?

  方法1利用芯片内部模块输出PWM信号,STM32 的定时器除了 TIM6 和 7。其他的定时器都可以用来产生 PWM 输出。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4路的 PWM 输出,这样, STM32 最多可以同时产生 30 路 PWM 输出! 但是!!!同一个定时器TIM只能产生一个频率的PWM波,你只能改变占空比。 具体例程可查看STM32数据手册
  方法2利用IO口高低电平转变输出PWM信号,比如上图中先把电平置1,维持1ms,然后将电平拉低,维持3ms,再将电平置高,如此循环往复下去,就可以产生一个周期4毫秒占空比为25%的PWM波了。具体方法就是给IO口加一个定时器,用定时器中断来实现及时切换高低电平。 看后面51单片机代码部分。

  • 定时器

  要想使用51单片机来产生一路PWM,根据上述的方法2,首先你应该知道什么是定时器?定时器是怎么工作的?

  定时器:和计数器说的是一个东西,因为它既能计时也能计数。定时器的实质是,由机器频率向一个16位寄存器累加,累加满溢出时触发中断。为了产生一个我们想要的时间间隔。比如说1s,所以我们要在这个寄存器里设定一个初值,以至于让它在这个初值上累加可以产生一个1s的倍数。这样我们就得到了稳定的时间间隔。
  这个寄存器分为TH(高八位)和TL(低八位)。所以我们需要把计算好的初值分成两部分分别放入TH和TL。

  过程
  首先,我们通过单片机的晶振频率得知其时钟周期,时钟周期*12=机器周期。每一个机器周期在寄存器内+1,直到加满溢出产生中断。

  举例说明
  若单片机外部时钟频率为12MHz,其时钟周期就是1/12μs,机器周期为1μs,也就是每1μs寄存器+1。16位的寄存器加到溢出最多需要(2^16)-1=65535μs,溢出也需要一个机器周期,所以总共要65536μs。但这个值太别扭,和我们要的1s没什么关系。我们最好让它记50000μs产生一次中断,所以其初值就设为65536-50000=15536。但我们还要将这个值分别放在高八位和低八位,所以要将这个十进制数,转换为4位十六进制数再分开赋值。十进制计算法:TH = 15536/256; TL = 15536%256;进制计算问题这里不细讨论。这样的话,每50ms就会产生一次中断。我们只要用程序判断其中断20次就记1s。
   

三、PWM的应用

1、输出模拟电压(通过电压的高低来控制如LED的亮度,直流电机的速度,蜂鸣器的音调等)
  PWM对模拟信号电平进行数字编码的方法,计算机只能输出0或5V的数字电压值而不能输出模拟电压,而我们如果想获得一个模拟电压值(介于0 - 5V的电压值),则需通过使用高分辨率计数器,改变方波的占空比来对一个模拟信号的电平进行编码。电压是以一种连接(1)或断开(0)的重复脉冲序列被夹到模拟负载上去的,连接即是直流供电输出,断开即是直流供电断开。通过对连接和断开时间的控制,只要带宽足够,可以输出任意不大于最大电压值的模拟电压。

  输出电压=(接通时间/脉冲时间)*最大电压值

PWM输出等效电压
   PWM输出等效电压
2、控制步进电机
  做项目的过程中,一般涉及到精确控制位移的时候,会经常用到步进电机。
  对于四线双极性步进电机把电脉冲信号变换成角位移以控制转子转动的电机。在自动控制装置中作为执行元件。每输入一个脉冲信号,步进电动机前进一步,故又称脉冲电动机。 !!!这里注意一点,直接控制单片机的话是脉冲控制,就是进来一个脉冲信号,步进电机转动一个步进角(一般为0.9°)。所以控制步进电机速度的方式就是通过控制 频率 (占空比一般都是50%)但是!!!现在可以通过接入步进电机驱动板的方式细分步进角。比如细分为2,一个脉冲步进电机就转动半个脉冲(0.45°)


四、51单片机例程

  这里使用51实现呼吸灯的功能同样原理也可以控制直流电机;而步进电机是通过控制频率的方式来控制速度、蜂鸣器通过控制频率控制音调。

接线:P1.0接任意一个LDE灯!

这里写图片描述
有两种实现方法:不用定时器(延时)、定时器
延时和用定时器的区别在于:延时时执行的是delay函数中变量的加减,延时过程中,单片机只能执行delay函数
                                              定时器的话,是TH和TL寄存器不断的累加,直到溢出时执行一次中断处理程序,期间单片机还可以执行其他程序!


1.不用定时器(单纯使用延时)

/***
*源代码来来自于 https://www.bilibili.com/read/cv4779664
*pwm LED呼吸灯
*现象:亮-灭-亮 循环
*LED接口:P1.0
*思路:改变延时时间实现亮度不一从而实现呼吸的效果
******/
#include <reg52.h> //引用头文件

sbit led=P1^0;     //LED接口

bit ledsign=0;     //定义一个标志位ledsign==0 

void delay(int);   //声明延时函数
   
void main()
{
  int i=0;         //i:延时控制变量
  while(1)         
  {
   if(ledsign==0)   //如果b=0(初始0)(灯由亮到灭)
		 {   
				led=1;         //灭
				delay(i);      //i秒后(i从小到大)
				led=0;         //亮
				delay(1000-i); //延时1000(可自行定义)-i秒后
				i+=2;          //增加i(开灯的时间)
        if(i>=1000) 
        {	
            ledsign=1;     //i到最大值(>1000)改变标志位下一阶段(灯由灭到亮)
        }
   }
   else if(ledsign==1)         //判断是否进入到下一阶段(灯由灭到亮)
   {       
      led=1;    //灭
      delay(i);   //i秒后(i在上一阶段已到最大值(>1000))
      led=0;    //亮
      delay(1000-i);//延时1000(随手定义)-i秒后
      i-=2;     //减少i(开灯的时间)
      if(i<=0) 
      {
        ledsign=0;//判断是否回到上一阶段
      }
   }
   
  }
}

void delay(int a)      //定义延时函数
{
  int i;
  for(i=0;i<a;i++);
}

 2.用定时器

#include<reg52.h>
/*************************

**************************/

sbit LED = P1^0;

unsigned char PWM_COUNT;  	 //计数
unsigned int  HUXI_COUNT;    //占空比更新时间
unsigned char PWM_VLAUE;     //占空比比对值
bit direc_flag;             //占空比更新方向

void timer0_init(void);
	
void main()
{
    HUXI_COUNT = 0;
    PWM_COUNT = 0;
    PWM_VLAUE = 5;
    direc_flag = 0;
    LED = 1;            //默认LED熄灭   
    timer0_init();      //定时器0初始化
    while(1);
}

void timer0_init()
{
    TMOD=0x02;          		//  工作于模式2(M1=1,M0=0)
    TH0=0x38;               //定时器溢出值设置,每隔200us发起一次中断。12M晶振
    TL0=0X38;
    ET0=1;                  //开定时器0中断
    EA=1;                       //开总中断
    PWM_COUNT =0;
	  TR0=1;                  //定时器0开始计时
}

void time0() interrupt 1
{   
    PWM_COUNT++;
    HUXI_COUNT++;
    if(PWM_COUNT == PWM_VLAUE)      //判断是否到了点亮LED的时候
        LED = 0;                    //点亮LED
    if(PWM_COUNT == 10)             //当前周期结束
    {
        LED = 1;                    //熄灭LED
        PWM_COUNT = 0;              //重新计时
    }

    if((HUXI_COUNT == 600) && (direc_flag == 0))
    {                               //占空比增加10%
        HUXI_COUNT = 0;
        PWM_VLAUE++;
        if(PWM_VLAUE == 9)          //占空比更改方向
            direc_flag = 1; 
    }

    if((HUXI_COUNT == 600) && (direc_flag == 1))
    {                               //占空比减少10%
        HUXI_COUNT = 0;
        PWM_VLAUE--;
        if(PWM_VLAUE == 1)          //占空比更改方向
            direc_flag = 0; 
    }   
}

 

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

单片机PWM输出原理与实践 的相关文章

  • java中的编码转换(以utf8和gbk为例)

    在正常javaweb开发中经常会发现字符转换的需求 xff0c 会存在中文字符转换乱码的现象 xff0c 如何解决以及其转换原理我至今懵懵懂懂 xff0c 于是专门写了个测试代码进行尝试 xff0c 总算理清了编码 xff0c 先上结论 x
  • ERROR com.alibaba.druid.pool.DruidDataSource - init datasource error, url jdbcmysql

    部署一个开源项目报错 ERROR com alibaba druid pool DruidDataSource init datasource error url jdbcmysql 很明显是数据库连接错误 但排除一下错误后 xff0c 我
  • KVM下的Windows虚拟机盘符扩容

    今天发现工作站上的一个Windows虚拟机的一个盘符没有空间了 xff0c 需要为其进行扩容 探究过程如下 xff1a 1 确认需要调整的盘符对应的文件 2 关闭虚拟机 3 调整存储文件的大小 打开终端 xff0c 进入文件在所目录 xff
  • IDEA lombok包的@Data注解报错找不到符号

    问题描述 xff1a 工程编译报错 java 找不到符号 问题抽象 定位错误可以发现是getter setter的问题 由于采用了 64 Data注解 xff0c 所以优先考虑是lombok的问题 解决方案 首先排除以下可能 lombok插
  • python配合阿里云域名解析实现DDNS功能

    前置工作 安装阿里模块 pip span class token function install span aliyun python sdk core v3 pip span class token function install s
  • linux开机自启服务简单配置

    使用任意方式在 usr lib systemd system路径下新建一个demo service文件并在其中以如下模板编写内容 span class token punctuation span Unit span class token
  • git取消超过范围大文件并重新提交

    问题报错 remote error File db383b59a623629b36cc62dd3917db21c1375cf0 span class token number 690 93 span MB exceeds span clas
  • 基于pyqt的无边框浏览器

    自己写了个基于pyqt的无边框浏览器 xff0c 可以配合源阅读的web看书 xff0c 自用自取 目录结构 xff1a ui ui webview pycall webview y 环境安装 xff1a pip span class to
  • Pycharm默认输入状态是insert状态,选中文字无法直接输入替换或删除

    最近开始学习python xff0c 使用Pycharm编辑器进行学习过程中却发现 xff1a 打开一个新的py文件 xff0c 我的光标处于加粗状态 xff0c 也就是编程软件经常出现的insert插入编辑模式 xff0c 我就点击了一下
  • 输入字体之间的间隔突然变大了

    额 xff0c 这个问题之前也遇到几次 xff0c 后来莫名其妙变好了 我就没深究 最近写代码又出现了这种情况 就是敲了个快捷键 xff0c 就变成 后来发现是IDE的快捷键和输入法快捷键冲突了 解决方法 xff1a 按一下 shift 4
  • 西瓜的JSON笔记

    1 JSON是什么 JSON 指的是 JavaScript 对象表示法 xff08 J ava S cript O bject N otation java xff0c 脚本 xff0c 对象 xff0c 注释 xff09 JSON的特点
  • Windows 下安装 Ubuntu 双系统

    转载自 xff1a Windows 下安装 Ubuntu 双系统 一 准备 xff1a xff08 一 xff09 准备工具 xff1a U盘一个 xff08 请提前备份U盘里面的资料 xff0c 因为后面操作要格式化U盘 xff09 Ub
  • FreeRTOS 互斥信号量和二值信号量对比

    互斥信号量 1 有优先级继承 2 尽量不要在中断中调用 3 xSemaphoreCreateMutex创建后 xff0c 可以直接take使用 二值信号量 1 无优先级继承 2 允许在中断中调用 3 可以当做标志位来使用 4 xSemaph
  • 工作站常见问题处理

    常见问题1 xff1a 系统重启网桥消失 1 现象 公司的工作站自从搬到新地方以来 xff0c 每次关机再启动 xff0c 或重启后 xff0c 都会出现网桥消失的情况 2 分析 查找了网桥和网卡的配置 xff0c 也觉得没有什么问题 xf
  • Ubuntu17 安装ProxyChains4

    span class hljs preprocessor 切换目录 span cd Downloads span class hljs preprocessor 下载 span git clone https span class hljs
  • c++实现ip是否在同一个网段的判断

    废话不说直接贴代码 xff1a ip的数据结构 typedef struct IP Struct ip地址划分后各个域的值 struct IpAdress Struct int first int second int third int
  • 计算ip地址是否在同一网段

    一 要判断两个IP地址是不是在同一个网段 xff0c 就将它们的IP地址分别与子网掩码做与运算 xff0c 得到的结果 gt 网络号 xff0c 如果网络号相同 xff0c 就在同一子网 xff0c 否则 xff0c 不在同一子网 例 xf
  • 面试官再问你 HashMap 底层原理,就把这篇文章甩给他看

    前言 HashMap 源码和底层原理在现在面试中是必问的 因此 xff0c 我们非常有必要搞清楚它的底层实现和思想 xff0c 才能在面试中对答如流 xff0c 跟面试官大战三百回合 文章较长 xff0c 介绍了很多原理性的问题 xff0c
  • Java核心技术读书笔记——集合

    本笔记为读 Java核心技术 卷1 第9版 而记录 目录 1 集合接口与实现相互分离1 1Java类库中集合接口和迭代器接口1 2泛型实用方法 2 具体的集合2 1链表2 2数组列表2 3散列表2 4树集2 5对象的比较2 6队列与双端队列
  • #每天一篇论文#(213/365) Joint 2D-3D-Semantic Data for Indoor Scene Understanding 结合2D-3D室内语义数据场景理解

    Joint 2D 3D Semantic Data for Indoor Scene Understanding http 3Dsemantics stanford edu A 摘要 本文提供了一个大型室内空间的数据集 xff0c 它提供了

随机推荐

  • 我心中的AI

    首先说一下我的身份 xff0c 一个刚刚踏入IT行业的年轻小伙 xff0c 相信在坐的大家心中都会有一个小小的梦想 拥有一个 大黄蜂 xff0c 这是我从事这个职业的原因所在 人工智能从诞生以来 xff0c 理论和技术日益成熟 xff0c
  • 2021-09-04 **mininet+flowvisor+floodlight实现网络切片功能**

    mininet 43 flowvisor 43 floodlight实现网络切片功能 这个项目所使用的软件flowvisor 和floodlight 都已经过时了网上能找到的资料太少了 xff0c 整个项目搭建过程中遇到的坑太多了 花了大量
  • CentOS 6.5 时间同步

    1 检查是否安装ntpdate rpm qa grep ntp 有返回说明已经安装 xff0c 若无返回 xff0c 执行安装命令进行安装 2 安装ntpdate yum install y ntp ntpdate 3 修改时区 vi et
  • 在linux安装elasticsearch-7.6.2 所遇到的坑

    64 TOC在linux安装elasticsearch 7 6 2 所遇到的坑 问题描述 刚接触学习elasticsearch xff0c 在linux环境安装就遇到了一些问题 运行角色问题 elasticsearch不建议使用root账号
  • freeRTOS多任务启动流程和源码分析

    最近学习白问网韦东山老师在B站开源的freeRTOS课程 xff0c 网址 xff1a 韦东山直播公开课 xff1a RTOS实战项目之实现多任务系统 第1节 xff1a 裸机程序框架和缺陷 哔哩哔哩 bilibili和7天物联网训练营 第
  • mkdir 创建目录命令

    mkdir命令 mkdir 命令简介 mkdir命令用来创建指定的名称的目录 xff0c 要求创建用户在当前目录权限 xff0c 并且制定的目录名不能是当前目录中已有的目录 命令格式 mkdir 选项 目录 命令参数 m mode 61 模
  • UCOS-II任务间通信(信号量、邮箱、消息队列)

    保护任务之间的共享数据和提供任务之间的通讯方法 xff1a 利用宏OS ENTER CRITICAL 和OS EXIT CRITICAL 来关闭和打开中断 xff0c 这可以用于多任务或者任务和ISR共享某些数据时可以采用这种方法 利用OS
  • 高考到程序员,从娇惯到耐艹

    现在的我刚好是走出校门没两天 xff0c 踏入it行业的程序员 此刻的心情 xff0c 有与挚友分别的不舍 xff0c 有悔恨当初的颓废 xff0c 还有一种提到望月的闯劲儿 总之心理活动错综复杂 xff0c 和高考那会儿玩世不恭的我大不相
  • AI浪潮下需要思考的事

    一 AI的意义 AI xff0c 即ArtificialIntelligence的缩写 xff0c 它是研究如何以人类的智能行为以及思考方式来解决问题的计算机科学的一个分支 目前主要研究的领域包括语音识别 图像识别 自然语言处理以及在某一特
  • Hive(二) -- ddl

    Hive支持标准SQL xff0c 同时又有自己的特点 xff0c 属于方言版SQL Hive的ddl主要包含对于数据库和表的查询 创建和删除 dml包含数据查询和插入 xff0c 其中插入有load和insert两种方式 xff0c 针对
  • autolisp的各种框(DCL)

    一 DCL是什么 前面的事情 xff0c 是通过在命令行输入参数来实现某个指令的 xff0c 而DCL是通过用户界面来实现交互的 下图就是一个典型的DCL 二 DCL怎么用 xff1f 首先说明 xff0c DCL不像lisp xff0c
  • 在hbase shell中过滤器的简单使用

    在hbase shell中查询数据 xff0c 可以在hbase shell中直接使用过滤器 xff1a span class hljs comment hbase shell span gt scan span class hljs st
  • kswapd0占用CPU过高问题处理

    项目场景 xff1a kswapd0占用CPU过高 xff0c 严重影响服务器及虚拟机的使用 问题描述 最近同事反应工作站上的虚拟机太慢了 到虚拟机上看了一下 xff0c 资料占得很满 xff0c 一点很长时间没反应 xff0c 卡得不行
  • QQ新版表情序号及对应

    在学习QQ机器人发送消息接口时遇到了新版表情发送问题 xff0c 以及QQ新版表情序号跟面板中不是完全对应的 xff0c 于是遍历了0 500号表情 xff0c 作一一输出 xff0c 得到了大部分表情的序号及对照如下 xff1a 表情使用
  • Java判断String字符串是否相等时容易出现的问题

    在程序设计中 xff0c 我们经常需要判断字符串是否相等 xff0c 如if a 61 61 b xff0c 但在java中 xff0c a和b两个字符串值相等 xff0c 但有时会判断出不相等的情况 例如 xff1a span class
  • ALDS1_2_C:Stable Sort

    题目链接 xff1a ALDS1 2 C Stable Sort 题目概要 xff1a 扑克牌中存在数字相同而花色不同的情况 xff0c 该题需要利用扑克牌这一特性来比较两种排序 xff1a 冒泡排序 选择排序 xff08 题中给出伪代码
  • jupyter notebook 安装nbextension不显示问题

    2023年4月18日 更新 评论区一位老哥的方法 xff0c 不用下载mark js xff0c 复制一份源目录里的文件改名即可 xff0c 经测试 xff0c 有效 xff0c 评论已置顶 首先放一下安装nbextensions的步骤 如
  • Python对象序列化性能比较:pickle、json、msgpack

    目录 前言三种工具介绍PickleJsonMsgpack性能参考 xff08 由ChatGPT给出 xff09 实际测试测试条件测试结果 前言 最近在做毕设 xff0c 需要读取处理大量的数据 xff0c txt中文文本 xff0c 大概有
  • IRQL_NOT_LESS_OR_EUQAL,间歇性蓝屏,4800h笔记本,暗影精灵6,解决办法,蓝屏问题排查

    目录 前言机器配置蓝屏情况已测试方法及思路前期准备使用WinDbg分析蓝屏文件软件 系统排查 xff1a 驱动排查 xff1a 系统排查 硬件排查硬件检测硬件替换 送修 已知解决办法总结 前言 本文章所列出解决方法适用于AMD Ryzen
  • 单片机PWM输出原理与实践

    一 什么是PWM xff1f PWM xff08 Pulse Width Modulation xff09 脉冲宽度调制 xff0c 它是通过对一系列脉冲的宽度进行调制 xff0c 等效出所需要的波形 xff08 包含形状以及幅值 xff0