基于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

bash 复制代码
#include <reg52.h>		//头文件
#include <intrins.h>
#include <stdio.h>
#include <math.h>  
#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long

uchar 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 信号发生器  ";

sbit rs=P2^7;	   	//12864液晶端口的定义
sbit rw=P2^6;
sbit ep=P2^5;
sbit lcd_psb=P2^4;

sbit  FSYNC=P1^4;   	//AD9833端口的定义
sbit  SCLK =P1^3;   
sbit  SDATA=P1^2;

sbit s1=P2^0;	  //光标键
sbit s2=P2^1;	  //上调键
sbit s3=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);
    
}


void display()
{		   
	    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)
			   		{
			
					     case 0: 
						         lcd_dat('S');	  //按0为正弦波
								 delay(5);
								 lcd_dat('I');
								 delay(5);
								 lcd_dat('N');
								 delay(5);
					             break;
					     case 1: 
						         lcd_dat('T');	  //按1为三角波
								 delay(5);
								 lcd_dat('R');
								 delay(5);
								 lcd_dat('I');
								 delay(5);
					             break;
					     case 2: 
						         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)
			   		 {
			
					     case 0: 
						         lcd_dat('S');	  //按0为正弦波
								 delay(5);
								 lcd_dat('I');
								 delay(5);
								 lcd_dat('N');
								 delay(5);
					             break;
					     case 1: 
						         lcd_dat('T');	  //按1为三角波
								 delay(5);
								 lcd_dat('R');
								 delay(5);
								 lcd_dat('I');
								 delay(5);
					             break;
					     case 2: 
						         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);
				}
			 }
		

		}
	

	}


}


void main() 
{	
	   	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)
   		{

		     case 0: 
			         Config_Data[0]=0x2108;	   //按0为正弦波
		             Config_Data[7]=0x2008;
		             break;
		     case 1: 
			         Config_Data[0]=0x210A;	   //按1为三角波
		             Config_Data[7]=0x200A;
		             break;
		     case 2: 
			         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]);
  		}

}








相关推荐
youshi666813 小时前
stm32-PWR、低功耗模式
stm32·单片机·嵌入式硬件
云泽80814 小时前
深入浅出 STM32(十八):时钟树、总线与寄存器的底层联动机制
stm32·单片机·嵌入式硬件
米饭不加菜15 小时前
C51 语言参考手册
经验分享·笔记·单片机·嵌入式硬件
科芯创展15 小时前
2.7VIN,5VOUT,360KHz,电荷泵升压芯片,XZ3120
单片机
dozenyaoyida15 小时前
LittleFS 嵌入式文件系统机制拆解与某 RISC-V MCU 实测配置
单片机·嵌入式·文件系统·risc-v·littlefs·flash存储
方芯半导体16 小时前
EtherCAT 从站方案中 MAC、PHY 与 MII 的层级关系与实现解析
网络·人工智能·单片机·macos·ethercat
智购科技无人售货机工厂16 小时前
2026自动售货机触摸屏驱动开发:从I2C协议到多点触控校准的工程实践~YH
android·驱动开发·python·单片机·云原生·django
天空'之城16 小时前
单片机基础核心知识点汇总(十四)
单片机·嵌入式硬件
DevHub17 小时前
STM32 USB HID 教程:TinyUSB 实现键盘设备,从描述符到枚举
arm开发·stm32·单片机·嵌入式硬件·mcu·计算机外设
泛凡(Linyongui)18 小时前
第三篇、生命的bug分两种:一种是Flash坏了,一种是RAM乱了
人工智能·单片机·程序人生