系统初始频率为50Hz.docx
《系统初始频率为50Hz.docx》由会员分享,可在线阅读,更多相关《系统初始频率为50Hz.docx(16页珍藏版)》请在冰豆网上搜索。
系统初始频率为50Hz
目录
摘要I
AbstractII
1、总体设计原理1
2.硬件芯片2
2.1控制芯片AT89C512
2.2数模转换芯片DAC08324
2.21DAC0832简介4
2.22DAC0832 的结构4
2.23DAC0832 的三种工作方式5
3系统电路设计与分析7
3.1基本原理7
3.2程序框图7
4源程序8
5电路图及仿真结果图12
5.1电路图12
5.2仿真结果图13
6.心得体会15
参考文献16
摘要
本课程设计是为了实现频率可控的正弦波信号发生器。
本课设采用AT89C51为控制核心,设计了一个低频函数信号发生器。
信号发生器采用数字波形合成技术,通过硬件电路和软件程序相结合,可输出正弦波,波形的频率和幅度在一定范围内可任意改变。
波形和频率的改变通过软件控制,幅度的改变通过硬件实现。
这里采取256个点,运用DAC0832实行数模转换加以末级采用高精度放大器实现完美的波形输出。
本文介绍了波形的生成原理、硬件电路和软件部分的设计原理。
本系统可以产生最高频率50HZ的波形。
该信号发生器具有体积小、价格低、性能稳定、功能齐全的优点。
这在平时自己研究中也可以自制,对于自己的能力提高有很大的帮助,理解一些频率变换实验更加直观。
关键字:
频率;正弦波;发生器
Abstract
Thiscourseisdesignedtoachievethesinewavefrequencycontrollablesignalgenerator.LetthelessonusingAT89C51tocontrolthecore,thedesignofalow-frequencysignalgeneratorfunction.Signalgeneratorusingdigitalwaveformsynthesistechnology,throughacombinationofhardwareandsoftwareprograms,sinewaveoutput,frequencyandamplitudeofthewaveformwithinacertainrangecanbearbitrarilychanged.Changethewaveformandfrequencycontrolledbysoftware,bychangingtheamplitudeofthehardwareimplementation.Heretake256points,usingDAC0832digital-analogconvertertoimplementthefinalstageamplifierwithhighprecisiontoachievetheperfectwaveoutput.Thispaperintroducestheprincipleofwaveformgeneration,hardwareandsoftwaredesignprinciplessection.Thissystemcanproducethehighestfrequency50HZwaveform.Thesignalgeneratorhasasmallsize,lowprice,stableperformance,fullyfunctionaladvantages.Thiscanalsobemadeintheusualownresearch,fortheirabilitytoimproveagreathelptounderstandsomeofthemoreintuitivefrequencyconversionexperiments.
Keywords:
frequency;sinewave;generator
1、总体设计原理
为实现频率可控的正弦波,而kile软件本身不具有SIN函数直接出现正弦波,为此将正弦波在理论上进行采样,当每个点的间隔很小的时候可以近似为连续的函数,这就需要利用芯片DAC0832进行实现。
DAC0832可以实现数模转换,在外面加上电流电压转换电路出现电压幅值。
在此基础上采用AT89C51进行控制,它进行数据输出控制还有显示控制,并且接受频率加减控制。
系统初始频率为50Hz,变频采用“+”、“-”键 控制,当按下“+”键是正弦波的频率自动加1输出,当按下“—”时,正弦波频率自动减一输出,用电压表进行波形测量,用液晶屏LCD1602进行显示具体的频率值
2.硬件芯片
2.1控制芯片AT89C51
AT89C51是美国ATMEL公司生产的低电压,高性能CMOS8位单片机,片内含4k bytes的可反复擦写的只读程序存储器(PEROM)和128 bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器(CPU)和Flash存储单元。
图1AT89C51管脚图
AT89C52结构介绍:
P0口:
P0口是一组8位漏极开路型双向I/O口,也即地址/数据总线复用口。
作为输出口用时,每位能吸收电流的方式驱动8个TTL逻辑门电路,对端口写“1”可作为高阻抗输入端用。
在访问外部数据存储器或程序存储器时,这组口线分时转换地址(低8位)和数据总线复用,在访问期间激活内部上拉电阻。
在FIash编程时,P0口接收指令字节,而在程序校验时,输出指令字节,校验时,要求外接上拉电阻。
P1口:
P1是一个带内部上拉电阻的8位双向I/O口,P1的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。
对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。
作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流(IIL)。
FIash编程和程序校验期间,P1接收低8位地址。
P2口:
P2是一个带有内部上拉电阻的8位双向I/O口,P2的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。
对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口,作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流(IIL)。
在访问外部程序存储器或16位地址的外部数据存储器(例如执行MOVX@DPTR指令)时,P2口送出高8位地址数据。
在访问8位地址的外部数据存储器(如执行MOVX@RI指令)时,P2口线上的内容(也即特殊功能寄存器(SFR)区中R2寄存器的内容),在整个访问期间不改变。
Flash编程或校验时,P2亦接收高位地址和其它控制信号。
P3口:
P3口是一组带有内部上拉电阻的8位双向I/O口。
P3口输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。
对P3口写入“1”时,它们被内部上拉电阻拉高并可作为输入端口。
作输入端时,被外部拉低的P3口将用上拉电阻输出电流(IIL)。
P3口除了作为一般的I/O口线外,更重要的用途是它的第二功能,如下表所示:
P3.0 RXD(串行输入口)
P3.1 TXD(串行输出口)
P3.2 /INT0(外部中断0)
P3.3 /INT1(外部中断1)
P3.4 T0(记时器0外部输入)
P3.5 T1(记时器1外部输入)
P3.6 /WR(外部数据存储器写选通)
P3.7 /RD(外部数据存储器读选通)
P3口还接收一些用于Flash闪速存储器编程和程序校验的控制信号。
RST:
复位输入。
当振荡器工作时,RST引脚出现两个机器周期以上高电平将使单片机复位。
ALE/PROG:
当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。
即使不访问外部存储器,ALE仍以时钟振荡频率的l/6输出固定的正脉冲信号,因此它可对外输出时钟或用于定时目的。
要注意的是:
每当访问外部数据存储器时将跳过一个ALE脉冲。
如有必要,可通过对特殊功能寄存器(SFR)区中的8EH单元的DO位置位,可禁止ALE操作。
该位置位后,只有一条MOVX和MOVC指令ALE才会被激活。
此外,该引脚会被微弱拉高,单片机执行外部程序时,应设置ALE无效。
PSEN:
程序储存允许输出是外部程序存储器的读选通信号,当AT89C51由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN有效,即输出两个脉冲。
在此期间,当访问外部数据存储器,这两次有效的PSEN信号不出现。
EA/VPP:
外部访问允许。
欲使CPU仅访问外部程序存储器(地址为0000H—FFFFH),EA端必须保持低电平(接地)。
需注意的是:
如果加密位LB1被编程,复位时内部会锁存EA端状态。
如EA端为高电平(接VCC端),CPU则执行内部程序存储器中的指令。
Flash存储器编程时,该引脚加上+12V的编程允许电源Vpp,当然这必须是该器件是使用12V编程电压Vpp。
XTAL1:
振荡器反相放大器的及内部时钟发生器的输入端。
XTAL2:
振荡器反相放大器的输出端。
2.2数模转换芯片DAC0832
2.21DAC0832简介
DAC转换器是一种将数字量转换成模拟量的器件,其特点是接收、保持和转换的是数字信息,不存在随温度和时间的漂移问题,因此电路的抗干扰性能较好。
DAC0832是8位分辨率的D/A转换集成芯片,它具有价格低廉、接口简单及转换控制容易等特点。
它由8位输入锁存器、8位DAC寄存器、8位DIA转换电路及转换控制电路组成,能和CPU数据总线直接相连,属中速转换器,大约在1us内将一个数字量转换成模拟量输出。
2.22DAC0832 的结构
D0~D7:
8位数据输入线,TTL电平,有效时间应大于 90ns(否则锁存器的数 据会出错);
ILE:
数据锁存允许控制信号输入线,高电平有效; CS:
片选信号输入线(选通数据锁存器),低电平有效;
WR1:
数据锁存器写选通输入线,负脉冲(脉宽应大于500ns)有效。
由ILE、 CS、WR1的逻辑组合产生LE1,当LE1为高电平时,数据锁存器状态随输入数据 线变换,LE1的负跳变时将输入数据锁存;
XFER:
数据传输控制信号输入线,低电平有效,负脉冲(脉宽应大于500ns) 有效;
WR2:
DAC寄存器选通输入线,负脉冲(脉宽应大于500ns)有效。
由WR1、XFER 的逻辑组合产生LE2,当LE2为高电平时,DAC寄存器的输出随寄存器的输入而 变化,LE2的负跳变时将数据锁存器的内容打入DAC寄存器并开始D/A转换。
IOUT1:
电流输出端1,其值随DAC寄存器的内容线性变化; IOUT2:
电流输出端2,其值与IOUT1值之和为一常数;
Rfb:
反馈信号输入线,改变Rfb端外接电阻值可调整转换满量程精度; Vcc:
电源输入端,Vcc的范围为+5V~+15V;
VREF:
基准电压输入线,VREF的范围为-10V~+10V; AGND:
模拟信号地 DGND:
数字信号地
图2DAC0832管脚图和内部逻辑图
2.23DAC0832 的三种工作方式
1.直通方式
直通方式就是使 DAC0832 内部的两个寄存器(输入寄存器和DAC 寄存器)
处于不锁存状态,数据一旦到达输入端DI7~DI0,就直接送入D/A 转换器,被转 换成模拟量。
当ILE为高电平,CS 和WR 1﹑WR 2和XFER 端都接数字地,这时 锁存信号LE 1 ﹑LE2 均为高
电平,输入寄存器和DAC 寄存器均处于不锁存状态,即直通方式。
2.单缓冲方式
2.单缓冲方式
单缓冲方式就是使两个寄存器中的一个处于缓冲方式,另一个处于锁存方式, 数据只通过一级缓冲器送入D/A 转换器。
通常的做法是将和XFER 均接地,使 DAC 寄存器处于直通方式,而把ILE接高电平,接端口地址译码信号,WR 1接 CPU系统总线的IOW 信号,使输入寄存器处于锁存方式。
单缓冲方式只需执行 一次写操作即可完成D/A 转换。
一般不需要多个模拟量同时输出时,可采用单 缓冲方式。
3.双缓冲方式
双缓冲方式就是使两个寄存器均处于锁存方式,数据要经过两级锁存(即两级 缓冲)后再送入D/A 转换器,这就是说,要执行两次写操作才能完成一次D/A 转 换。
只要将ILE 接高电平,WR 1和WR 2接CPU的IOW ,CS 和XFER 分别接两 个不同的I/O 地址译码信号即可。
图中的 Rfb 是内部电阻,是为外部运算放大器提供的反馈电阻,用以提供适当 的输出电压,Vref 端是由外电路为芯片提供的参考电源,电压范围在-10V~ +10V。
另外,DAC0832 为电流输出型DAC,使用时需外接运算放大器,芯片 的电源电压最好工作在+15V。
3系统电路设计与分析
3.1基本原理
本次实验采用DC0832芯片的但缓冲方式,正弦波信号的产生用循环语句进行连续产生,进而近似得到模拟型。
对于正弦信号,为确定每一个点的幅值,因为DAC0832芯片输出为8位,总共可以取256个值,因此将一个周期的正弦信号分为256份,取256个值,这样可以保证一定的精确度。
正弦波幅值的计算公式如下:
A=B*sin(I*π/255) (I从0取到255)
正弦波的幅度主要采用由主AT89C51控制D/A转换的参考电压来控制,正弦波频率的变化由改变输出点之间的延时来实现。
判断是否有加减频率要求时,判断P1口的数据,当P1口低四位为“1111”时,表示没有中断请求,当低四位为“1011”时,表示加频率的请求,程序进入加频率的中断;当低四位为“1101”时,表示减频率的请求,程序进入减频率的中断。
因为AT89C51中断是低电平触发,所以可以用与门电路实现控制,当按键按下时与门输出为低电平触动触发。
减价频率均以1HZ为步进
3.2程序框图
4源程序
#include
#defineucharunsignedchar
#defineuintunsignedint
//#defineFosc24000000/12000000//12分频后的频率
sbitDA_S1=P2^0;//控制DAC0832的8位输入寄存器,仅当都为0时,可以输出数据(处于直通状态),否则,输出将被锁存
sbitDA_S2=P2^1;//控制DAC0832的8位DAC寄存器,仅当都为0时,可以输出数据(处于直通状态),否则,输出将被锁存
sbitkey=P3^2;
/uintT_temp;
ucharcodelcd_hang1[]={"SineWave"};
ucharidatalcd_hang2[16]={"f=Hz"};
uinta=0;
uinttotal_freq=50;
ucharcodesine_tab[256]={
//输出电压从0到最大值(正弦波1/4部分)
0x80,0x83,0x86,0x89,0x8d,0x90,0x93,0x96,0x99,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,0xb1,0xb4,0xb7,0xba,0xbc,
0xbf,0xc2,0xc5,0xc7,0xca,0xcc,0xcf,0xd1,0xd4,0xd6,0xd8,0xda,0xdd,0xdf,0xe1,0xe3,0xe5,0xe7,0xe9,0xea,0xec,
0xee,0xef,0xf1,0xf2,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfd,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,
//输出电压从最大值到0(正弦波1/4部分)
0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf2,0xf1,0xef,
0xee,0xec,0xea,0xe9,0xe7,0xe5,0xe3,0xe1,0xde,0xdd,0xda,0xd8,0xd6,0xd4,0xd1,0xcf,0xcc,0xca,0xc7,0xc5,0xc2,
0xbf,0xbc,0xba,0xb7,0xb4,0xb1,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x99,0x96,0x93,0x90,0x8d,0x89,0x86,0x83,0x80,
//输出电压从0到最小值(正弦波1/4部分)
0x80,0x7c,0x79,0x76,0x72,0x6f,0x6c,0x69,0x66,0x63,0x60,0x5d,0x5a,0x57,0x55,0x51,0x4e,0x4c,0x48,0x45,0x43,
0x40,0x3d,0x3a,0x38,0x35,0x33,0x30,0x2e,0x2b,0x29,0x27,0x25,0x22,0x20,0x1e,0x1c,0x1a,0x18,0x16,0x15,0x13,
0x11,0x10,0x0e,0x0d,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
//输出电压从最小值到0(正弦波1/4部分)
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0d,0x0e,0x10,
0x11,0x13,0x15,0x16,0x18,0x1a,0x1c,0x1e,0x20,0x22,0x25,0x27,0x29,0x2b,0x2e,0x30,0x33,0x35,0x38,0x3a,0x3d,
0x40,0x43,0x45,0x48,0x4c,0x4e,0x51,0x55,0x57,0x5a,0x5d,0x60,0x63,0x66,0x69,0x6c,0x6f,0x72,0x76,0x79,0x7c,0x80};
voiddelay(ucharz)//延迟
{
uintx;
for(x=z;x>0;x--);
}
/************1602液晶的相关函数*************/
#definelcd_portsP1
sbitrs=P2^2;
sbitrw=P2^3;
sbitlcden=P2^4;
voidwrite_com(ucharcom)
{
rs=0;//置零,表示写指令
lcden=0;
lcd_ports=com;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voidwrite_date(uchardate)
{
rs=1;//置1,表示写数据(在指令所指的地方写数据)
lcden=0;
lcd_ports=date;
delay(5);
lcden=1;
delay(5);
lcden=0;
}
voiddisp_lcd(ucharaddr,uchar*temp1)
{
ucharnum;
write_com(addr);
delay
(1);//延时一会儿?
?
?
for(num=0;num<16;num++)
{
write_date(temp1[num]);//或者这样写write_date(*(temp1+num));
delay
(1);
}
}
voidinit_lcd()
{
//ucharnum;
lcden=0;//可有可无?
?
?
rw=0;//初始化一定要设置为零,表示写数据
write_com(0x38);//使液晶显示点阵,为下面做准备
write_com(0x0c);//初始设置
write_com(0x06);//初始设置
write_com(0x01);//清零
write_com(0x80);//使指针指向第一行第一格
disp_lcd(0x80,&lcd_hang1[3*16]);//在第一行显示
disp_lcd(0xc0,&lcd_hang1[4*16]);//在第二行显示
/*for(num=0;num<16;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40);//给指针重新赋值,使之指向第二行第一格
for(num=0;num<16;num++)
{
write_date(table1[num]);
delay(5);
}*/
/*TMOD=0x01;//选用定时方式1
TH0=(65536-50000)/256;//赋初值
TL0=(65536-50000)%256;//
EA=1;//开总中断
ET0=1;//开定时器中断
TR0=1;//启动定时器*/
}
/********************1602液晶函数声明结束*********************/
voidkey_int0()interrupt0//中断
{
ucharkeytemp;
uinttotal_freq;//总频率
EA=0;TR0=0;//关总中断与定时器
delay(5);//延时够吗?
?
?
if(key==0)//确实有按键按下而引发中断
{
keytemp=P1&0x0f;//获取P1口低四位的值
switch(keytemp)
{
case0x0d:
//加频率
a++;
total_freq++;
break;
case0x0b:
//减频率
a--;
total_freq--;
break;
}
}
while(!
key);
EA=1;TR0=1;//开启总中断与定时器
}
voidmain()
{
uchari=0;
DA_S2=0;//使DAC寄存器处于直通状态
DAdata=0;
DA_S1=1;//关闭8位输入寄存器
init_lcd();
IT0=1;//设置外部中断0为下降沿触发
ET0=1;//开定时器中断
EX0=1;
EA=1;
while
(1)
{DA_S1=0;//打开8位输入寄存器
DA_S1=1;//关闭8位输入寄存器
for(i=0;i<256;i++)
{