一·实验目的
1﹑掌握PWM的工作原理。
2﹑掌握采用PWM实现DAC的工作原理及电路原更大。3﹑掌握PWM实现信号发生器的方法。
二﹑实验原理
PWM是 Pulse Width Modulation 的缩写,中文意思就是脉冲宽度调制,简称脉宽调制·它是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,其控制简单﹑灵活和动态响应好等优点而成为电力电子技术最广泛应用的控制方式,其应用领域包括测量,通信,功率控制与变换,电动机控制﹑伺服控制﹑调光﹑开关电源,甚至某些音频放大器,因此学习PWM具有十分重要的现实意义。
其实我们也可以这样理解,PWM是一种对模拟信号电平进行数字编码的方法·通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码·PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM进行编码。PWM对应模拟信号的等效图,如下图所示:
从图中可以看到,上图 a是一个正弦波即模拟信号, b是一个数字脉冲波形即数字信号。我们知道在计算机系统中只能识别是1和0,对于51单片机芯片,要么输出高电平(5V),要么输出低电平(O),假如要输出1.5V的电压,那么就必须通过相应的处理,比如本章所要讲解的 PWM输出,其实从上图也可以看到,只要保证数字信号脉宽足够就可以使用PWM进行编码,从而输出1.5V的电压。PWM的输出其实就是对外输出脉宽可调(即占空比调节)的方波信号,信号频率是由T的值决定,占空比由C的值决定·其示意图如图所示:
从上图中可以看到,PWM输出频率是不变的,改变的是C的值,此值的改变将导致PWM输出信号占空比的改变·占空比其实就是一个周期内高电平时间与周期的比值·而频率的话可以使用51单片机的定时器确定
三﹑主要仪器设备
机电实验平台,万用表﹑示波器,电脑四﹑实验内容
单片机电路如图所示:
开发板上 DAC(PWM)模块电路,如下图所示:
从上图中可知,该模块是独立的,由J50端子输入PWM信号,可使用单片机 P2.1管脚输出 PWM信号至J50端子,DAC1为 PWM输出信号,将其连接一个LED,这样可以通过指示灯的状态直观的反映出 PWM输出电压值变化·LM358芯片与这些电容电阻构成了一个跟随电路,即输入是多少,输出即为多大电压,输出电压范围是0-5V·输出信号由J52端子的DAC1引出,在其端子上还有一个AIN3脚,它是上一章介绍ADC时的外部模拟信号输入通道О如果使用短接片将DAC1和AIN3短接,这样就可以使用
XPT2046芯片采集检测PWM输出信号。
完成实验内容:通过采用PWM实现DA功能,输出一正弦波函数,并用示波器测量甩产生的波形,并拍照。
#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"
sbit PWM=P1^0;
void SIN();
void sinss();
void PWM100();
unsigned char i;T_flag,PWM_flag,SIN_flag,PWM_count;
unsigned char PWM_code[100]={50,53,56,59,62,65,68,71,74,76,
79,81,84,86,88,90,92,93,95,96,
97,98,99,99,99,99,99,99,99,98,
97,96,95,93,92,90,88,86,84,81,
79,76,74,71,68,65,62,59,56,53,
50,46,43,40,37,34,31,28,25,23,
20,18,15,13,11,9,7,6,4,3,
2,1,0,0,0,0,0,0,0,1,
2,3,4,6,7,9,11,13,15,18,
20,23,25,28,31,34,37,40,43,46};
void main()
{
Timer0_Init();
while(1)
{
;
}
}
void Timer0_Routine() interrupt 1// 1ms
{
TL0 = 0xa0; //设置定时初值
TH0 = 0xFF; //设置定时初值
T_flag=1;
if (T_flag==1)
{
T_flag=0;
PWM_count++;
if(PWM_count<PWM_code[i])
PWM=1;
if(PWM_count>=PWM_code[i])
PWM=0;
if(PWM_count>99)
{
PWM_count=0;
PWM=1;
if(i<100)i++;else i=0;
}
}
}
void PWM100(unsigned char PWM_code_tmp)
{
if (T_flag==1)
{
T_flag=0;
PWM_count++;
if(PWM_count<PWM_code_tmp)
PWM=1;
else
PWM=0;
if(PWM_count>99)
{
PWM_count=0;
PWM_flag=1;
}
}
}
void SIN() //循环调用比较值
{
{
for (i=0;i<100;i++)
{
PWM100(PWM_code[i]);
if(PWM_flag==1) PWM_flag=0;
}
if(i==100) SIN_flag=1;
}
}
void sinss()
{
if(SIN_flag==1)
{ SIN_flag=0;
SIN();
}
}