C51模拟PWM
PWM是什么
PWM,即脉冲宽度调制,是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。
PWM原理
随着电子技术的发展,出现了多种PWM技术,其中包括:相电压控制PWM、脉宽PWM法、随机PWM、SPWM法、线电压控制PWM等,而在镍氢电池智能充电器中采用的脉宽PWM法,它是把每一脉冲宽度均相等的脉冲列作为PWM波形,通过改变脉冲列的周期可以调频,改变脉冲的宽度或占空比可以调压,采用适当控制方法即可使电压与频率协调变化。可以通过调整PWM的周期、PWM的占空比而达到控制充电电流的目的。
模拟信号的值可以连续变化,其时间和幅度的分辨率都没有限制。9V电池就是一种模拟器件,因为它的输出电压并不精确地等于9V,而是随时间发生变化,并可取任何实数值。与此类似,从电池吸收的电流也不限定在一组可能的取值范围之内。模拟信号与数字信号的区别在于后者的取值通常只能属于预先确定的可能取值集合之内,例如在{0V, 5V}这一集合中取值。
模拟电压和电流可直接用来进行控制,如对汽车收音机的音量进行控制。在简单的模拟收音机中,音量旋钮被连接到一个可变电阻。拧动旋钮时,电阻值变大或变小;流经这个电阻的电流也随之增加或减少,从而改变了驱动扬声器的电流值,使音量相应变大或变小。与收音机一样,模拟电路的输出与输入成线性比例。
尽管模拟控制看起来可能直观而简单,但它并不总是非常经济或可行的。其中一点就是,模拟电路容易随时间漂移,因而难以调节。能够解决这个问题的精密模拟电路可能非常庞大、笨重(如老式的家庭立体声设备)和昂贵。模拟电路还有可能严重发热,其功耗相对于工作元件两端电压与电流的乘积成正比。模拟电路还可能对噪声很敏感,任何扰动或噪声都肯定会改变电流值的大小。
通过以数字方式控制模拟电路,可以大幅度降低系统的成本和功耗。此外,许多微控制器和DSP已经在芯片上包含了PWM控制器,这使数字控制的实现变得更加容易了。
PWM的优点
PWM的一个优点是从处理器到被控系统信号都是数字形式的,无需进行数模转换。让信号保持为数字形式可将噪声影响降到最小。噪声只有在强到足以将逻辑1改变为逻辑0或将逻辑0改变为逻辑1时,也才能对数字信号产生影响。
对噪声抵抗能力的增强是PWM相对于模拟控制的另外一个优点,而且这也是在某些时候将PWM用于通信的主要原因。从模拟信号转向PWM可以极大地延长通信距离。在接收端,通过适当的RC或LC网络可以滤除调制高频方波并将信号还原为模拟形式。
总之,PWM既经济、节约空间、抗噪性能强,是一种值得广大工程师在许多设计应用中使用的有效技术。
上文摘自:http://www.elecfans.com/article/83/116/2011/20111102233223.html
c51模拟原理:用中断控制高电平在一个周期内的占比
视频介绍:http://v.youku.com/v_show/id_XMTI4NTkzNjY4.html
51程序:
1 #include<reg52.h>
2
3 #define uchar unsigned char
4 #define uint unsigned int
5
6 sbit led = P1^2;
7 uchar cycle; //定义周期,该数字X基准定时时间,如果是10,则周期是10*0.1ms
8 uchar pwm_on; //定义高电平时间
9
10 void delay(uint cnt) //uint,防止数据溢出
11 {
12 while(--cnt);
13 }
14
15 void main()
16 {
17 bit flag;
18
19 TMOD |= 0x01;
20 TH0 = (65536-100)/256;
21 TL0 = (65536-100)%256; //定时0.1ms
22 IE = 0x82; //打开中断
23 TR0 =1;
24
25 cycle = 30; //时间可以调整,这个10是调整,8位PWM就是256步
26 while(!flag)
27 {
28 delay(2000); //延时时间,从一个亮度到下一个亮度的时间,速度快就能看到连续效果
29 pwm_on++;
30 if(pwm_on == cycle) flag = 1;
31 }
32 while(flag) //亮度递减,同上,是个相反的过程
33 {
34 delay(2000);
35 pwm_on--;
36 if(0 == pwm_on) flag = 0;
37 }
38 // while(1)
39 // {
40 // led = 1;
41 // }
42 }
43
44 //定时器中断
45 void timer(void) interrupt 1 using 1
46 {
47 static uchar count;
48 TH0 = (65536-100)/256;
49 TL0 = (65536-100)%256; //定时0.1ms
50 //led = 0;
51
52 if(count == pwm_on) P1 = 0xff; //灯灭
53 count++;
54 if(count == cycle)
55 {
56 count = 0;
57 if(pwm_on!=0) //如果左右时间是0,保持原来状态
58 P1 = 0x00; //灯亮
59 }
60 }