源码系列:基于FPGA的数模转换(DA)设计

原创 FPGA技术江湖 2024-04-08 08:10

大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。


今天给大侠带来基于FPGA的数模转换(DA)设计,附源码,获取源码,请在“FPGA技术江湖”公众号内回复“ 数模转换设计源码”,可获取源码文件。话不多说,上货。


设计背景: 


数模转换器(Digital to Analog Converter)即DAC,是数字世界和模拟世界之间的桥梁。人类生活在模拟世界中,虽然数字器件及设备的比重日益增强,但是DAC的发展仍是必不可少的。从航空航天、国防军事到民用通信、多媒体、数字信号处理等都涉及到DAC应用。DAC基本上由4个部分组成,即权电阻网络、运算放大器、基准电源和模拟开关。它是一种将二进制数字量形式的离散信号转换成以参考电压为基准的模拟量的转换器。

 

设计原理: 



本设计采用串行数/模转换芯片TLC5620,TLC5620是一个拥有四路输出的数/模转换器,时钟频率最大可达到1MHz。TLC5620芯片接口如下:


该芯片主要有以下特点:四通道8位电压输出DA转换器、5V单电源供电、串行接口、高阻抗基准输入、可编程1或2输出范围、同时更新设备、内部上电复位、低功耗、半缓冲输出。该芯片主要应用于:可编程电源、数字控制放大器/误差器、移动通信、自动测试设备、研发过程检测和控制和信号合成等。

芯片接口功能表如下:


转换公式:V = REF*(CODE/256)* (1+RNG)

V:实际电压;REF:基准电压;CODE:输入8位数据;RNG:范围。

TLC5620的接口时序如下列图所示:

图1 LOAD控制更新(LDAC为低电平)

 

图2 LDAC控制更新(LDAC为低电平)

 


图3 LOAD控制更新(使用8位串行数据,LOAD为低电平)

 

图4 LDAC控制更新(使用8位串行数据)


如图1所示:当LOAD为高电平时,数据在CLK的下降沿被锁存至DATA,只要所有数据被锁存,则将LOAD拉低,将数据从串行输入寄存器传送到所选择的DAC。如图2所示:串行编程期间LDAC为高电平,数据在LOAD为低电平时进行锁存,当LDAC变为低电平时传送至DAC输出。如图3、4所示:输入数据最高位(MSB)在前,数据传输使用两个8个时钟周期。

在本设计中运用的是图1的工作时序:


数据通道选择:


RNG:控制DAC输出范围。当RNG为低时,输出范围在基准电压和GND之间;当RNG为高时,输出范围为两倍的基准电压和GND。


设计架构


本设计驱动TLC5620将输入的数字量转换为实际的模拟量(电压),通过四个按键控制四路输出的电压变化,每按一次,电压值也随之上升,同时在数码管上也依次显示相应的值(依次为A1,A0,RNG,输入DATA)。本设计采用的开发板的基准电压为2.5V。设计架构图如下所示:


key_test模块通过四个按键输入的值,组合输出两个数据,11位的wr_data是TLC_DA模块解码所需的数据。20位的out_data是seg_num模块数码管显示所需的数据。


设计代码


顶层top模块代码如下:

module top(    //顶层模块:将各个模块组合//外部接口  input         clk,   //系统时钟50MHz   input         rst_n, //低电平复位  input   [3:0] key,   //四个按键组成的按键信号,低电平有效
output da_data,//DA串行接口数据 output da_clk, //DA串行接口时钟 output da_ldac,//DA更新信号 output da_load, //DA串行接口加载控制信号 output [7:0] seg, //数码管段选 output [2:0] sel //数码管位选); //内部信号:模块内部的接口信号,比如模块TLC_DA的输出信号data_in,通过内部信号r_data与模块key_test的输入信号wr_data相连 wire [10:0] wr_data; wire [19:0] out_data; //输入给数码管的数据
//模块例化 TLC_DA TLC_DA_inst( //输入数字量转换为模拟量模块 .clk(clk), .rst_n(rst_n), .da_clk(da_clk), .da_data(da_data), .da_ldac(da_ldac), .da_load(da_load), .data_in(wr_data) );
key_test key_test_inst( //按键控制模块 .clk(clk), .rst_n(rst_n), .key(key), .wr_data(wr_data), .out_data(out_data) );
seg_num seg_num_inst( //数码管显示模块 .clk(clk), .rst_n(rst_n), .data_in(out_data), .seg(seg), .sel(sel) );
endmodule


key_test模块代码如下:

module key_test(     //按键控制模块//端口信号:模块的输入输出接口  input           clk,       //50MHZ  input           rst_n,     //低电平复位  input  [3:0]    key,       //四个按键组合信号
output [10:0] wr_data, //输出一帧数据,为DA模块的输入数字量 output [19:0] out_data //输出数码管显示数据 );
//计数器时钟分频 reg [30:0] cnt; reg clk_r; //分频时钟:在消除抖动的时钟频率下进行按键的检测 always@(posedge clk or negedge rst_n) //按键消抖,时间为0.2s进行一次检测 if(!rst_n) begin cnt <= 0; clk_r <= 0; end else if(cnt < 30'd1000_0000) cnt <= cnt + 1'b1; else begin cnt <= 0; clk_r <= ~clk_r; end
//按键为低电平有效,当检测到对应按键之后,相应数值加1,并显示相应的通道 reg [7:0] data; //按键输入数据 reg [1:0] channel; //通道选择 reg [7:0] key1,key2,key3,key4; //相应四个按键 always@(posedge clk_r or negedge rst_n ) if(!rst_n) begin key1 <= 8'h00; key2 <= 8'h00; key3 <= 8'h00; key4 <= 8'h00; data <= 8'h00; channel <= 2'b00; end else case(key) 4'b1110 : begin //按键1:选择通道A,且输入数字量加1 channel <= 2'b00; key1 <= key1 + 1'b1; data <= key1; end 4'b1101 : begin //按键2:选择通道B,且输入数字量加1 channel <= 2'b01; key2 <= key2 + 1'b1; data <= key2; end 4'b1011 : begin //按键3:选择通道C,且输入数字量加1 channel <= 2'b10; key3 <= key3 + 1'b1; data <= key3; end 4'b0111 : begin //按键4:选择通道D,且输入数字量加1 channel <= 2'b11; key4 <= key4 + 1'b1; data <= key4; end default :; endcase
//用赋值语句将需要的数据组合起来,在此例中将RNG默认为1 assign wr_data = {channel,1'b1,data}; assign out_data = {{3'b000,channel[1]},3'b000,channel[0],4'h1,data};
endmodule


TLC_DA模块代码如下:
module TLC_DA(    //输入数字量转换为模拟量模块,本实验用TLC5620 //端口信号:模块的输入输出接口  input         clk,   //系统时钟50MHz   input         rst_n, //低电平复位  input [10:0]  data_in, //输入一帧数据    output         da_data, //串行数据接口  output        da_clk,  //串行时钟接口       output reg    da_ldac, //更新控制信号  output reg     da_load  //串行加载控制接口  );
//计数器时钟分频:根据芯片内部的时序要求进行分频 reg [30:0] cnt; wire da_clk_r; //TLC 5620内部时钟信号 always@(posedge clk or negedge rst_n) //满足协议中的时钟要求,在TLC 5620中时钟要求不大于1MHZ if(!rst_n) cnt <= 6'd0; else cnt <= cnt + 1'b1;
assign da_clk_r = cnt[5];
//接收时序状态机 reg [2:0] state; reg [3:0] cnt_da; reg da_data_r; reg da_data_en; //限定da_data,da_clk的有效区域 always@(posedge da_clk_r or negedge rst_n) if(!rst_n) begin state <= 0; cnt_da <= 0; da_load <= 1; da_ldac <= 0; da_data_r <= 1'b1; da_data_en <= 0; end else case(state) 0: state <= 1; 1: begin da_load <= 1; da_data_en <= 1; if(cnt_da <= 10) begin cnt_da <= cnt_da + 1'b1; case(cnt_da) 0: da_data_r <= data_in[10]; 1: da_data_r <= data_in[9]; 2: da_data_r <= data_in[8]; 3: da_data_r <= data_in[7]; 4: da_data_r <= data_in[6]; 5: da_data_r <= data_in[5]; 6: da_data_r <= data_in[4]; 7: da_data_r <= data_in[3]; 8: da_data_r <= data_in[2]; 9: da_data_r <= data_in[1]; 10: da_data_r <= data_in[0]; default:; endcase state <= 1; end else begin cnt_da <= 0; state <= 2; da_data_en <= 0; end end 2: begin da_load <= 0; state <= 3; end 3: begin da_load <= 1; state <= 0; end default: state <= 0; endcase
assign da_data = (da_data_en) ? da_data_r : 1'b1; assign da_clk = (da_data_en)?da_clk_r : 1'b0;
endmodule

seg_num模块代码如下:
module seg_num(      //数码管显示模块:选择数码管0-4共5个数码管显示{A1,A0,RNG,DATA}//端口信号:模块的输入输出接口  input         clk,   //系统时钟50MHz   input         rst_n, //低电平复位  input  [19:0]  data_in, //20位输入数据
output reg [7:0] seg, //数码管段选 output reg [2:0] sel //数码管位选 );
//通过查找表的方式,将相应位的数码管与数据的相应位一一对应 reg [3:0] num; always@(*) case(sel) 4: num = data_in[3:0]; //第五个数码管显示数据的低四位[3:0] 3: num = data_in[7:4]; //第四个数码管显示数据的低四位[7:4] 2: num = data_in[11:8]; //第三个数码管显示数据的低四位[11:8] 1: num = data_in[15:12]; //第二个数码管显示数据的低四位[15:12] 0: num = data_in[19:16]; //第一个数码管显示数据的低四位[19:16] default:; endcase
//通过查找表的方式,将数据与数码管的显示方式一一对应 always@(*) case(num) 0: seg <= 8'hC0; //8'b1100_0000 1: seg <= 8'hF9; //8'b1111_1001 2: seg <= 8'hA4; //8'b1010_0100 3: seg <= 8'hB0; //8'b1011_0000 4: seg <= 8'h99; //8'b1001_1001 5: seg <= 8'h92; //8'b1001_0010 6: seg <= 8'h82; //8'b1000_0010 7: seg <= 8'hF8; //8'b1111_1000 8: seg <= 8'h80; //8'b1000_0000 9: seg <= 8'h90; //8'b1001_0000 default:seg <= 8'hFF; //8'b1111_1111 endcase
//计数器时钟分频:用cnt第10位的变化作为分频时钟 reg [23:0] cnt; always@(posedge clk or negedge rst_n) if(!rst_n) cnt <= 4'd0; else cnt <= cnt + 1'b1; //在分频时钟下,数码管的0-5位依次循环 always@(posedge cnt[10] or negedge rst_n) //分频时钟为2^10/50M if(!rst_n) sel <= 0; else if(sel < 4) sel <= sel + 1'b1; else sel <= 0;


仿真测试


test顶层模块测试代码:
`timescale 1 ns/ 1 ns    //设置仿真时间单位与精度分别为1ns/1ns           //若设为`timescale 1ns/1ps  (#200 就是延时200 ns; 1ps就是仿真的精度)module test;    //测试模块:主要是将激励信号赋相应的值,仿真之后观察波形,验证与实际功能是否一样
//端口信号定义,激励信号为reg型 reg clk; reg rst_n; reg [3:0] key; wire [7:0] seg; wire [2:0] sel;
//模块例化 top top( .clk(clk), .rst_n(rst_n), .key(key), .seg(seg), .sel(sel) );
//初始化激励,以及给相应激励赋值 initial begin clk = 0;rst_n = 0; key = 4'b1111; //在复位阶段,将激励赋初值
#200 rst_n = 1; //在延时200ns后将复位信号置为1
//实现按键1开,关 #500000 key = 4'b1110; #500000 key = 4'b1111;
end
always #10 clk = ~clk; //时钟的表示,即每隔10ns翻转一次,一个周期的时间即为20ns,时钟为1/20ns = 50MHZ
endmodule


仿真图如下:
 


由于仿真时间原因,这里只测试按键1按下时的数码管显示,显示为00100,表示通道A,RNG为1,输入数字量为00。之后实际下板验证,用万用表也可测出输入数字量对应的电压值。

- THE END -

🍁


往期精选 

 
 

【免费】FPGA工程师人才招聘平台

FPGA人才招聘,企业HR,看过来!

系统设计精选 | 基于FPGA的实时图像边缘检测系统设计(附代码)

基于原语的千兆以太网RGMII接口设计

时序分析理论和timequest使用_中文电子版

求职面试 | FPGA或IC面试题最新汇总篇

资料汇总|FPGA软件安装包、书籍、源码、技术文档…(2024.01.06更新)

FPGA就业班,05.04开班,新增课程内容不加价,高薪就业,线上线下同步!

FPGA技术江湖广发江湖帖

无广告纯净模式,给技术交流一片净土,从初学小白到行业精英业界大佬等,从军工领域到民用企业等,从通信、图像处理到人工智能等各个方向应有尽有,QQ微信双选,FPGA技术江湖打造最纯净最专业的技术交流学习平台。


FPGA技术江湖微信交流群

加群主微信,备注姓名+学校/公司+专业/岗位进群


FPGA技术江湖QQ交流群

备注姓名+学校/公司+专业/岗位进群

FPGA技术江湖 任何技术的学习就好比一个江湖,对于每一位侠客都需要不断的历练,从初入江湖的小白到归隐山林的隐世高人,需要不断的自我感悟自己修炼,让我们一起仗剑闯FPGA乃至更大的江湖。
评论
  • 这篇内容主要讨论三个基本问题,硅电容是什么,为什么要使用硅电容,如何正确使用硅电容?1.  硅电容是什么首先我们需要了解电容是什么?物理学上电容的概念指的是给定电位差下自由电荷的储藏量,记为C,单位是F,指的是容纳电荷的能力,C=εS/d=ε0εrS/4πkd(真空)=Q/U。百度百科上电容器的概念指的是两个相互靠近的导体,中间夹一层不导电的绝缘介质。通过观察电容本身的定义公式中可以看到,在各个变量中比较能够改变的就是εr,S和d,也就是介质的介电常数,金属板有效相对面积以及距离。当前
    知白 2025-01-06 12:04 209浏览
  • 每日可见的315MHz和433MHz遥控模块,你能分清楚吗?众所周知,一套遥控设备主要由发射部分和接收部分组成,发射器可以将控制者的控制按键经过编码,调制到射频信号上面,然后经天线发射出无线信号。而接收器是将天线接收到的无线信号进行解码,从而得到与控制按键相对应的信号,然后再去控制相应的设备工作。当前,常见的遥控设备主要分为红外遥控与无线电遥控两大类,其主要区别为所采用的载波频率及其应用场景不一致。红外遥控设备所采用的射频信号频率一般为38kHz,通常应用在电视、投影仪等设备中;而无线电遥控设备
    华普微HOPERF 2025-01-06 15:29 160浏览
  •  在全球能源结构加速向清洁、可再生方向转型的今天,风力发电作为一种绿色能源,已成为各国新能源发展的重要组成部分。然而,风力发电系统在复杂的环境中长时间运行,对系统的安全性、稳定性和抗干扰能力提出了极高要求。光耦(光电耦合器)作为一种电气隔离与信号传输器件,凭借其优秀的隔离保护性能和信号传输能力,已成为风力发电系统中不可或缺的关键组件。 风力发电系统对隔离与控制的需求风力发电系统中,包括发电机、变流器、变压器和控制系统等多个部分,通常工作在高压、大功率的环境中。光耦在这里扮演了
    晶台光耦 2025-01-08 16:03 44浏览
  • 「他明明跟我同梯进来,为什么就是升得比我快?」许多人都有这样的疑问:明明就战绩也不比隔壁同事差,升迁之路却比别人苦。其实,之间的差异就在于「领导力」。並非必须当管理者才需要「领导力」,而是散发领导力特质的人,才更容易被晓明。许多领导力和特质,都可以通过努力和学习获得,因此就算不是天生的领导者,也能成为一个具备领导魅力的人,进而被老板看见,向你伸出升迁的橘子枝。领导力是什么?领导力是一种能力或特质,甚至可以说是一种「影响力」。好的领导者通常具备影响和鼓励他人的能力,并导引他们朝着共同的目标和愿景前
    优思学院 2025-01-08 14:54 47浏览
  • 根据Global Info Research项目团队最新调研,预计2030年全球封闭式电机产值达到1425百万美元,2024-2030年期间年复合增长率CAGR为3.4%。 封闭式电机是一种电动机,其外壳设计为密闭结构,通常用于要求较高的防护等级的应用场合。封闭式电机可以有效防止外部灰尘、水分和其他污染物进入内部,从而保护电机的内部组件,延长其使用寿命。 环洋市场咨询机构出版的调研分析报告【全球封闭式电机行业总体规模、主要厂商及IPO上市调研报告,2025-2031】研究全球封闭式电机总体规
    GIRtina 2025-01-06 11:10 117浏览
  • 根据环洋市场咨询(Global Info Research)项目团队最新调研,预计2030年全球无人机锂电池产值达到2457百万美元,2024-2030年期间年复合增长率CAGR为9.6%。 无人机锂电池是无人机动力系统中存储并释放能量的部分。无人机使用的动力电池,大多数是锂聚合物电池,相较其他电池,锂聚合物电池具有较高的能量密度,较长寿命,同时也具有良好的放电特性和安全性。 全球无人机锂电池核心厂商有宁德新能源科技、欣旺达、鹏辉能源、深圳格瑞普和EaglePicher等,前五大厂商占有全球
    GIRtina 2025-01-07 11:02 115浏览
  • By Toradex 秦海1). 简介嵌入式平台设备基于Yocto Linux 在开发后期量产前期,为了安全以及提高启动速度等考虑,希望将 ARM 处理器平台的 Debug Console 输出关闭,本文就基于 NXP i.MX8MP ARM 处理器平台来演示相关流程。 本文所示例的平台来自于 Toradex Verdin i.MX8MP 嵌入式平台。  2. 准备a). Verdin i.MX8MP ARM核心版配合Dahlia载板并
    hai.qin_651820742 2025-01-07 14:52 101浏览
  • 大模型的赋能是指利用大型机器学习模型(如深度学习模型)来增强或改进各种应用和服务。这种技术在许多领域都显示出了巨大的潜力,包括但不限于以下几个方面: 1. 企业服务:大模型可以用于构建智能客服系统、知识库问答系统等,提升企业的服务质量和运营效率。 2. 教育服务:在教育领域,大模型被应用于个性化学习、智能辅导、作业批改等,帮助教师减轻工作负担,提高教学质量。 3. 工业智能化:大模型有助于解决工业领域的复杂性和不确定性问题,尽管在认知能力方面尚未完全具备专家级的复杂决策能力。 4. 消费
    丙丁先生 2025-01-07 09:25 108浏览
  • 在智能家居领域中,Wi-Fi、蓝牙、Zigbee、Thread与Z-Wave等无线通信协议是构建短距物联局域网的关键手段,它们常在实际应用中交叉运用,以满足智能家居生态系统多样化的功能需求。然而,这些协议之间并未遵循统一的互通标准,缺乏直接的互操作性,在进行组网时需要引入额外的网关作为“翻译桥梁”,极大地增加了系统的复杂性。 同时,Apple HomeKit、SamSung SmartThings、Amazon Alexa、Google Home等主流智能家居平台为了提升市占率与消费者
    华普微HOPERF 2025-01-06 17:23 195浏览
  • 本文介绍编译Android13 ROOT权限固件的方法,触觉智能RK3562开发板演示,搭载4核A53处理器,主频高达2.0GHz;内置独立1Tops算力NPU,可应用于物联网网关、平板电脑、智能家居、教育电子、工业显示与控制等行业。关闭selinux修改此文件("+"号为修改内容)device/rockchip/common/BoardConfig.mkBOARD_BOOT_HEADER_VERSION ?= 2BOARD_MKBOOTIMG_ARGS :=BOARD_PREBUILT_DTB
    Industio_触觉智能 2025-01-08 00:06 84浏览
  • 故障现象一辆2017款东风风神AX7车,搭载DFMA14T发动机,累计行驶里程约为13.7万km。该车冷起动后怠速运转正常,热机后怠速运转不稳,组合仪表上的发动机转速表指针上下轻微抖动。 故障诊断 用故障检测仪检测,发动机控制单元中无故障代码存储;读取发动机数据流,发现进气歧管绝对压力波动明显,有时能达到69 kPa,明显偏高,推断可能的原因有:进气系统漏气;进气歧管绝对压力传感器信号失真;发动机机械故障。首先从节气门处打烟雾,没有发现进气管周围有漏气的地方;接着拔下进气管上的两个真空
    虹科Pico汽车示波器 2025-01-08 16:51 51浏览
  • 村田是目前全球量产硅电容的领先企业,其在2016年收购了法国IPDiA头部硅电容器公司,并于2023年6月宣布投资约100亿日元将硅电容产能提升两倍。以下内容主要来自村田官网信息整理,村田高密度硅电容器采用半导体MOS工艺开发,并使用3D结构来大幅增加电极表面,因此在给定的占位面积内增加了静电容量。村田的硅技术以嵌入非结晶基板的单片结构为基础(单层MIM和多层MIM—MIM是指金属 / 绝缘体/ 金属) 村田硅电容采用先进3D拓扑结构在100um内,使开发的有效静电容量面积相当于80个
    知白 2025-01-07 15:02 139浏览
  • 彼得·德鲁克被誉为“现代管理学之父”,他的管理思想影响了无数企业和管理者。然而,关于他的书籍分类,一种流行的说法令人感到困惑:德鲁克一生写了39本书,其中15本是关于管理的,而其中“专门写工商企业或为企业管理者写的”只有两本——《为成果而管理》和《创新与企业家精神》。这样的表述广为流传,但深入探讨后却发现并不完全准确。让我们一起重新审视这一说法,解析其中的矛盾与根源,进而重新认识德鲁克的管理思想及其著作的真正价值。从《创新与企业家精神》看德鲁克的视角《创新与企业家精神》通常被认为是一本专为企业管
    优思学院 2025-01-06 12:03 152浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦