使用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种波形完全能够满足实验中的使用要求。通过软件实现可以输出更多的基本波形如:梯形波、三角波、反向锯齿波等,具有实际的使用价值。 |
|