王洁曦丑女无敌董迎迎:使用PWM调制信号产生多种波形
来源:百度文库 编辑:中财网 时间:2024/04/28 16:39:32
使用PWM调制信号产生多种波形
作者:
概 述 :在自身研发过程中,信号发生器是一个必不可少的仪器,但因为其价钱的缘故往往使个人研发者望而怯步。而往往我们需求的波形不多、要求精度也不是那么精密,因此对于满足一般性的要求波形发生器,我们可以用一片小型的单片机来完成。这样不但可以增加自身的技能还可以节省一批费用,何乐而不为呢。
在大多设计中我们普遍采用求定点正弦函数值的做法:以产生正弦波为例,采用定点法来生成波形,即将一个周期的正弦波按360o等分为若干点,计算出各点的正弦函数值,并转化相应的D/A转换器输入数值,这样得到一个正弦函数表。通过程序将该表存于单片机的程序存储器中,利用单片机的定时器来产生定时,每当定时时间到时,查表得到该点对应的输出值,然后通过D/A转换得到该点的对应电压值。如此,周而复始地查表输出,就得到所要的正弦波。由于一个周期正弦波的点数固定,改变定时器的定时值,就改变相邻两点的间隔时间,从而改变正弦波的频率。 三角波和锯齿波的产生方法与正弦波类似。方波的产生较简单,只要交替地将最大值和最小值输出给D/A进行转换即可,它们的延续时间为周期的一半。
在此,我们通过另外一种更简便的方法来产生多种波形,使用单片机的PWM调制信号产生多种波形,但此种方法的缺陷就是产生波形的频率有限。
摘 要:介绍了基于HT46R47单片机产生多种波形,采用放大器TL062,高速、稳定、具有良好的线性,用户通过按键选择输出需要的波形,波形精度能够满足一般的使用条件。
关键词:波形发生器、单片机HT46R47、放大器TL062、三角波、锯齿波、正弦波。
本文利用HT46R47单片机外接滤波电路,由HT46R47单片机产生不同占空比的PWM信号,经过滤波器将其窄带波形滤除掉从儿得到我们所需要的试验波形。由用户通过按键选择输出实验中经常使用到的几种基本波形:三角波、锯齿波、正弦波。
1 硬件设计
HT46R47单片机时钟电路采用内部方式,外接晶体谐振器(频率为4 MHz),微调电容值为30 pF。系统复位采用掉电复位方式,通过按键由用户选择要输出的波形,按键选择占用PA.0~PA.7口,采用独立式键盘结构。利用HT46R47单片机内部自带的PWM发生器在 PD.0口上产生PWM信号,通过改变PWM信号的占空比来调节输出波形的频率。系统设计图如图1所示。
1.1 二级运算放大器TL062
前面TL
其输出为:U02 = -U01 = 1/RC∫U0dt;由图可知,U02 = -Ui,则 U0 = -RCdv/dt。
1.2 PWM调制原理
冲量相等而形状不同的窄脉冲加在具有惯性的环节上时,其效果基本相同。冲量指窄脉冲的面积。效果基本相同,是指环节的输出响应波形基本相同。低频段非常接近,仅在高频段略有差异。
图1-1 形状不同而冲量相同的各种窄脉冲
面积等效原理:
分别将如图1-1所示的电压窄脉冲加在一阶惯性环节(R-L电路)上,如图1
图1-2 冲量相同的各种窄脉冲的响应波形
用一系列等幅不等宽的脉冲来代替一个正弦半波,正弦半波N等分,看成N个相连的脉冲序列,宽度相等,但幅值不等;用矩形脉冲代替,等幅,不等宽,中点重合,面积(冲量)相等,宽度按正弦规律变化。
SPWM波形——脉冲宽度按正弦规律变化而和正弦波等效的PWM波形。
图1-3 用PWM波代替正弦半波
要改变等效输出正弦波幅值,按同一比例改变各脉冲宽度即可。
2 软件设计
在硬件设计的基础上进行软件编程,由用户通过按键选择需要输出何种波形。按照波形发生器的功能,其应用程序必须有初始化、波形产生、键盘管理等几部分,我们在这里重点介绍正弦波的生成过程:
2.1 正弦波输出
我们在这里采用定时/计数器改变其PWM寄存器的值,从而改变PWM的占空比。首先设置定时/计数寄存器(TMR),定时/计数控制器(TMRC),中断控制寄存器(INTC)。然后通过HT46R47内部自带的脉冲宽度调制器,输出PWM信号。
PWM的占空比的计算方式:X(n)=PWM/256;
斜率点的计算方式:n=0~39;(取的点数)
X(n)=(sin(0.05*Pi*n)+1)/2;
按照以上计算公式我们抽取了40个点一个周期,从而计算出我们所需要的PWM值,程序源代码如下 :
/**---------------文件信息-------------------------------------------------------------------------------
**文 件 名: CreateWave.c
**创 建 人:
**最后修改日期:
**描 述:
**-----------------历史版本信息------------------------------------------------------------------------
** 创建人:
** 版 本: v1.0
** 日 期:
** 描 述: 原始版本
**--------------当前版本修订------------------------------------------------------------------------------
** 修改人:
** 版 本:
** 日 期:
** 描 述:
#include
//--------------------------RAM define--------------------------//
#define IAR _iar
#define MP _mp
#define ACC _acc
#define PCL _pcl
#define TBLP _tblp
#define TBLH _tblh
#define STATUS _status
#define INTC _intc
#define TMR _tmr
#define TMRC _tmrc
#define PA _pa
#define PAC _pac
#define PB _pb
#define PBC _pbc
#define PD _pd
#define PDC _pdc
#define PWM _pwm
#define ADRL _adrl
#define ADRH _adrh
#define ADER _ader
#define ACSR _acsr
#define TON _ton
#define PD0 _pd0
#define PA7 _pa7
//--------------------------I/O define--------------------------//
#define KEY_1 _pa0
#define KEY_2 _pa1
#define KEY_3 _pa2
typedef unsigned char uint8; /*-----无符号8位整型变量------*/
typedef signed char int8; /*-----有符号8位整型变量------*/
typedef unsigned long uint16; /*-----无符号16位整型变量-----*/
typedef signed long int16; /*-----有符号16位整型变量-----*/
const uint8 wave[40]={128,148,168,186,203,219,232,242,250,254,255,254,250,242,232,219,203,186,
168,148,128,108,88,70,53,37,24,14,6,2,1,2,6,14,24,37,53,70,88,108};
const uint8 wave2[40]={128,131,134,137,140,144,147,150,153,156,160,163,166,169,172,176,179,
182,185,188,192,195,198,201,204,207,210,214,217,220,224,227,230,233,236,240,243,246,249,255};
const uint8 wave3[40]={128,140,153,166,179,192,204,217,230,243,255,243,230,217,204,192,179,166,
153,140,128,116,103,90,77,64,52,39,26,13,1,13,26,39,52,64,77,90,103,116};
uint8 Acc_buff,Status_buff,Key_flag,Point1,Point2,Point3;
unsigned long Tcounter1,Tcounter2,Tcounter3;
#pragma vector Timer0 @0x08 //定时器0中断入口地址
/**********************************************************************************
** 函数名称: Delay()
** 功能描述: 延时函数
** 输 入: x,x可决定延时时间的长短
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
** 作 者:
** 日 期:
/**********************************************************************************
void Delay(uint16 x)
{
uint16 i;
if(x>=0xFFFF) x=0xFFFF;
for(i=0; i
}
/************************************************************************************ 函数名称: SysInit()
** 功能描述: 系统初始化
** 输 入:
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
** 作 者:
** 日 期:
/**********************************************************************************
void SysInit(void)
{
INTC=0b00000101; //允许定时器0中断
TMRC=0b10100010; //定时器模式,无分频(Timer Rate为1:1)
TMR=206; //256-206*1us==50us
TON=1;
PAC=0x
PBC=0x00; //PB设置为输入
PDC=0x00; //PD设置为输出
Point1=Point2=Point3=Acc_buff=Status_buff=Key_flag=0;
Tcounter1=Tcounter2=Tcounter3=0;
PD0=1;
}
/************************************************************************************ 函数名称: Timer0()
** 功能描述: 定时器0函数
** 输 入:
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
** 日 期:
**********************************************************************************
void Timer0(void)
{
Acc_buff=ACC;
Status_buff=STATUS; //保持现场
if(Key_flag==0x01) {Tcounter1++;Point2=Point3=0;}
if(Key_flag==0x02) {Tcounter2++;Point1=Point3=0;}
if(Key_flag==0x04) {Tcounter3++;Point1=Point2=0;}
TMR=206;
ACC=Acc_buff;
STATUS=Status_buff;
}
/************************************************************************************ 函数名称: main()
** 功能描述: 系统主程序
** 输 入: 无
** 输 出: 无
** 全局变量: 无
** 调用模块: 无
** 作 者:
** 日 期:
/**********************************************************************************
void main(void)
{
SysInit();
while(1)
{
if(Tcounter1>=50) //f=10Hz的正弦波
{
Tcounter1=0;
PWM=wave1[Point1];
PD0=1;
Point1++;
if(Point1==40) Point1=0;
}
if(Tcounter2>=50) //f=10Hz的三角波形
{
Tcounter2=0;
PWM=wave2[Point2];
Point2++;
if(Point2==40) Point2=0;
}
if(Tcounter3>=50) //f=10Hz的锯齿波形
{
Tcounter3=0;
PWM=wave3[Point3];
Point3++;
if(Point3==40) Point3=0;
}
//-----------------------------按键动作----------------------------------------//
if(KEY_1==0)
{
Delay(500);
if(KEY_1==0) {Key_flag=0x01;}
}
else if(KEY_2==0)
{
Delay(500);
if(KEY_2==0) Key_flag=0x02;
}
else if(KEY_3==0)
{
Delay(500);
if(KEY_3==0) Key_flag=0x04;
}
}
}
2.2 锯齿波和三角波输出
锯齿波中的斜线用一个个小台阶来逼近,在一个周期内从最小值开始逐步递增,当达到最大值后又回到最小值,如此循环,当台阶间隔很小时,波形基本上近似于直线。适当选择循环的时间,可以得到不同周期的锯齿波。
而三角波形输出则和正弦波形输出类似。
三角波斜率计算公式:n=0~39;
X(n)=(n/10+1)/2;(n<=10)
X(n)=((20-n)/10+1)/2; (10<><>
X(n)=((n-40)/10+1)/2; (n>30)
锯齿波的斜率计算公式:n=0~39;
X(n)=n/40;
3 结语
本文基于HT46R47单片机的多种波形发生器产生的3种波形完全能够满足实验中的使用要求。通过软件实现可以输出更多的基本波形如:梯形波、三角波、反向锯齿波等,具有实际的使用价值。
<>