基于51单片机的波形发生器proteus仿真数码管LCD12864显示

news2025/7/28 9:18:19

仿真图1简介:

本系统采用51单片机作为系统的MCU(具体型号见下图),该系统显示器为四位数码管,可实时显示波形的参数情况
可显示四种波形,分别是方波、正弦波、三角波、锯齿波。
该设计具有电压表功能,可显示当前所测电压参数,其中ADC芯片采用的是PCF8591
该设计不支持调节波形的占空比
波形输出通过仿真软件的示波器可以查看得到
系统设计有一个功能按键作为波形切换功能。
在这里插入图片描述

#include <reg51.h>
#include <PCF8591.h>
#include <seg.h>

sbit KEY = P3^7;

unsigned char code sin_num[]={
0,0,0,0,0,0,0,0,1,1,1,1,1,2,2,2,
2,3,3,4,4,4,5,5,6,6,7,7,8,8,9,9,
10,10,11,12,12,13,14,15,15,16,17,18,18,19,20,21,
22,23,24,25,25,26,27,28,29,30,31,32,34,35,36,37,
38,39,40,41,42,44,45,46,47,49,50,51,52,54,55,56,
57,59,60,61,63,64,66,67,68,70,71,73,74,75,77,78,
80,81,83,84,86,87,89,90,92,93,95,96,98,99,101,102,
104,106,107,109,110,112, 113,115,116,118,120,121,123,124,126,128,
129,131, 132,134,135, 137, 139,140,142,143,145,146,148, 149,151,153,
154,156,157,159,160,162,163,165, 166,168,169,171,172,174,175,177,
178,180,181, 182,184,185,187,188,189,191,192,194,195,196,198,199,
200,201,203,204,205,206,208,209,210,211,213,214,215,216,217,218,
219,220,221,223,224,225,226,227,228,229,230,230,231,232,233,234,
235,236,237,237,238,239,240,240,241,242,243,243,244,245,245,246,
246,247,247,248,248,249,249,250,250,251,251, 251,252,252,253,253,
253,253,254,254,254,254,254,255,255,255,255, 255,255,255,255,255
}; //这是正弦波上升半周期的采样

uchar Recv_Buffer;//数据接收缓冲
uchar Voltage[]="0.000V  ";//数据分解为电压x.xx
float Vol_Am;								//放大后的电压值
uchar key_ms;
uchar mode;

void delay(unsigned int x)//延时
{
	while(--x);
}

void key_pro()
{
	if(KEY == 0)	key_ms++;
	if(key_ms	>= 5)
	{
		if(KEY == 0)
		{
			key_ms = 0;
			mode++;
			if(mode >= 5)	mode = 0;
			while(!KEY);
		}
	}
}

void DAC_Wave()
{
	int i;
	switch(mode)
  {
   case 1: //三角波
			for(i=0;i<255;i++)
			{
				DAC_PCF(i);
				key_pro();
			}
			for(i=255;i>0;i--)
			{
				DAC_PCF(i);
				key_pro();
			}
			break;
			
	  case 2://方波
			DAC_PCF(0);
			delay(2500);
			DAC_PCF(0xff);
			delay(2500);
			break;
		
	  case 3://三角波
			for(i=255;i>0;i--)
			{
					DAC_PCF(i);
					key_pro();
			}
			break;
		
	  case 4: //正弦波 采用数组采样值 波形更好
			for(i=0;i<255;i++)
			{
				DAC_PCF(sin_num[i]);
				key_pro();
			}
			for(i=255;i>=0;i--)
			{
				DAC_PCF(sin_num[i]);
				key_pro();
			}
			break;
	  default : DAC_PCF(0x00);//否则为0 防错
	}
}

// 转换模数转换后得到的值
void Convert_To_Voltage(uchar val)
{
	Vol_Am = val;
	Vol_Am = Vol_Am*5/255*1000;
	Voltage[4]=(uint)Vol_Am%10+'0';
	Voltage[3]=(uint)Vol_Am/10%10+'0';
	Voltage[2]=(uint)Vol_Am/100%10+'0';
	Voltage[0]=(uint)Vol_Am/1000%10+'0';
}

void dis_pro()
{
	if(mode == 0)
	{
		ISendByte(0x00);
		Recv_Buffer=IRcvByte(); 
		Convert_To_Voltage(Recv_Buffer);
		seg_display((uint)Vol_Am);
	}
	else
	{
		seg_display_One(mode);
		DAC_Wave();
	}
}

void main()
{
	while(1)
	{
		key_pro();
		dis_pro();
	}
}

仿真图2简介:

本系统采用51单片机作为系统的MCU(具体型号见下图),该系统显示器为两个两位数码管,分别显示波形频率和幅度
可显示三种波形,分别是方波、正弦波、三角波。
该设计不支持调节波形的占空比
波形输出通过仿真软件的示波器可以查看得到
系统设计有七个功能按键,其中三个分别是波形选择按键,另外四个按键分别功能是频率加减和幅度加减。
波形发生器的核心芯片是利用DAC0832产生+运放LM358经过放大之后输出
在这里插入图片描述

#include<reg51.h>
#include <math.h>
#define uchar unsigned char
#define uint unsigned int
uchar code tab1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar code tab2[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};	//  带小数点的0-9

uchar ds[]={135,145,158,167,176,188,199,209,218,226,234,240,245,249,252,254,254,253,251,247,243,237,230,222,213,204,193,182,170,158,
146,133,121,108,96,84,72,61,50,41,32,24,17,11,7,3,1,0,0,2,5,9,14,20,28,36,45,55,66,78,90,102,114,128};
uchar code sin_param[64]={135,145,158,167,176,188,199,209,218,226,234,240,245,249,252,254,254,253,251,247,243,237,230,222,213,204,193,182,170,158,
146,133,121,108,96,84,72,61,50,41,32,24,17,11,7,3,1,0,0,2,5,9,14,20,28,36,45,55,66,78,90,102,114,128};

uchar code Triangle[64]={0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,144,152,160,168,176,184,192,200,208,216,224,232,240,248,
248,240,232,224,216,208,200,192,184,176,168,160,152,144,136,128,120,112,104,96,88,80,72,64,56,48,40,32,24,16,8,0};

uchar flag=1,time=0,sum=0,timer=0;
unsigned long frequency=10,volt=50,chuzhi=20000;
double acc=1;
uint  SH=0xff,SL=0x38,SQH=0xb1,SQL=0xe0;
sbit key1=P2^0;
sbit key2=P2^1;
sbit key3=P2^2;  //  三种波按钮
sbit key4=P2^3;	 //  频率-
sbit key5=P2^4;	 //  频率+
sbit key6=P2^5;	 //  幅值+
sbit key7=P2^6;	 //  幅值-
sbit fsw=P3^4;
sbit fgw=P3^5;
sbit vgw=P3^6;
sbit vxw=P3^7;


 void delay()
{
  uchar i;
  for(i=0;i<125;i++)
  ;
}


void init_ST()
{
  uint schuzhi;
  schuzhi=(15625/frequency);
  SH=(65536-schuzhi)/256;
  SL=(65536-schuzhi)%256;
  
}
void init_Sq()
{
  if(frequency>=8)
    chuzhi=500000/frequency;
  else
    chuzhi=50000/frequency;
  SQH=(65536-chuzhi)/256;
  SQL=(65536-chuzhi)%256;

}



void display()
{
  fsw=0;
  P0=tab1[frequency/10];
  delay();
  P0=0x00;
  fsw=1;
  fgw=0;
  P0=tab1[frequency%10];
  delay();
  P0=0x00;
  fgw=1;
  vgw=0;
  P0=tab2[volt/10];
  delay();
  P0=0x00;
  vgw=1;
  vxw=0;
  P0=tab1[volt%10];
  delay();
  P0=0x00;
  vxw=1;
 
}


 






void main()
{
  TMOD=0X11;
  EA=1;
  IT0=1;
  ET0=1;
  ET1=1;
  EX0=1;
  TH0=0xff;
  TL0=0x38;  //200us
  TH1=(65536-20000)/256;
  TL1=(65536-20000)%256;
  TR0=1; 
  while(1)
  {
   

  	display();
    
  }
}

void  zhongduan0() interrupt 1
{ 
  TH0=SH;
  TL0=SL;
  time++;
  if(time==64)
    time=0;
  if(flag==1)
  {
	sum=ds[time];
	P1=sum;
    
  }
  if(flag==2)
  {
	sum=ds[time];
	P1=sum;
    
  }
  
  if(flag==3)
  {
	TR0=0;
	TR1=1; 
  }
  
}

void zhongduan1() interrupt 3
{
  
  TH1=SQH;
  TL1=SQL;
  timer++;
  if(flag==3)
  {	
    if(frequency>=8)
	{ 
      sum=0xff*acc;
      if(timer%2==0)
        P1=0x00;
      else
        P1=sum;
    }
	else
	{
	  sum=0xff*acc;
	  if((timer/10)%2==0)
	    P1=0x00;
	  else
	    P1=sum;
	  
	}
	

  }
  if(flag==1||flag==2)
  {
    TR1=0;
	TR0=1;
  }
  if(timer==100)
    timer=0;
	     
	   
    
}
    
   
  

  


void keyscanFV() interrupt 0
{
  uchar i;
  EX0=0;
  delay();
  if(key1==0)
  {
      flag=1;
	  for(i=0;i<64;i++)
	    ds[i]=sin_param[i];
  }
  if(key2==0)
  {
      flag=2;
	  for(i=0;i<64;i++)
	    ds[i]= Triangle[i];
  }

  if(key3==0)
      flag=3;
 

  if (key4==0)
  {
    if(frequency<99)
	{
      frequency++;
	  init_ST();
	  init_Sq();
	}
  }
  else if(key5==0)
  { 
    if(frequency>0)
	{
      frequency--;
	  init_ST();
	  init_Sq();
	}
  }  

仿真图3简介:

本系统采用C51单片机作为系统的MCU,该系统显示器为LCD12864,可实时显示波形的参数情况
可显示四种波形,分别是正弦波 三角波方波锯齿波,且它们的频率范围均是0-400HZ
该设计不支持调节波形的占空比
波形输出通过仿真软件的示波器可以查看得到
波形发生器的核心芯片是利用DAC0832产生+运放UA741经过放大之后输出,可以通过电位器手动调节波形的幅度大小
系统设计有两个功能按键分别是切换波形和频率调节等功能。
在这里插入图片描述

#include <reg52.h>
#include <math.h>
#include <intrins.h>
#include <lcd12864.h>

#define DAC_OUT	P2

sbit change_wave=P3^2;               //改变波形按键
sbit change_rate=P3^3;               //改变频率按键
uchar mode=0,rate=0,delay_time=0,k,p; //为波形发生模块提供中间变量
uchar *which_wave,*which_wave2;                    
uint rate_num;

uchar code Sine_wave[64]=                                    //DA输出对应电压值对应的数字量,正弦波
{
    128,114,102,90,78,66,55,45,36,28,20,14,9,5,2,1,1,1,
    3,7,11,17,24,32,41,50,61,72,84,96,108,121,133,146,
    158,170,182,193,204,213,222,230,237,243,247,251,253,
    254,254,252,249,245,240,234,226,218,209,199,188,176,
    167,158,145,135
};

uchar code Sawtooth_Wave[64]=                                //锯齿波
{
    255,251,247,243,239,235,231,227,223,219,215,210,206,202,
    198,194,190,186,182,178,174,170,166,162,158,154,150,146,
    142,138,134,130,125,121,117,113,109,105,101,97,93,89,85,
    81,77,73,69,61,57,53,49,45,40,36,32,28,24,20,16,12,8,4,0
};

uchar code Square_wave[64]=                                  //方波
{
    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    255,255,255,255,255,255,
};

uchar code Triangular_Wave[64]=                              //三角波
{
    0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128,136,
    144,152,160,168,176,184,192,200,208,216,224,232,240,248,
    248,240,232,224,216,208,200,192,184,176,168,160,152,144,
    136,128,120,112,104,96,88,80,72,64,56,48,40,32,24,16,8,0
};

void wave_delay()                         //波形延时函数
{
    int a,b;
    for(a=1; a>0; a--)
        for(b=122; b>0; b--);
}

void wave_init()             //波形发生模块的初始化(外部中断0、1)
{
    EA=1;
    IT0=1;             //下降沿触发
    EX0=1;
    IT1=1;
    EX1=1;
}

void disp_wave(uchar *wave)   //显示波形函数
{
    uchar page,i;
    uint date;
    select(1);								//选择左屏
    for(i=32; i<64; i++)
    {
        page=7-(wave[i]/4)/8;
        date=7-(wave[i]/4)%8;
        date=pow(2,date);
        setpos(page,i);				//选择行列
        lcd_wdat(date);
    }
    select(2);								//选择右屏
    for(i=0; i<64; i++)
    {
        page=7-(wave[i]/4)/8;
        date=7-(wave[i]/4)%8;
        date=pow(2,date);
        setpos(page,i);				//选择行列
        lcd_wdat(date);
    }
}

void main()
{

    lcd_init();
    clr_screen();
    which_wave=&Sine_wave[0];
    disp_chinese();
    disp_function(chinese_sine);
    disp_rate(400);
    disp_xy();
    disp_wave(which_wave);
    wave_init();
    while(1)
    {
        delay_time=rate;            //rate=0时,12mhz下,为400hz的波形。循环一次的时间为0.00025ms
        DAC_OUT=*(which_wave+k);
        k++;
        if(k==64)
            k=0;
        while(delay_time)
            delay_time--;
    }
}

void int0() interrupt 0    //波形选择中断服务程序
{
    EX0=0;
    wave_delay();
    mode++;
    if(mode==4)
        mode=0;
    switch(mode)
    {
    case 0 :																				//显示正弦波
        which_wave=&Sine_wave[0];
        which_wave2=&chinese_sine[0];
        break;
    case 1 :																				//显示三角波
        which_wave=&Triangular_Wave[0];
        which_wave2=&chinese_triangular[0];
        break;
    case 2 :																				//显示方波
        which_wave=&Square_wave[0];
        which_wave2=&chinese_square[0];
        break;
    case 3 :																				//显示锯齿波
        which_wave=&Sawtooth_Wave[0];
        which_wave2=&chinese_sawtooth[0];
        break;
    }
    wave_delay();
    clr_screen();																		
    disp_chinese();																
    disp_rate(400/rate);
    disp_function(which_wave2);
    disp_xy();
    disp_wave(which_wave);
    while(!change_wave);
    EX0=1;
}

void int1() interrupt 2       //频率选择
{
    EX1=0;
    wave_delay();
    p++;
    if(p==50)
        p=0;
    rate=p;
    wave_delay();
    rate_num=1/((0.000036+0.000006*rate)*64);
    clc_rate();
    disp_rate(rate_num);
    while(!change_rate);
    EX1=1;
}

源文件: http://www.jh-tec.cn/archives/8351

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/16413.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言MFC导出dll回调函数方法详解

如何将回调函数导出来 这一章节主要讲述在导出函数的基础上如何将回调函数导出来。 C程序设计语言&#xff08;第1-3部分&#xff09;&#xff08;原书第4版&#xff09; 京东自营优惠价&#xff1a;&#xffe5;119.1立即抢购 回调函数的应用相信很多C程序猿儿们都不陌生吧…

弘玑Cyclone2022年产品发布会:人人可用的数字化工作平台——弘玑工作易

近日&#xff0c;在弘玑Cyclone“智无边界&#xff0c;数字未来”发布会上&#xff0c;弘玑Cyclone2022年超级自动化系列产品全新亮相&#xff0c;首席产品官贾岿博士带领产品团队以创新技术对新时代语境下的数字生产力进行了全新解读。 本文将为大家分享本次发布会重磅推出的…

为什么要让员工入职流程实现自动化

人和人之间的第一印象非常重要&#xff0c;一段缘分能不能开始&#xff0c;就看第一印象够不够给力了。其实&#xff0c;公司和新员工之间也存在着这样的关系&#xff0c;但也有些许差别。公司对新员工的第一印象&#xff0c;更多是从第一次见面的时候就产生了&#xff0c;而新…

NodeJs实战-待办列表(4)-解决待办事项中文乱码问题

NodeJs实战-待办列表4-解决待办事项中文乱码问题乱码问题在哪里产生的定位乱码问题VSCode 启动 NodeJs 调试模式浏览器中调试JS效果图执行添加执行完成乱码问题在哪里产生的 运行第3节的server.js, 当添加中文待办事项时候&#xff0c;会产生中文乱码问题。乱码可能在以下地方…

一款超好用的开源密码管理器?

程序员宝藏库&#xff1a;https://gitee.com/sharetech_lee/CS-Books-Store DevWeekly收集整理每周优质开发者内容&#xff0c;包括开源项目、资源工具、技术文章等方面。 每周五定期发布&#xff0c;同步更新到 知乎&#xff1a;Jackpop 。 欢迎大家投稿&#xff0c;提交iss…

最新消息:2022高被引科学家名单已公布,都想成为高被引,到底应该怎么做?(附名单)

11月15日&#xff0c;科睿唯安发布了2022年“高被引科学家”名单。该名单旨在遴选全球自然科学和社会科学领域最具影响力的研究人员。入选“高被引科学家”名单&#xff0c;意味着该学者在其所研究领域具有世界级影响力&#xff0c;其科研成果为该领域发展作出了较大贡献。 全球…

百度全景数据采集与分析

1、百度街景是什么 全景是通过将平面数字图像转换为三维空间&#xff0c;从而带来拟真交互体验的地图浏览方式。 全景技术通过专业相机将现实世界的空间场景捕捉下来&#xff0c;利用软件将多幅平面照片拼接合成&#xff0c;并模拟成三维空间的360度全景景观。全景具有真实感强…

127. 单词接龙

127. 单词接龙 字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> … -> sk&#xff1a; 每一对相邻的单词只差一个字母。对于 1 < i < k 时&#xff0c;每个 si 都在 wordList 中。注意&…

linux线程互斥锁

互斥量mutex 大部分情况&#xff0c;线程使用的数据都是局部变量&#xff0c;变量的地址空间在线程栈空间内&#xff0c;这种情况&#xff0c;变量归属单个线程&#xff0c;其他线程无法获得这种变量。 但有时候&#xff0c;很多变量都需要在线程间共享&#xff0c;这样的变量…

基于粒子群优化算法的冷热电联供型综合能源系统运行优化附Matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

JAVA图书管理练习

目录0.前言1.书类(BOOK)1.1 Book1.2 BookList2. User类2.1 user类2.2 AdminUser类2.3 NormalUser类3.Operation类3.1 添加图书3.2 删除图书3.3 查找图书3.4 展示图书3.5 退出系统3.6 借阅图书3.7 归还图书0.前言 1.在学习了面向对象,接口继承等语法后,综合使用这些语法完成一个…

【第九章】vim 程序编辑器

文章目录vi与vimvi的使用范例按键说明一般指令模式可用的按钮说明&#xff1a;光标移动、复制贴上、搜寻取代等一般指令模式切换到编辑模式的可用的按钮说明一般指令模式切换到命令行界面的可用按钮说明vim的暂存盘、救援回复与打开时的警告讯息vi与vim 一、Linux上面的指令都…

Java#12(String中的常用方法)

目录 一.String中的方法substring 1.作用:截取字符串 2.格式:对象名.substring(开始的索引,结束的索引(没写就截到结尾)) 3.返回类型是String,所以要用一个字符串对象来接收 4.特点: 二.String中的办法replace 1.作用:替换字符串中的内容 2.格式:对象名.replace("要…

【面试题】flex布局画色子

1. flex布局 flex属性作用flex-direction设置主轴的方向justify-content设置主轴上的子元素排列方式align-items设置侧轴上的子元素排列方式flex-wrap设置子元素是否换行align-self设置子元素在侧轴的对齐方式 2. 通过flex布局画色子 <!DOCTYPE html> <html lang&qu…

Zotero文献管理软件入门使用方法:软件下载、文献导入、引文插入

本文介绍文献管理软件Zotero的基础使用方法&#xff0c;包括软件下载与安装、文献与PDF导入、在Word中插入参考文献等的方法。 在EndNote文献输出引用格式自定义修改与编辑界面解读&#xff08;https://blog.csdn.net/zhebushibiaoshifu/article/details/115221112&#xff09;…

Mysql、Hive、Sqoop的安装及配置

Mysql的安装及配置 1、查看系统安装的MariaDB rpm -qa|grep mariadb2、删除查询到的MariaDB&#xff0c;这里的mariadb-libs-5.5.68-1.el7.x86_64是通过上一步查出来的 rpm -e --nodeps mariadb-libs-5.5.68-1.el7.x86_643、执行以下命令下载并安装mysql5.7 wget http://de…

蓝桥杯刷题(一)

蓝桥杯刷题1.单词分析2.成绩统计3.最短路4.门牌制作5.数字三角&#xff08;较困难&#xff09;1.单词分析 我本人其实是比较讨厌操作字符的&#xff0c;因为比较麻烦&#xff0c;所以我将字符都用ascll码值表示。例如‘a’97,‘b’98,c‘99’&#xff0c;所以b-a1 #include<…

prometheus学习

指标类型 测量型&#xff08;gauge&#xff09; 这种类型是上下增减的数字&#xff0c;本质上是特定度量的快照。常见的有CPU&#xff0c;内存&#xff0c;磁盘使用率等。对于业务上来说&#xff0c;指标可能是网站上的客户数量。 计数型&#xff08;counter&#xff09; 这…

【Final Project】Kitti的双目视觉里程计(2)重读

1.基础 ​ 纠正一个思想&#xff0c;即要具有模块化的思维&#xff0c;面对整体中模块是不要考虑其他&#xff0c;就仅考虑如何将一个类抽象出来&#xff0c;思考实现怎样的功能。前面的总结学习我认为是错误的学习方法&#xff0c;并不系统。我的目的&#xff1a;借鉴学习别人…

基于移动应用的城市公共气象服务平台的设计与实现

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下&#xff0c;你想解决的问…