找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4088|回复: 3
收起左侧

PWM技术的原理和应用—基于89C52/89C51单片机演示程序

[复制链接]
ID:816824 发表于 2021-3-30 00:10 | 显示全部楼层 |阅读模式
一、技术概念
PWM,中文名称为“脉冲宽度调制”,该技术是用于在数字电路模拟电路的控制。在数字电路中,只存在01信号,即“电压为0V”和“电压为5V”,而在模拟电路中,不同的电压值会对器件的工作状态会有不同的效果。例如:一颗LED的工作电压为1.7V-3.6V不等,不同的电压值,影响着LED的亮度。那么如何通过数字电路的“0”、“1”来控制LED两端出现不同的电压?
   二、技术原理
在日常时候中,我们用的生活电压为220V,这个是用直流电压表测试的。如果用交流电压,那么示数会在±340V之间振荡。因为220V是其有效值,±340V是其峰峰值。如果单片机的I/O口也会输出一个从“5V”到“0V”的振荡信号,会不会也在I/O口存在一个“0”到“5V”之间的有效值。
既然是一个振荡的信号,那么就要考虑两个指标:“周期/频率”“高电平的持续时间/低电平的持续时间”
频率一定大,既周期时间要短,因为LED有余晖作用,在短时间内电压为0时,灯光并不会立刻消失。我们假设频率为100Hz,也就是说1S之内有100个波形(1个高电平和1个低电平为一个波形)。T=0.01s
先设置高电平持续时间为0.005s,占周期的50%=0.005/0.01)×100%,而这个50%被称为PWM的占空比。
占空比为50%.png 324609_2_0.jpg
那么我们可以根据这些数据通过公式来推出其等效的直流电压(直流电压表的示数),是计算其有效值还是其平均值
是有效值,因为交流电的有效值在相同时间内消耗的能量是一样的,公式推导如下:
图片1.jpg
※U是有效值,u(t)是交流电的对t的函数,T为周期
平均值:仅仅是电压在时间上的平均值,是不能等效成元件两端的电压。
图片2.jpg

通过公式计算出占空比50%时,其有效值为U=2.5*1.414=3.54V

    不同的占空比,对应着不同的有效值:
不同的占空比.png
三,流程图
从原理可以得知一个51系列的单片机通过控制I/O口的输出信号的占空比就可以控制LED的亮度。
那么我们设定4种占空比(10%30%50%90%)的情况,并且通过摁键可以互相改变。
信号的周期可以通过单片机的定时器来控制,一个周期为0.01s=10ms,当定时器工作在方式1,单片机晶振为12MHz时,一次定时器中断最大时间为65.536ms。我们设定一次定时器中断时间为100μs,这样一个波形的周期需要经过100次的定时器中断,设置一个变量count,用来判断是否到达100,从而重新开始一个周期。
可以先设置I/O口的初始为高电平,定义一个标志变量FLAGFLAG的作用是用来和count做比较从而单片机判断是否达到了占空比的要求,例如,占空比设定为50%,当count=50的时候,将高电平变为低电平,就会出现占空比为50%的波形。
PWM流程图.png

四、单片机代码
  1. #include "reg52.h"
  2. sbit L=P2^0;
  3. sbit K=P3^0;
  4. unsigned int count=0,FLAG=0,stat;
  5. void DELAY(int t)
  6. {
  7.                 while(t--);
  8. }
  9. void init_T0(void)
  10. {
  11.         EA=1;
  12.         ET0=1;
  13.         IP=0x02;
  14.   TMOD=0x01;
  15.         TL0=(65535-100)%256;
  16.         TH0=(65535-100)/256;
  17.         TR0=1;
  18. }
  19. void scan_key(void)
  20. {
  21.         if(K==0)
  22.         {
  23.                 DELAY(10);
  24.                 if(K==0)
  25.                 {
  26.                         switch(stat)
  27.                          {
  28.          case 0:
  29.                                          TR0 = 1;
  30.                                          L = 0;
  31.                                    FLAG = 10;
  32.                                    stat = 1;
  33.                                  break;
  34.                                  case 1:
  35.                                    FLAG = 50;
  36.                                    stat = 2;
  37.                                  break;
  38.                                  case 2:
  39.                                          FLAG = 90;
  40.                                    stat = 3;
  41.                                  break;
  42.                                  case 3:
  43.                                          L= 1;
  44.                                    TR0 = 0;
  45.                                    stat = 0;
  46.                                  break;
  47.                          }
  48.                          while (K==0);
  49.                 }
  50.         }
  51. }
  52. void main()
  53. {
  54.         init_T0();
  55.         L=1;
  56.         while(1)
  57.         {
  58.                         scan_key();
  59.   }
  60. }
  61. void timer0() interrupt 1
  62. {
  63.         TL0=(65535-100)%256;
  64.         TH0=(65535-100)/256;
  65.         
  66.         if(count==FLAG)
  67.         {
  68.                 L=1;
  69.         }
  70.         count++;
  71.         if(count==100)
  72.         {                count=0;
  73.                 if(FLAG==0)
  74.                 L=1;
  75.                 else
  76.                 L=0;
  77.         }

  78. }
复制代码

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:582255 发表于 2021-3-31 11:51 | 显示全部楼层
应该是65536-100吧?
回复

使用道具 举报

ID:163285 发表于 2021-3-31 11:59 | 显示全部楼层
讲的很好!请设计一个8灯连续左右移动的呼吸灯,即1灯最亮8灯最俺,2灯次亮7灯次暗。。。。。。
回复

使用道具 举报

ID:894943 发表于 2021-4-2 12:01 | 显示全部楼层
简单扼要,好文章,适合初学者
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表