基于STC89C51单片机的多波形信号发生器设计与Proteus仿真
基于STC89C51单片机的多波形信号发生器设计与Proteus仿真
摘 要
随着电子技术和集成电路的飞速发展,信号发生器作为电子测量领域的基础设备,其性能和智能化水平不断提升。本设计以STC89C51单片机为控制核心,设计了一款多波形信号发生器。系统通过单片机控制DA转换模块产生多种波形信号,结合LCD液晶显示模块实现信号频率、幅值及波形类型的实时显示,并通过按键模块完成参数设置与波形切换。硬件电路部分包括DA转换电路、LCD显示接口电路及按键控制电路;软件部分采用C语言编写,实现波形生成算法、数据处理及人机交互等功能。同时,本设计利用Proteus仿真软件对整个系统进行了电路仿真与功能验证,仿真结果表明:系统能够稳定输出正弦波、方波、三角波等多种波形,频率和幅度调节范围满足设计要求,波形质量良好,LCD显示准确,按键响应灵敏。该设计具有结构简单、成本低廉、操作方便、可靠性高等优点,为信号发生器的教学实验和工程应用提供了有效的参考方案。
关键词:信号发生器;STC89C51单片机;DA转换;Proteus仿真;LCD显示
Abstract
With the rapid development of electronic technology and integrated circuits, signal generators, as fundamental equipment in the field of electronic measurement, have continuously improved in performance and intelligence. This design adopts the STC89C51 microcontroller as the control core to design a multi-waveform signal generator. The system generates various waveform signals through the microcontroller-controlled DA conversion module, combines an LCD display module to achieve real-time display of signal frequency, amplitude, and waveform type, and uses a keypad module for parameter setting and waveform switching. The hardware circuit includes a DA conversion circuit, an LCD display interface circuit, and a keypad control circuit. The software is programmed in C language to implement waveform generation algorithms, data processing, and human-machine interaction functions. Meanwhile, the Proteus simulation software is used to simulate and verify the entire system. The simulation results show that the system can stably output multiple waveforms such as sine waves, square waves, and triangular waves. The frequency and amplitude adjustment ranges meet the design requirements, with good waveform quality, accurate LCD display, and sensitive keypad response. This design features a simple structure, low cost, convenient operation, and high reliability, providing an effective reference solution for teaching experiments and engineering applications of signal generators.
Keywords: Signal Generator; STC89C51 Microcontroller; DA Conversion; Proteus Simulation; LCD Display
目录
摘 要 1
Abstract 1
实验一 信号发生器 3
一、 实验目的 3
二、实验原理 3
1 系统概述 4
1.1 设计任务 4
1.2 总体方案 4
2 信号发生器的Proteus软件仿真电路设计 5
2.1 LCD液晶设计 5
2.2 DA模块 6
2.3 按键模块 6
3 数字电压表的软件程序设计 6
三.实验设备 6
四、实验内容 7
#include <reg52.h> //头文件#include <intrins.h>#include <stdio.h>#include <math.h>#define uint unsigned int#define uchar unsigned char#define ulong unsigned longuchar s1num,shape,num,a,b,c,d,e,f,h,boxing;ulong Freq,g;uint Config_Data[8];uchar code table1[]="波形选择 : SIN ";uchar code table2[]="波形频率 : ";uchar code table3[]="0 0 0 0 0 0 0 HZ";uchar code table4[]="DDS 信号发生器 ";sbitrs=P2^7;//12864液晶端口的定义 sbitrw=P2^6;sbitep=P2^5;sbitlcd_psb=P2^4;sbitFSYNC=P1^4;//AD9833端口的定义 sbit SCLK=P1^3;sbitSDATA=P1^2;sbits1=P2^0;//光标键 sbits2=P2^1;//上调键 sbits3=P2^2;//下调键 void Wave_Generate(ulong,uchar);//波形的频率和波形的选择 void AD9833_Send_Word(uint);//AD9833的数据接收函数 void delay(uint);//延时函数 void delay(uint xms){uint i,j;for(i=xms;i>0;i--)for(j=110;j>0;j--);}void lcd_cmd(uchar cmd)//12864写入的指令{rs=0;rw=0;ep=0;P0=cmd;delay(5);ep=1;delay(5);ep=0;}void lcd_dat(uchar dat)//12864写入的数据{rs=1;rw=0;ep=0;P0=dat;delay(5);ep=1;delay(5);ep=0;}void lcd_init()//12864液晶的初始化{lcd_psb=1;delay(5);lcd_cmd(0x34);delay(5);lcd_cmd(0x30);delay(5);lcd_cmd(0x0c);delay(5);lcd_cmd(0x01);delay(5);}voiddisplay(){uint i;lcd_cmd(0x80);//第一行显示 while(table1[i]!='\0'){lcd_dat(table1[i]);i++;}i=0;lcd_cmd(0x90);//第二行显示 while(table2[i]!='\0'){lcd_dat(table2[i]);i++;}i=0;lcd_cmd(0x88);//第三行显示 while(table3[i]!='\0'){lcd_dat(table3[i]);i++;}i=0;lcd_cmd(0x98);//第四行显示 while(table4[i]!='\0'){lcd_dat(table4[i]);i++;}}void input_freq()//矩形键盘扫描函数{if(s1==0)//光标键{delay(5);if(s1==0){s1num++;while(!s1);lcd_cmd(0x0f);if(s1num==1){lcd_cmd(0x80+7);}if(s1num==2){lcd_cmd(0x88+6);}if(s1num==3){lcd_cmd(0x88+5);}if(s1num==4){lcd_cmd(0x88+4);}if(s1num==5){lcd_cmd(0x88+3);}if(s1num==6){lcd_cmd(0x88+2);}if(s1num==7){lcd_cmd(0x88+1);}if(s1num==8){lcd_cmd(0x88+0);}if(s1num==9){s1num=0;lcd_cmd(0x0c);g=a+10*b+100*c+1000*d+10000*e+100000*f+1000000*h;Freq=g;boxing=shape;Wave_Generate(Freq,boxing);}}}if(s1num!=0)//上调键{if(s2==0){delay(5);if(s2==0){while(!s2);if(s1num==1){shape++;if(shape==3)shape=0;lcd_cmd(0x80+6);switch(shape){case0: lcd_dat('S');//按0为正弦波 delay(5);lcd_dat('I');delay(5);lcd_dat('N');delay(5);break;case1: lcd_dat('T');//按1为三角波 delay(5);lcd_dat('R');delay(5);lcd_dat('I');delay(5);break;case2: lcd_dat('D');//按2为方波 delay(5);lcd_dat('A');delay(5);lcd_dat('C');delay(5);break;}}if(s1num==2){a++;if(a==10)a=0;lcd_cmd(0x88+6);lcd_dat(0x30+a);}if(s1num==3){b++;if(b==10)b=0;lcd_cmd(0x88+5);lcd_dat(0x30+b);}if(s1num==4){c++;if(c==10)c=0;lcd_cmd(0x88+4);lcd_dat(0x30+c);}if(s1num==5){d++;if(d==10)d=0;lcd_cmd(0x88+3);lcd_dat(0x30+d);}if(s1num==6){e++;if(e==10)e=0;lcd_cmd(0x88+2);lcd_dat(0x30+e);}if(s1num==7){f++;if(f==10)f=0;lcd_cmd(0x88+1);lcd_dat(0x30+f);}if(s1num==8){h++;if(h==10)h=0;lcd_cmd(0x88+0);lcd_dat(0x30+h);}}}}if(s1num!=0){if(s3==0){delay(5);if(s3==0){while(!s3);if(s1num==1){shape--;if(shape==-1)shape=2;lcd_cmd(0x80+6);switch(shape){case0: lcd_dat('S');//按0为正弦波 delay(5);lcd_dat('I');delay(5);lcd_dat('N');delay(5);break;case1: lcd_dat('T');//按1为三角波 delay(5);lcd_dat('R');delay(5);lcd_dat('I');delay(5);break;case2: lcd_dat('D');//按2为方波 delay(5);lcd_dat('A');delay(5);lcd_dat('C');delay(5);break;}}if(s1num==2){a--;if(a==-1)a=9;lcd_cmd(0x88+6);lcd_dat(0x30+a);}if(s1num==3){b--;if(b==-1)b=9;lcd_cmd(0x88+5);lcd_dat(0x30+b);}if(s1num==4){c--;if(c==-1)c=9;lcd_cmd(0x88+4);lcd_dat(0x30+c);}if(s1num==5){d--;if(d==-1)d=9;lcd_cmd(0x88+3);lcd_dat(0x30+d);}if(s1num==6){e--;if(e==-1)e=9;lcd_cmd(0x88+2);lcd_dat(0x30+e);}if(s1num==7){f--;if(f==-1)f=9;lcd_cmd(0x88+1);lcd_dat(0x30+f);}if(s1num==8){h--;if(h==-1)h=9;lcd_cmd(0x88+0);lcd_dat(0x30+h);}}}}}voidmain(){P0=0xff;P1=0xff;P2=0xff;P3=0xff;//delay(10000);lcd_init();display();FSYNC=1;SCLK=0;delay(5);Wave_Generate(1000,0);while(1){input_freq();}}void AD9833_Send_Word(uint Data_In){uchar i;SCLK=1;FSYNC=0;for(i=0;i<16;i++){SCLK=1;SDATA=(bit)((Data_In&0x8000)>>15);SCLK=0;Data_In=Data_In<<1;}FSYNC=1;SCLK=0;}void Wave_Generate(ulong Freq,uchar shape){ulong temp;uchar k;if(Freq>12000000)Freq=12000000;switch(shape){case0: Config_Data[0]=0x2108;//按0为正弦波 Config_Data[7]=0x2008;break;case1: Config_Data[0]=0x210A;//按1为三角波 Config_Data[7]=0x200A;break;case2: Config_Data[0]=0x2128;//按2为方波 Config_Data[7]=0x2028;break;default: Config_Data[0]=0x2108;Config_Data[7]=0x2008;}temp=Freq*10.73;//temp=Freq*(0x10000000/20000000);Config_Data[1]=temp&0x00003fff;Config_Data[3]=Config_Data[1];Config_Data[2]=(temp&0x0fffc000)>>14;Config_Data[4]=Config_Data[2];Config_Data[1]=Config_Data[1]|0x4000;Config_Data[2]=Config_Data[2]|0x4000;Config_Data[3]=Config_Data[3]|0x8000;Config_Data[4]=Config_Data[4]|0x8000;Config_Data[5]=0xC000;Config_Data[6]=0xE000;for(k=0;k<8;k++){AD9833_Send_Word(Config_Data[k]);}}