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

单片机DDS函数信号发生器设计

该设计以AT89S52为主控芯片,通过控制高性能DDS(直接数字频率合成)芯片AD9834产生不同频率的信号,经过6阶巴特沃兹低通滤波电路,连接数字电位器的运算放大电路,输出信号。可以输出不同频率的正弦波、三角波和方波,使用LCD1602液晶显示屏实时显示输出波形的类型、频率和幅值等信息。

一.引言

函数信号发生器有多种设计方法,本文设计是基于单片机的DDS函数信号发生器。它的基本原理是通过单片机控制DDS芯片产生不同类型、不同频率以及不同幅值的波形信号,这种方法具有精度高、性能稳定的特点,得到了广泛的应用

二.硬件设计

主要包括单片机控制电路、USB供电电路、下载程序电路、按键电路、稳压电路、DDS电路、低通滤波电路、调幅电路以及显示电路。整体设计框图如下图所示。

在这里插入图片描述

1.1 单片机控制电路
采用AT89S52单片机作为控制芯片,图2.2所示为单片机控制电路。按下复位按钮K6,复位脚得到VCC的高电平,单片机复位,按钮松开后,单片机开始工作。时钟电路和单片机内部振荡电路一起构成了单片机的内部时钟方式。
在这里插入图片描述

1.2 DDS电路

设计采用的是ADI公司生产的一款DDS芯片AD9834。AD9834 是一款低功耗、可编程的波形发生器,它不仅能产生正弦波,还能输出三角波和方波,其时钟频率为75MHz,故最大能产生37.5MHz的信号。AD9834输出的正弦波和三角波的频率、相位都可以通过控制芯片进行编程控制,调节简单,本文通过单片机控制AD9834,进行编程控制,输出波形、频率和幅值。
在这里插入图片描述

1.3 滤波电路

由于DDS芯片产生的信号频率并不是纯净的,且由于各种仪器的相互干扰,所以滤波电路就显得极其重要。因为巴特沃斯滤波器有着最平坦的通带幅频特性,根据本设计需求,阶数增高,滤波效果就越好。
在这里插入图片描述

1.4 稳压电路
采用AMS1117-3.3V芯片,将主电路电源5V稳压为3.3V,提供给DDS电路(AD9834电路),使其功耗较低。

在这里插入图片描述
1.5 按键电路
本设计需要通过按键输入所需函数信号的输出波形、频率和幅值,采用独立按键,每个按键占用一个I/O资源口,设计电路简单。按键K1-K5分别连接到单片机AT89S52的P3.2-P3.6引脚,K1是数字按键,可以改变频率值;K2是频率的位选按键;K3是增加幅值按键;K4是减小幅值按键;K5是波形选择按键。
在这里插入图片描述
1.6 调幅电路
由于要使输出波形的幅值可调,所以在DDS的输出端加上一个数字电位器MCP41010和运算放大器AD8065,对运算放大器使用单电源5.0V进行供电,后续6倍放大,数字电位器MCP41010的片选CS、CLK、SI端口分别连接单片机的P1.0、P1.2、P1.3,如下图所示。
在这里插入图片描述
1.7 供电与下载电路
采用自锁开关,USB供电方式,给单片机主电路供电,下载采用ISP在线烧写程序方式。
在这里插入图片描述
1.7 显示电路
显示采用LCD1602液晶实现。液晶显示屏的DB0-DB7端口分别与单片机的P0.0-P0.7连接;RS、RW、E端口分别与单片机的P2.1、P2.2、P2.3连接,通过编写程序在液晶上显示信息,第一行显示幅值“am”,单位是“V”、波形类型,第二行显示频率值和位选信号;引脚VO外接一个2K可调电阻器,可以通过改变其阻值,调节液晶显示屏的亮度。
在这里插入图片描述

二.软件设计

采用模块化设计。 主要优点是:单个模块比起一个完整的程序易编写、调试及修改,程序的易读性好,程序的修改可局部化、模块可以共存,一个模块可以被多个任务在不同条件下调用。
本程序设计主要分为main主函数、AD9834部分、按键部分、LCD1602显示部分。设计流程图如下图所示。
在这里插入图片描述

2.1 AD9834写入数据

AD9834拥有三个标准串行接口,分别是引脚13(SDATA)、引脚 14(SCLK)、引脚14(FSYNC),分别连接单片机P1.3、P1.2和P1.1端口。SCLK是串行时钟输入,为内部时钟,下降沿触发SDATA,16位串行数据字通过端口SDATA输入。当时序时间为SCLK的下降沿时,16位数据被依次被读入AD9834,FSYNC处于低电平时输入有效,当它位于高电平时,数据不能被输入,SDATA更新。所以FSYNC可以被用作片选信号,当FSYNC保持低电平时,新的控制字被写入AD9834中,当FSYNC保持上升沿时,可以从引脚19、引脚20输出信号。
AD9834开始写入16位数据代码:

void AD9834_Write_16Bits(unsigned int Data)	//向AD9834要写入的16位数据
{unsigned char i = 0 ;
SCLK=1;
FSYNC=1;FSYNC=0;  //低电平使数据有效for(i=0 ;i<16 ;i++) {					if(Data & 0x8000)SDATA=1 ;else
SDATA=0 ;					   
SCLK=0;Data <<= 1 ;SCLK=1;} FSYNC=1;
}

2.2 AD9834输出信号
AD9834通过不同的时序控制产生信号,三角波和正弦波采用同一输出端,方波采用单独的输出端。

void AD9834_Select_Wave(unsigned int initdata)
{
FSYNC=1;
SCLK=1;RESET =1;RESET =0;
FSYNC=0;AD9834_Write_16Bits(initdata);//initdata-要输入的命令
}

频率寄存器为28位,每次输入16位数据,从高位到低位输入,设置修改频率程序如下:

void AD9834_Set_Freq(unsigned char freq_chanel, unsigned long freq)	
{unsigned long FREQREG = (unsigned long)(268435456.0/AD9834_SYSTE
M_COLCK*freq);unsigned int FREQREG_LSB_14BIT = (unsigned int)FREQREG;unsigned int FREQREG_MSB_14BIT = (unsigned int)(FREQREG>>14);if(freq_chanel == FREQ_0){  FREQREG_LSB_14BIT &= ~(1U<<15);FREQREG_LSB_14BIT |= 1<<14;FREQREG_MSB_14BIT &= ~(1U<<15);FREQREG_MSB_14BIT |= 1<<14;}else  {  FREQREG_LSB_14BIT &= ~(1<<14);FREQREG_LSB_14BIT |= 1U<<15;FREQREG_MSB_14BIT &= ~(1<<14);FREQREG_MSB_14BIT |= 1U<<15;}AD9834_Write_16Bits(FREQREG_LSB_14BIT);AD9834_Write_16Bits(FREQREG_MSB_14BIT); 
}

CS引脚拉低,才能输入数据,设置幅值程序如下:

void AD9834_AmpSet(unsigned char amp)
{
unsigned char i;
unsigned int temp;
CS=0;
temp =0x1100|amp;
for(i=0;i<16;i++){SCLK=0;AD9834_Delay();if(temp&0x8000)SDATA=1 ;elseSDATA=0 ;
temp<<=1;AD9834_Delay();SCLK=1;AD9834_Delay();}CS=1;
}

2.3 控制部分
该程序部分为主函数部分,主要负责初始化配置单片机、AD9834和LCD1602,通过单片机控制,利用5个按键,设置波形、频率和幅值,控制AD9834输出相应的波形、频率和幅值,将这些参数信息显示在LCD1602液晶屏上。
例如波形键K5设置:按1下波形类型加1,一共3种波形。按1下初始为正弦波,按2下为方波,按3下为三角波,再按一下则为1正弦波,依次循环。以下是显示设置波形主要部分代码。

else if(key5==0)
{ 
WaveModle=WaveModle+1;
if(WaveModle==3)WaveModle=0;
if(WaveModle==1){AD9834_WaveSeting(FreqData,0,SIN_WAVE,0 );DispStrAt("sinWave", 8, 0);}
elseif(WaveModle==0){AD9834_WaveSeting(FreqData,0,TRI_WAVE,0 );Dis
pStrAt("TriWave", 8, 0);}
elseif(WaveModle==2){AD9834_WaveSeting(FreqData,0,SQU_WAVE,0 );Di
spStrAt("SquWave", 8, 0);}		 
while(key5==0);
}	

2.4 显示部分

主函数调用LCD1602显示控制函数,根据指令显示相应的信息,在液晶显示屏LCD1602上进行显示。LCD1602可显示两行数据,每行16个数据。首先根据其指令编码对其进行初始化;LCD1602是一个慢显示,所以对其读写数据需要一定的延时,以待其完全接收;在显示时,首先根据其地址分配,设定第一行的起始位置,再显示第一行的内容。第二行显示同理。
LCD1602主要显示信息程序如下:

void SendToLCD(const uchar data val, bit flag) 
{   bit EAFlag;
uchar timeout = 0xef;EAFlag = EA;
EA = 0; while(LCDisBusy() && --timeout);               RS_LCD = flag;                 RW_LCD = 0;                 DB_LCD = val;               E_LCD= 1;              E_LCD= 0;
EA = EAFlag;
}

三.数据采集及分析

本设计正弦波输出频率为1Hz-10MHz,三角波和方波输出频率为1Hz-5MHz,正弦波和三角波幅值可调,范围是0-3.6V,通过安捷伦示波器测输出信号,进行数据采集并分析。
3.1 正弦波测试
把正弦波输出端接入示波器,以10KHz,100KHz,1MHz,2MHz,3MHz,4MHz,5MHz,6MHz,7MHz,8MHz,9MHz,10MHz作为测试点。
在这里插入图片描述
在这里插入图片描述
从上表可以得到,相对误差:3M时,相对误差为0.33%;8M时,相对误差为1.25% ;9M时,相对误差为1.11% ;10M时,相对误差为1.00% ;其余所测值相对误差均为0,所以,随着频率增加,相对误差稍变大。

3.2 三角波测试
把三角波输出端接入示波器,以10KHz,100KHz,1MHz,2MHz,3MHz,4MHz,5MHz作为测试点。
在这里插入图片描述
从小表可以得出,相对误差:3M时,相对误差为0.33%,其余所测值相对误差为0,所以,实测频率与理论频率相比,误差较小。
但是和正弦波一样,随着频率的增大,幅值在变小,信号衰减,频率越增大,信号衰减的越明显。同样,频率越小,调幅作用越好;频率越增加,幅值误差就会越大,调幅作用也减弱。
在这里插入图片描述
3.3 方波测试
把方波输出端接入示波器,以10KHz,100KHz,1MHz,2MHz,3MHz,4MHz,5MHz作为测试点。
在这里插入图片描述
从下表可以看出,相对误差:2M时,相对误差为1.00%,3M时,相对误差为0.33% ,所以,实测频率误差较小,因为方波是由AD9834芯片的内部比较器产生的,幅值不变,几近为3.44V,占空比不变,为50%。
在这里插入图片描述

四.小结

根据以上正弦波、三角波和方波不同频率的波形图以及实测的频率、幅值等数据,可以得出,正弦波、三角波和方波的频率误差情况,每种波形仅有较少几个理论频率,所测的实测频率存在误差,其余均无。相对误差最大为1.25%,最小为0,所以,实测频率结果较好,误差较小。
但是正弦波和三角波随着频率的增大,幅值在减小,频率越增加,幅值越下降,导致这种情况的原因有:
1、AD9834芯片的自身特性导致的,由于DAC的输出是阶梯状的波形,在频域上表示为Sinc效应,即随着频率的增加,幅度下降;2、运算放大器对输出信号也有一定的衰减。所以,频率小时,调幅作用比较明显,随着越增加,幅值下降越大,调幅作用也减弱。
源设计图及相关程序链接:源程序、PCB图、实物图等

五.附录

设计的电路图、PCB图及相关程序等。

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

理解接口,

关键点 接口可抽象出重要的行为标准&#xff08;用抽象方法来表示&#xff09;。 可以把实现接口的类的对象的引用赋值给接口变量&#xff0c;体 现该类根据接口里的行为标准给出具体行为。 ~接口的思想~&#xff1a;可以要求某些类&#xff08;类的父类可不同&#xff09;有…

监视和内存观察

监视和内存观察 5.监视和内存观察5.1 监视5.2 内存 5.监视和内存观察 在调试的过程中我们&#xff0c;如果要观察代码执行过程中&#xff0c;上下文环境中的变量的值&#xff0c;有哪些方法呢&#xff1f; 这些观察的前提条件一定是开始调试后观察&#xff0c;比如&#xff1…

Python小白笔记

输入 # 一行输入多个数字&#xff0c;空格隔开&#xff0c;存入列表a中 a list(map(int, input().split())) print(a) >>>21 22 34 54 67 >>>[21, 22, 34, 54, 67] 输出 数据&#xff1a; print(%d%10.3f%(x,y)) y的精度为3&#xff0c;宽度为10 %0 …

Oracle 部署及基础使用

1. Oracle 简介 Oracle Database&#xff0c;又名 Oracle RDBMS&#xff0c;简称 Oracle Oracle系统&#xff0c;即是以Oracle关系数据库为数据存储和管理作为构架基础&#xff0c;构建出的数据库管理系统。是目前最流行的客户/服务器&#xff08;client/server&#xff09;或…

SpringTask实现的任务调度与XXL-job实现的分布式任务调度【XXL-Job工作原理】

目录 任务调度 分布式任务调度 分布式任务调度存在的问题以及解决方案 使用SpringTask实现单体服务的任务调度 XXL-job分布式任务调度系统工作原理 XXL-job系统组成 XXL-job工作原理 使用XXL-job实现分布式任务调度 配置调度中心XXL-job 登录调度中心创建执行器和任务 …

测试用例要如何写

1、测试点与测试用例 测试点不等于测试用例&#xff0c;这是我们首先需要认识到的。 问题1&#xff1a;这些测试点在内容上有重复&#xff0c;存在冗余。 问题2&#xff1a;一些测试点的测试输入不明确&#xff0c;不知道测试时要测试哪些。 问题3&#xff1a;总是在搭相似…

【pynput】监控是否打开百度贴吧网页

文章目录 简介Demo 简介 有网友提过一个要求&#xff0c;用 Python 实现一个 电脑打开某网站就自动关机的功能。 想到的思路有两个&#xff1a; 【windows 平台】, 获取活动的窗口标题&#xff0c;如果标题里包含了某些网站名称, 那就使用关机命令 可以定时拉取标题, 也可以使…

滑块验证码

1.这里针对滑块验证给了一个封装的组件verifition&#xff0c;使用直接可以调用 2.组件目录 3.每个文件的内容 3.1 Api文件中只有一个index.js文件&#xff0c;用来存放获取滑块和校验滑块结果的api import request from /router/axios//获取验证图片 export function reqGe…

Docker出现容器名称重复如何解决

假如你的重复容器名称是mysql5 删除已存在的容器&#xff1a;如果你不再需要那个已经存在的名为“mysql5”的容器&#xff0c;你可以删除它。使用下面的命令&#xff1a; docker rm -f mysql5这条命令会强制删除正在运行的容器。一旦容器被删除&#xff0c;你就可以重新使用这个…

Java 面向对象(类与对象 成员方法 方法重载 可变参数 构造方法 / 构造器 this关键字 包 访问修饰符)

目录 一、类与对象1. 类与对象的定义2. 类和对象的内存分配机制 二、成员方法1. 成员方法的定义2. 方法的调用机制3. 成员方法传参机制 三、方法重载四、可变参数1. 基本概念2. 基本语法3. 应用 五、 构造方法 / 构造器1. 特点2. 使用案例3. 对象创建的流程 六、this关键字1. 运…

P6安装:安装P6提示1433端口无效

错误描述 尝试运行 Microsoft SQL Server 2005 的 Primavera P6 数据库时&#xff0c;遇到以下错误&#xff1a; SQLServerException: The TCP/IP connection to the host [name], port 1433 has failed. Error: “Connection refused: connect. Verify the connection prope…

MATLAB的多项式相加

多项式的加减在阶次相同的情况下可直接运算&#xff0c;若两个相加减的多项式阶次不同&#xff0c;则低阶多项式必须用零填补高阶项系数&#xff0c;使其与高阶多项式有相同的阶次。而且通常情况下&#xff0c;进行加减的两个多项 式的阶次不会相同&#xff0c;这时可以自定义一…

视频素材库大全免费无水印必备素材网站,整理分享抖音视频素材剪辑必备

想要做出容易上热门的抖音视频作品&#xff0c;你一定要找到合适的短视频剪辑素材&#xff0c;今天我就给你收集了视频素材库大全免费无水印必备素材网站&#xff0c;都给你提供了海量的短视频素材库大全免费无水印&#xff0c;从风景&#xff0c;美食&#xff0c;动漫&#xf…

从排序算法的艺术看C语言qsort函数的魅力:一场数据的时空穿越

欢迎来到白刘的领域 Miracle_86.-CSDN博客 系列专栏 C语言知识 先赞后看&#xff0c;已成习惯 创作不易&#xff0c;多多支持&#xff01; 目录 一 、回调函数 二、qsort函数 1.qsort函数排序整型数据 2.qsort函数排序结构数据 一 、回调函数 何为回调函数&#xff1…

基于matlab使用 fmincon 函数来进行有约束条件的最小化问题求解

一、一般步骤 生成带有噪声的正态分布数据&#xff1b;定义拟合模型。 model (params, x) normpdf(x, params(1), params(2)); 初始参数猜测 initial_guess [mu, sigma]; 设置约束条件 lb [0, 0]; % 参数的最小值 ub [10, 10]; % 参数的最大值 定义优化问题 opts …

deepseek-coder模型量化

1 简介 DeepSeek-Coder在多种编程语言和各种基准测试中取得了开源代码模型中最先进的性能。 为尝试在开发板进行部署&#xff0c;首先利用llama.cpp对其进行量化。 2 llama.cpp安装 git clone之后进入文件夹make即可&#xff0c;再将依赖补全pip install -r requirements.tx…

【吊打面试官系列】Java虚拟机JVM篇 - 关于双亲委派模型

大家好&#xff0c;我是锋哥。今天分享关于JVM双亲委派模型的JVM面试题&#xff0c;希望对大家有帮助&#xff1b; 什么是双亲委派模型&#xff1f; 双亲委派模型针对的是 Java 虚拟机中三个类加载器的&#xff0c;这三个类加载器分别是&#xff1a; 启动类加载器&#xff08;B…

node.js快速入门-day03

个人名片&#xff1a; &#x1f60a;作者简介&#xff1a;一名大二在校生 &#x1f921; 个人主页&#xff1a;坠入暮云间x &#x1f43c;座右铭&#xff1a;给自己一个梦想&#xff0c;给世界一个惊喜。 &#x1f385;**学习目标: 坚持每一次的学习打卡 文章目录 web服务器创建…

力扣hot100:34. 在排序数组中查找元素的第一个和最后一个位置(二分查找的理解)

我们知道使用二分查找能找到值所在的位置。假如我们在找到值后仍然不断的更新指针会发生什么&#xff1f;我们可以利用这一点来找到最左边的以及最右边的值。 如果当nums[mid]target时&#xff0c;使得 rightmid-1&#xff0c;那么最终会使得target在right的右边。 如果当nums[…

海外媒体宣发套餐推广攻略实现品牌全球化-华媒舍

如今&#xff0c;在全球经济一体化的浪潮下&#xff0c;品牌全球化已成为企业成功的重要因素之一。海外市场作为一个巨大而具有潜力的机会&#xff0c;吸引着越来越多的企业前往探索。而在海外市场的推广过程中&#xff0c;海外媒体宣发套餐成为了重要的推广方式之一。本文将为…