波形发生器课程设计.docx
《波形发生器课程设计.docx》由会员分享,可在线阅读,更多相关《波形发生器课程设计.docx(10页珍藏版)》请在冰豆网上搜索。
波形发生器课程设计
课程设计
题目波形發生器
姓名
院(系)
专业班级
学号
日期2010年12月13日—2010年12月19日
摘要
数模转化器可以实现将数字量转化为模拟量的功能,对于理想的数模转换器,输入的数字量的波形与输出的模拟量之间呈线性关系。
因此,通过使用单片机来输出不同的数字量,再通过D/A转换,就可以得到不同的波形。
本文主要讲述通过单片机产生方波、三角波、锯齿波、梯形波、正弦波的数字量,并给出相应的D/A转化电路,进而得到具有相应波形的模拟量。
这五种波形的数字量都可以简单地通过定时器中断来产生。
关键词:
波形发生数模转换单片机定时器中断
一、实验原理
利用单片机实现波形输出的重点在于对应波形的数字量的产生。
不同波形产生实质上是对输出的二进制数字量进行相应改变来实现的。
在本文中,所有波形的二进制数字量的产生都通过定时器中断。
在每次中断中,八位的二进制数字量通过I/O口输出,再经由D/A转化电路转化为模拟量。
除正弦信号,其他波形的初始的八位二进制数字量都为0。
各种波形的数字量产生如下:
1)对于方波信号,在每次定时器中断时都对二进制数字量进行位取反,因此,方波信号的二进制数字量总是在0x00和0xff二者上变动。
2)对于三角波信号,在每次定时器中断中,二进制数字量依次加1,达到0xff时依次减1
3)对于锯齿波信号,其类似于三角波信号,但在达到0xff时将二进制数字量置为0x00
4)对于梯形波信号,其类似于三角波信号,但在达到0xff或0x00时,都会保持一段时间
5)对于正弦波信号,可以直接对正弦曲线进行均匀取样后直接转化为数字量,在每次定时器中断中,都依序将这些数字量输出
对于D/A转换,可以利用集成芯片DAC0832来实现。
由于DAC0832输出的是电流量,在D/A转换后需要添加额外的比例运放电路来产生电压量。
二、实验电路
实验的流程如下:
单片机在开始运行后就会不断进行键盘扫描。
当按下对应波形的按钮后,单片机会产生相应波形的数字量,这个数字量作为DAC0832的输入再被转化为电流量。
电流量经过两个反比例运算放大器后,转化为电压量输出到示波器中显示。
三、实验结果
实验所产生的方波、三角波、锯齿波、梯形波、正弦波波形如下所示
四、实验体会
五、程序代码
#include
typedefunsignedcharuchar;
typedefunsignedintuint;
//正弦曲线四分之一周期曲线的数字量
ucharcodesdata[256]=\
{128,130,131,133,134,136,137,139,140,142,144,145,147,148,150,151,153,154,156,157,159,160,162,164,165,167,168,169,171,172,174,175,177,178,180,181,182,184,185,187,188,189,191,192,194,195,196,197,199,200,201,203,204,205,206,208,209,210,211,212,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,236,237,238,239,240,240,241,242,242,243,244,244,245,246,246,247,247,248,248,249,249,250,250,251,251,251,252,252,252,253,253,253,253,254,254,254,254,254,255,255,255,255,255,255,255,255,255,255,255,255,255,255,254,254,254,254,254,253,253,253,253,252,252,252,251,251,251,250,250,249,249,248,248,247,247,246,246,245,244,244,243,242,242,241,240,240,239,238,237,236,236,235,234,233,232,231,230,229,228,227,226,225,224,223,222,221,220,219,218,217,216,215,214,212,211,210,209,208,206,205,204,203,201,200,199,197,196,195,194,192,191,189,188,187,185,184,182,181,180,178,177,175,174,172,171,169,168,167,165,164,162,160,159,157,156,154,153,151,150,148,147,145,144,142,140,139,137,136,134,133,131,130,128};
//timer用于重装时间常数
staticunion{
uinttime;
struct{
ucharth;
uchartl;
}time_array;
}timer;
//counter用于波形发生时的计数,从0到255
staticucharcounter;
//state表示当前所要输出波形,1表示方波,2表示三角波,3表示锯齿玻,4表示梯形波,5表示正弦波,0表示暂停波形发生(保持P2口输出不变)
staticucharstate;
//new_state根据P1口的电平,转化为state
staticucharnew_state;
//check_state_bit用于get_state函数中
staticucharcheck_state_bit;
//direction表示波形方向,direction=0表示波形处于上升,direction=1表示波形处于下降
staticbitdirection;
//delay用于梯形波中
staticbitdelay;
//stop表示暂停波形发生(保持P2口输出不变)
staticbitstop;
/*
获取当前状态,即哪个按钮被按下
若没有按钮被按下,则state保持不变
若P1_0=0,则state=1,表示方波发生
若P1_1=0,则state=2,表示三角波发生
以此类推
若P1_5=0,则state=0,表示暂停波形发生(保持P2口输出不变)
*/
voidget_state(){
//优先考虑P1_5口,即优先考虑暂停波形发生
if(!
P1_5){
new_state=0;
return;
}
check_state_bit=0x01;
new_state=1;
while((check_state_bit&P1)&&new_state<6){
check_state_bit<<=1;
++new_state;
}
if(new_state==6)
new_state=state;
}
//每次state即将发生改变,即切换输出到另一种波形时,都进行初始化
voidinit(){
P2=0;
direction=0;
counter=0;
}
//检查P1口,以输出相应的选择的波形
voidcheck(){
get_state();
//如果state即将发生改变
if(state!
=new_state){
//当P1_5口为低电平,new_state=0
//则暂停波形发生,则暂停定时器1定时,并令P3_6口(WR)为高电平
if(new_state==0){
P3_6=1;
TR1=0;
stop=1;
return;
}
//切换输出波形
else{
init();
state=new_state;
if(state==4)
delay=0;
}
}
elseif(stop){
P3_6=0;
TR1=1;
stop=0;
}
}
//当INT0脚接收到一个下降沿,则触发外部中断0
//则输出波形的周期倍增
voidint0int()interrupt0{
if(timer.time==15680)
timer.time=245;
else
timer.time<<=1;
init();
}
//当INT1脚接收到一个下降沿,则触发外部中断1
//则输出波形的周期倍减
voidint1int()interrupt2{
if(timer.time==245)
timer.time=15680;
else
timer.time>>=1;
init();
}
//定时器1用于波形的发生
voidtimeint()interrupt3{
//~time.time等价于time.time=65535-time.time
timer.time=~timer.time+1;
TL1=timer.time_array.tl;
TH1=timer.time_array.th;
timer.time=~(timer.time-1);
//方波发生
if(state==1){
++counter;
if(counter==0xff){
direction=~direction;
P2=~P2;
counter=1;
}
}
//其余波的发生
elseif(state>1&&state<6){
//当输出梯形波,若delay=1则进行延迟,即保持当前输出电平不变
if(state==4){
if(!
delay)
P2=counter;
}
//输出正弦波
elseif(state==5){
if(direction)
P2=~(sdata[counter])+1;
else
P2=sdata[counter];
}
//输出三角波、锯齿波
else
P2=counter;
//当波形处于下降过程
if(direction){
//若counter下降至0,则改变波形方向至上升过程
if(counter==0){
//对于梯形波,下降结束后进行延迟
if(state==4){
delay=~delay;
if(delay)
counter=0xfe;
else
direction=~direction;
}
else{
direction=~direction;
counter++;
}
}
else
counter--;
}
//当波形处于上升过程
else{
//若counter上升至0xff,则改变波形方向至下降过程
if(counter==0xff){
//对于梯形波,上升结束后进行延迟
if(state==4){
delay=~delay;
if(delay)
counter=0x01;
else
direction=~direction;
}
//对于锯齿波,当上升至0xff,将counter置为0
elseif(state==3)
counter=0;
else{
direction=~direction;
counter--;
}
}
else
counter++;
}
}
}
voidmain(){
IEN=0x8F;
TMOD=0x10;
PT1=1;
IT0=1;
IT1=1;
state=0xff;
P3_6=0;
//~time.time等价于time.time=65535-time.time
timer.time=1960;
timer.time=~timer.time+1;
TL1=timer.time_array.tl;
TH1=timer.time_array.th;
timer.time=~(timer.time-1);
TR1=1;
while
(1)
check();
}