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

news2025/1/12 18:59:24

单片机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 ;
	    else
	    SDATA=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.coloradmin.cn/o/1524089.html

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

相关文章

P2036 [COCI2008-2009 #2] PERKET

题目描述 Perket 是一种流行的美食。为了做好 Perket&#xff0c;厨师必须谨慎选择食材&#xff0c;以在保持传统风味的同时尽可能获得最全面的味道。你有 &#xfffd;n 种可支配的配料。对于每一种配料&#xff0c;我们知道它们各自的酸度 &#xfffd;s 和苦度 &#xfffd…

安装Pytorch——CPU版本

安装Pytorch——CPU版本 1. 打开pytorch官网2. 选择pip安装pytorch-cpu3.复制安装命令4. 在cmd命令窗口&#xff0c;进入你的虚拟环境4.1 创建虚拟环境4.2 进行安装 5. 安装成功6. 进行测试——如下面步骤&#xff0c;如图6.1 输入 python6.2 输入 import torch6.2 输入 print …

Spring Boot中application配置文件的生效顺序

Spring Boot的一个重要特性就是它的自动配置&#xff0c;这一特性在很大程度上依赖于名称为application的配置文件。本文将详细介绍在Spring Boot中&#xff0c;这些配置文件的加载顺序以及每份文件的应用范围。 文章目录 配置文件的种类配置文件的加载顺序配置文件的环境切换 …

kubernetes学习总结

kubernetes学习大纲 kubernetes的发展历程 Kubernetes的组件和架构 Kubernetes API对象基本组成 Kubernetes中的yml详解1 Kubernetes中的yml详解2 Deployment与Service

运用html相关知识编写导航栏和二级菜单

相关代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><s…

手机网络连接性能API接口:查询手机网络连接性能状态

手机在网状态查询服务是一项非常方便的服务&#xff0c;可以帮助我们随时了解一个手机号码的在网状态。不论是查询自己的手机号码&#xff0c;还是查询他人的手机号码&#xff0c;这个服务都可以帮助我们获取准确的信息。今天&#xff0c;我想和大家介绍一个非常好用的手机在网…

如何遍历map

小王学习录 前言遍历map集合1. 使用for-each循环遍历 entrySet()2. 使用迭代器遍历 entrySet()3. 通过 keySet() 遍历4. 使用迭代器遍历 keySet()5. 仅遍历 values() 如果只关心map中的值而不关心键&#xff0c;可以遍历 values()&#xff1a;6. 使用流(Streams)进行遍历 总结 …

HarmonyOS(鸿蒙)不再适合JS语言开发

ArkTS是鸿蒙生态的应用开发语言。它在保持TypeScript&#xff08;简称TS&#xff09;基本语法风格的基础上&#xff0c;对TS的动态类型特性施加更严格的约束&#xff0c;引入静态类型。同时&#xff0c;提供了声明式UI、状态管理等相应的能力&#xff0c;让开发者可以以更简洁、…

SpringMVC03 基础操作续与几个简单的交互

前文 第一篇 第二篇 基础操作 上篇博客我们知道了如何获取Session内容以及传输数组,json,对象,集合等的传送和获取 这节课我们可以从上篇的结束开始,其实Spring对Session进行了进一步的封装,我们可以使用其他的方式也可以读取和设置Session(更简洁的方式) 1.直接使用HTTPSessio…

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

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

Cloudways搭建WordPress外贸独立站完整教程

现在做个网站不比从前了&#xff0c;搭建网站非常的简单&#xff0c;主要是由于开源的CMS建站系统的崛起&#xff0c;就算不懂编程写代码的人也能搭建一个自己的网站&#xff0c;这些CMS系统提供了丰富的主题模板和插件&#xff0c;使用户可以通过简单的拖放和配置操作来建立自…

【Linux】基础 IO(文件描述符)-- 详解

一、前言 1、文件的宏观理解 文件在哪呢&#xff1f; 从广义上理解&#xff0c;键盘、显示器、网卡、声卡、显卡、磁盘等几乎所有的外设都可以称之为文件&#xff0c;因为 “Linux 下&#xff0c;一切皆文件”。 从狭义上的理解&#xff0c;文件在磁盘&#xff08;硬件&#…

【教学类-44-06】20240318 0-9数字描字帖 A4横版整页(宋体、黑体、文鼎虚线体)

背景需求&#xff1a; 大四班老师要以前的姓名描字帖 【教学类-35-02】20231207大班姓名描字帖&#xff1a;A4单面3*10个姓名&#xff0c;双面共60个名字-CSDN博客文章浏览阅读402次&#xff0c;点赞5次&#xff0c;收藏8次。【教学类-35-02】20231207大班姓名描字帖&#xf…

前端学习之css样式 背景样式、字体样式、列表样式、边框样式、内外边距元素属性的转换

背景样式 html文件 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>背景样式</title><link rel"stylesheet" href"../css/3.1背景样式.css"> </head> <bo…

MyBatis3源码深度解析(十三)MyBatis的核心组件(二)

文章目录 前言4.3 Configuration组件4.3.9 mappedStatements4.3.10 Configuration组件的其它属性 4.4 Executor4.5 MappedStatement4.6 StatementHandler4.7 TypeHandler4.8 ParameterHandler4.9 ResultSetHandler4.10 小结 前言 MyBatis框架的配置信息有两种&#xff0c;一种…

Flutter开发进阶之使用工具效率开发

Flutter开发进阶之使用工具效率开发 软件开发团队使用Flutter开发的原因通常是因为Flutter开发性能高、效率高、兼容性好、可拓展性高&#xff0c;作为软件PM来说主要考虑的是范围管理、进度管理、成本管理、资源管理、质量管理、风险管理和沟通管理等&#xff0c;可以看到Flu…

OpenCV图像相似性及相似度比对算法

背景 在做图像处理或者计算机视觉相关的项目的时候&#xff0c;很多时候需要我们对当前获得的图像和上一次的图像做相似性比对&#xff0c;从而找出当前图像针对上一次的图像的差异性和变化点&#xff0c;这需要用到OpenCV中的一些图像相似性和差异性的比对算法&#xff0c;在O…

Java零基础入门-如何代码模拟斗地主洗牌发牌动作(上)?

一、本期教学目标 掌握map集合常用方法。掌握map集合使用场景。通过map集合实现斗地主洗牌发牌动作。 二、前言 对于双列集合之map集合&#xff0c;它的相关知识点及拓展咱们都已经差不多学完了。接下来&#xff0c;就是带着大家如何灵活运用map进行一个实战教学&#xff0c;…

【方法封装】时间格式化输出,获取请求设备和IP

目录 时间类 1.1 获取当前时间&#xff0c;以特定格式化形式输出 1.2 自定义时间&#xff0c;以特定格式化输出 1.3 获取当前时间&#xff0c;自定义格式化 1.4 自定义时间&#xff0c;自定义格式化 设备类 根据请求头信息&#xff0c;获取用户发起请求的设备 请求IP类 …

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:TabContent)

仅在Tabs中使用&#xff0c;对应一个切换页签的内容视图。 说明&#xff1a; 该组件从API Version 7开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。 子组件 支持单个子组件。 说明&#xff1a; 可内置系统组件和自定义组件&#xff0c;支…