基于51单片机的函数信号发生器

基于51单片机函数信号发生器

(仿真+程序+原理图+设计报告)

功能介绍

具体功能:

1.LCD1602液晶显示波形种类和频率值(10-100HZ);

2.按键设置波形种类和设定频率步进值;

3.电位器器改变振幅(0V-3.5V稳定);

4.本设计可产生正弦波、锯齿波、三角波、矩形波;

5.有四个指示灯分别指示发出的是哪种波形,方便明了;

​演示视频:

基于51单片机的函数信号发生器 

添加图片注释,不超过 140 字(可选)

程序

#include<reg52.h>					   //包含头文件
#include<intrins.h>
#define uchar unsigned char			   //宏定义
#define uint unsigned int
/***公众号:木子单片机****/
sbit s1=P3^5; 						   //定义按键的接口
sbit s2=P3^6;
sbit s3=P3^7;
sbit s4=P3^4;sbit led0=P3^0;							//定义四个LED,分别表示不同的波形
sbit led1=P3^1;
sbit led2=P3^2;
sbit led3=P3^3;sbit lcdrs=P2^7;					   //液晶控制引脚,还有一个控制脚是RW,因为我们只需要向液晶里写数据系那是就好了,所以,我们直接将RW引脚接地
sbit lcden=P2^6;char num,boxing,u;					   //定义全局变量
uchar pinlv=100,bujin=1,bujin1=1;		   //频率初始值是10Hz,步进值默认是0.1,显示步进值变量
uchar code table[]="0123456789";		//定义显示的数组
uchar code table1[]="Fout=     Wave form:";	//初始化显示字符
unsigned int m;				   //定义变量 m
int a,b,h,num1;							//定义全局变量//自定义字符
uchar code zifu[]={		   //此数组内数据为液晶上显示波形符号的自定义字符0x0e,0x11,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x11,0x0e,0x00,	  //正弦波	   0  10x00,0x07,0x04,0x04,0x04,0x04,0x1c,0x00,0x00,0x1c,0x04,0x04,0x04,0x04,0x07,0x00,	  //矩形波	   2  30x00,0x01,0x02,0x04,0x08,0x10,0x00,0x00,0x00,0x10,0x08,0x04,0x02,0x01,0x00,0x00,	  //三角波	   4  50x00,0x01,0x03,0x05,0x09,0x11,0x00,0x00,  	  //锯齿波	   6
};
uchar code sin[64]={	   //此数组内的数据为,da输出对应电压值对应的数字量,0是0V,255是5V 
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 juxing[64]={		//一个周期是采样64个点, 所以数组内是64个数据
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,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
};					  //矩形波取码uchar code sanjiao[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 code juchi[64]={
0,4,8,12,16,20,24,28,32,36,40,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,130,134,138,142,
146,150,154,158,162,166,170,174,178,182,186,190,194,198,202,206,210,215,219,223,227,231,235,239,243,247,251,255
};					  //锯齿波取码void delay(uint xms)	 //延时函数
{int a,b;for(a=xms;a>0;a--)for(b=110;b>0;b--);
}
void write_com(uchar com)		//写命令函数
{lcdrs=0;P0=com;	delay(1);lcden=0;delay(1);						 			  lcden=1;
}void write_date(uchar date)		//写数据函数
{lcdrs=0;P0=date;delay(1);lcden=0;delay(1);lcden=1;
}//自定义字符集
void Lcd_ram()      
{ uint i,j,k=0,temp=0x04; for(i=0;i<7;i++){for(j=0;j<8;j++){write_com(temp+j);write_date(zifu[k]);k++;}temp=temp+8;}
}void init_lcd()					//初始化函数
{uchar i;								  lcden=0;					//默认开始状态为关使能端,见时序图  Lcd_ram();write_com(0x01);			//显示清屏,将上次的内容清除,默认为0x01.write_com(0x0f);write_com(0x38);			//显示模式设置,默认为0x38,不用变。 write_com(0x0c);			//显示功能设置0x0f为开显示,显示光标,光标闪烁;0x0c为开显示,不显光标,光标不闪write_com(0x06);			//设置光标状态默认0x06,为读一个字符光标加1. write_com(0x80);			//设置初始化数据指针,是在读指令的操作里进行的for(i=10;i<20;i++)			   //显示初始化{write_date(table1[i]);		   //显示第一行字符}write_com(0x80+40);			   //选择第二行for(i=0;i<9;i++){write_date(table1[i]);		   //显示第二行字符}write_com(0x80+10);				   //选择第一行第十个位置write_date(0);write_date(1);write_date(0);write_date(1);write_date(0);write_date(1);					   //显示自定义的波形图案write_com(0x80+40+9);		   //选择第二行第九个位置write_date(' ');write_date('1');write_date('0');write_date('.');write_date('0');write_date('H');write_date('z');				   //显示初始的频率值
}
void initclock()			   //定时器初始化函数
{TMOD=0x10;				   //定时器的工作方式TH0=a;TL0=b;					   //定时器赋初值EA=1;					   //打开中断总开关ET0=1;					   //打开定时器允许中断开关TR0=1;					   //打开定时器定时开关
}
void display()				   //显示函数
{uchar qian,bai,shi,ge;	   //定义变量用于显示qian=pinlv/1000;		   //将频率值拆成一位的数据,将数据除以1000,得到的商是一位数,赋值给qianbai=pinlv%1000/100;		   //将频率除以1000的余数再除以100就得到了频率的百位,赋值给baishi=pinlv%1000%100/10;	   //同上,得到频率的十位ge=pinlv%1000/100%10;write_com(0x80+40+9); //选中第二行第九个位置if(qian==0)				   //千位如果为0write_date(' ');		   //不显示else					   //千位不为0write_date(table[qian]);   //正常显示千位if(qian==0&&bai==0)		   //千位和百位都为0write_date(' ');		   //百位不显示else					   //不都为0write_date(table[bai]);	   //百位正常显示write_date(table[shi]);	   //显示十位数write_date('.');		   //显示小数点write_date(table[ge]);	   //显示个位write_date('H');		   //显示频率的单位Hzwrite_date('z');if(boxing==0)			   //判断波形为正弦波{write_com(0x80+10);	   //选中一行频率图案位置write_date(0);		   //显示正弦波图案write_date(1);write_date(0);write_date(1);write_date(0);write_date(1);led3=1;led0=0;					//点亮正弦波指示灯}if(boxing==1)				//注释同上{write_com(0x80+10);write_date(2);write_date(3);write_date(2);write_date(3);write_date(2);write_date(3);led0=1;led1=0;}if(boxing==2){write_com(0x80+10);write_date(4);write_date(5);write_date(4);write_date(5);write_date(4);write_date(5);led1=1;led2=0;}if(boxing==3){write_com(0x80+10);write_date(6);write_date(6);write_date(6);write_date(6);write_date(6);write_date(6);led2=1;led3=0;}
}
void keyscan()					//频率调节键盘检测函数
{if(s1==0)					//加按键是否按下{	 EA=0;					//关闭中断delay(2);			    //延时去抖if(s1==0)				//再次判断{while(!s1);			//按键松开pinlv+=bujin;		//频率以步进值加if(pinlv>1000)		//最大加到100Hz{pinlv=100;		//100Hz}display();			//显示函数m=65536-(15000/pinlv);//计算频率
/*频率值最小是10Hz,pinlv的值是100(因为要显示小数点后一位),150000/100=1500,这个1500就是定时器需要计时的,单位是us,65536-1500得到的是定时器的初值,
先不管初值,先看定时时间,1500us,一个波形的周期是由64个定时组成的,所以,一个波形周期就是64*1500us=96000,也就是96ms,约等
于100ms,也就是10Hz的频率*/a=m/256;			//将定时器的初值赋值给变量b=m%256;EA=1;				//打开中断总开关}}if(s2==0)					//减按键按下{	 delay(5);if(s2==0){EA=0;	while(!s2);pinlv-=bujin;		   //频率以步进值减if(pinlv<100){pinlv=100;}display();m=65536-(15000/pinlv);a=m/256;b=m%256;	EA=1;}}if(s3==0)					 //波形切换按键{	 delay(5);if(s3==0){EA=0;while(!s3);boxing++;			   //波形切换if(boxing>=4)		   //4种波形{boxing=0;}display();EA=1;}}	
}
void bujindisplay()				 //步进值设置界面显示程序
{uint bai,shi,ge;			 //定义步进值 百十个位bai=bujin1/100;				 //将步进值除以100得到百位,也就是频率值的十位,因为有一个小数位shi=bujin1%100/10;			 //将步进值除以100的余数除以十得到十位ge=bujin1%100%10;			 //取余10后得到个位,也就是频率步进值的小数点后一位write_com(0x80+11);			 //选中液晶第一行第十一列if(bai==0)					 //百位是否为0write_date(' ');			 //百位不显示else						 //百位不为0write_date(table[bai]);		 //显示百位数据write_date(table[shi]);		 //显示十位数据write_date('.');			 //显示小数点write_date(table[ge]);		 //显示个位,也就是小数点后一位
}
void bujinjiance()				 //步进值设置键盘程序
{if(s4==0)					 //步进设置按键按下{delay(5);				 //延时去抖if(s4==0)				 //再次判断按键{while(!s4);		 //按键释放,按键松开才继续向下执行h++;				 //变量加if(h==1)			 //进入设置状态时{write_com(0x01);			  //清屏write_com(0x80);			  //初始化显示步进设置界面write_date('S');delay(1);	  //step valuewrite_date('t');delay(1);write_date('e');delay(1);write_date('p');delay(1);write_date(' ');delay(1);write_date('v');delay(1);write_date('a');delay(1);write_date('l');delay(1);write_date('u');delay(1);write_date('e');delay(1);write_date(':');delay(1);bujin1=bujin;				  //步进值赋值给临时变量bujindisplay();			  //显示步进值}if(h==2)						  //退出设置{h=0;						  //清零bujin=bujin1;				  //设置好的临时步进值赋值给步进变量init_lcd();					  //初始化液晶显示initclock();				  //定时器初始化display();					  //调用显示程序}}}if(h==1)								  //设置步进值时{if(s1==0)							  //加按键按下{delay(5);						  //延时去抖if(s1==0)						  //再次判断{while(!s1);					  //按键释放bujin1++;					  //步进值加1if(bujin1>=101)				  //步进值最大100,也就是10.0Hz{bujin1=1;				  //超过最大值就恢复到0.1Hz}bujindisplay();				  //步进显示}}if(s2==0)							  //减按键,注释同上{delay(5);if(s2==0){while(!s2);bujin1--;					  //步进减if(bujin1<=0){bujin1=100;}bujindisplay();}}}
}

硬件设计

使用元器件:

单片机:STC89C52;

(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)

9*15万用板;DAC0832芯片;

LM358芯片;8脚IC座;

20脚IC座;40脚IC座;

100欧姆电阻*2;220欧姆电阻;

5mmLED(红、黄、绿、雾白)*4;

30pf瓷片电容*2;104独石电容*2;

1602液晶;16p母座;

16p排针;4p排针;

103电位器;10k电阻*2;

2.2k电阻*3;1k电阻*2;

103排阻(10k);按键*5;

10uf电解电容;12M晶振;

自锁开关;DC电源插口;

导线:若干;

添加图片注释,不超过 140 字(可选)

流程图:

添加图片注释,不超过 140 字(可选)

设计资料

01仿真图

本设计使用proteus7.8和proteus8.9两个版本设计!具体如图!

添加图片注释,不超过 140 字(可选)

正弦波

添加图片注释,不超过 140 字(可选)

方波

添加图片注释,不超过 140 字(可选)

三角波

添加图片注释,不超过 140 字(可选)

锯齿波

添加图片注释,不超过 140 字(可选)

02原理图

本系统原理图采用Altium Designer19设计,具体如图!

添加图片注释,不超过 140 字(可选)

03程序

本设计使用软件keil5版本编程设计!具体如图!

添加图片注释,不超过 140 字(可选)

04设计报告

一万两千字设计报告,具体如下!

添加图片注释,不超过 140 字(可选)

05设计资料

        资料获取请关注同名公众号,全部资料包括程序(含注释)、仿真源文件 、AD原理图、开题报告、设计报告、结构框图、流程图、实物图、元件清单、讲解视频等。具体内容如下,全网最全! !

 

可以关注下方公众号!

点赞分享一起学习成长。

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

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

相关文章

UE5近战对抗系统Tutorial

文章目录 BP_Character 组合攻击Notify State 检测攻击BP_Character 攻击反馈BP_Character 生命系统BP_Character 死亡效果BP_Character 武器系统BP_Enemy 初始化和行为树 BP_Character 组合攻击 首先我们获取攻击动画&#xff0c;在这里使用的是 Easy Combo Buffering 的攻击…

聊聊JSON

引言 JSON的概念 JSON&#xff08;JavaScript Object Notation&#xff09;是一种轻量级的数据交换格式&#xff0c;它基于JavaScript的一个子集&#xff0c;但独立于语言&#xff0c;这意味着它可以被许多编程语言轻松解析。JSON的简洁性和易读性使其成为Web开发中数据交换的…

掌握 NumPy:高效数组处理综合指南(第 2/2 部分)

照片由 兹比内克布里瓦尔 on Unsplash 一、介绍 欢迎来到我关于 NumPy 的教程的第二部分&#xff01;之前&#xff0c;我们已经介绍了以下列表中的前 7 章。现在在这篇文章中&#xff0c;我们将从第 8 章一直到第 14 章。 Numpy 安装数组初始化Numpy 数组限制计算速度和内存使用…

量子计算:1 从薛定谔的猫开始

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型重新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;则…

基于PHP的民宿管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的民宿管理系统 一 介绍 此民宿管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端jquery.js和echarts.js。系统角色分为用户和管理员。用户可以在线浏览和预订民宿&#xff0c;管理员登录后台进行相关管理等。(在系统…

【python】OpenCV——Color Correction

文章目录 cv2.aruco 介绍imutils.perspective.four_point_transform 介绍skimage.exposure.match_histograms 介绍牛刀小试遇到的问题 参考学习来自 OpenCV基础&#xff08;18&#xff09;使用 OpenCV 和 Python 进行自动色彩校正 cv2.aruco 介绍 一、cv2.aruco模块概述 cv2.…

JAVA小知识28:FIle类文件对象

Java 中的 File 类是 java.io 包中的一个类&#xff0c;用于表示文件和目录路径名的抽象表示。它提供了一些方法来操作文件和目录 一、File的创建 1.1、绝对路径 绝对路径是指从文件系统的根目录开始定位文件或目录的完整路径。它通常以根目录符号开始&#xff0c;在 Window…

【Mac】DMG Canvas for mac(DMG镜像制作工具)软件介绍

软件介绍 DMG Canvas 是一款专门用于创建 macOS 磁盘映像文件&#xff08;DMG&#xff09;的软件。它的主要功能是让用户可以轻松地设计、定制和生成 macOS 上的安装器和磁盘映像文件&#xff0c;以下是它的一些主要特点和功能。 主要特点和功能 1. 用户界面设计 DMG Canva…

Rocky Linux 更换CN镜像地址

官方镜像列表&#xff0c;下拉查找 官方镜像列表&#xff1a;https://mirrors.rockylinux.org/mirrormanager/mirrorsCN 开头的站点。 一键更改镜像地址脚本 以下是更改从默认更改到阿里云地址 cat <<EOF>>/RackyLinux_Update_repo.sh #!/bin/bash # -*- codin…

自研地面站!自主开源无人飞行系统 Prometheus V2 版重大升级详解

自主开源无人飞行系统 Prometheus V2 相对于 Prometheus V1 在多方面做了重大的升级&#xff0c;今天我们将聊聊 Prometheus V2 的地面站升级。 地面站的重大提升 熟悉 Prometheus 的小伙伴们可能知道&#xff0c;V1 版本是没有专门的地面站的。而在 Prometheus V2 中&#x…

VERYCLOUD睿鸿股份亮相亚马逊云科技中国峰会2024

5月30日&#xff0c;为期两天的亚马逊云科技中国峰会在上海世博中心圆满落幕。 多位大咖现场分享&#xff0c;生成式AI时代的数据战略&#xff0c;企业级AI应用&#xff0c;最新技术、产品重磅发布&#xff0c;创新行业解决方案 …… 作为亚马逊云科技的生态合作伙伴&#x…

好大夫在线医生数据医生姓名科室荣誉等202406

好大夫在线医生数据医生姓名科室荣誉等 2024年6月数据&#xff0c;总共934027条数据&#xff0c;可导出为excel,csv等 好大夫在线2024-06月数据 包含简介信息&#xff01; 可见样例数据 样例数据_医生2.xlsx https://www.alipan.com/s/DBEW9MgHEPP 点击链接保存&#xff0…

易宝OA downloadfile 任意文件读取

【产品&&漏洞简述】 易宝OA系统是一种专门为企业和机构的日常办公工作提供服务的综合性软件平台&#xff0c;具有信息管理、 流程管理 、知识管理&#xff08;档案和业务管理&#xff09;、协同办公等多种功能 易宝OA downloadfile 文件读取&#xff0c;攻击者可通过…

【单片机毕业设计选题24019】-基于STM32的安防监测灭火系统

系统功能: 1. 水泵喷水灭火功能&#xff1a;当火焰传感器监测到火焰时&#xff0c;蜂鸣器报警&#xff0c;水泵工作实现灭火。 2. 风扇功能&#xff1a;当烟雾传感器检测到CO或温度传感器检测到温度超过阈值时&#xff0c;蜂鸣器报警&#xff0c; 启动风扇进行驱散烟雾或降温…

毫秒级响应!清科优能应用 TDengine 建设虚拟电厂运营管理平台

小T导读&#xff1a;在清科优能的虚拟电厂运营管理平台建设中&#xff0c;项目初期预计涉及约一万台设备、总数据采集量达数十万&#xff0c;在数据库选择上&#xff0c;其希望能支持至少两千台设备的并发数据处理。本文介绍了清科优能的数据库选型经验以及最终应用效果&#x…

简易人工智能入门

一、监督or非监督 监督学习&#xff08;Supervised Learning&#xff09;&#xff1a;训练集有标记信息&#xff08;Y&#xff09;&#xff0c;学习方式有分类和回归 无监督学习&#xff08;Unsupervised Learning&#xff09;&#xff1a;训练集没有标记信息&#xff0c;学习…

后端实现预览pdf,mp4,图片

PDF预览 /*** pdf预览* param response*/RequestMapping(value "/preview")public void showPdf(HttpServletResponse response) {try {//String filePath this.getClass().getClassLoader().getResource("../../static/pdf/readme.pdf").getPath();Stri…

解决virtualbox虚拟机与主机之间复制粘贴

1、在VirtualBox管理器中设置共享粘贴板和拖放方向为双向 2、在存储中设置使用主机输入输出&#xff08;I/O&#xff09;缓存。 3、在存储→控制器&#xff1a;SATA→***.vdi下勾选固态驱动器 4、在虚拟机→设备→安装增强功能 如果上述操作重启虚拟机后&#xff0c;还不行&am…

【考研408计算机组成原理】数值表示和运算之快速数值转换

苏泽 “弃工从研”的路上很孤独&#xff0c;于是我记下了些许笔记相伴&#xff0c;希望能够帮助到大家 另外&#xff0c;利用了工作之余的一点点时间&#xff0c;整理了一套考研408的知识图谱&#xff0c; 我根据这一套知识图谱打造了这样一个408知识图谱问答系统 里面的每一…

【单片机毕业设计选题24018】-基于STM32和阿里云的农业大棚系统

系统功能: 系统分为手动和自动模式&#xff0c;上电默认为自动模式&#xff0c;自动模式下系统根据采集到的传感器值 自动控制&#xff0c;温度过低后自动开启加热&#xff0c;湿度过高后自动开启通风&#xff0c;光照过低后自动开启补 光&#xff0c;水位过低后自动开启水泵…