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

原创 FPGA技术江湖 2025-01-04 08:30

大侠好,欢迎来到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.11.14更新)

FPGA技术江湖广发江湖帖

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


FPGA技术江湖微信交流群

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


FPGA技术江湖QQ交流群

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

FPGA技术江湖 任何技术的学习就好比一个江湖,对于每一位侠客都需要不断的历练,从初入江湖的小白到归隐山林的隐世高人,需要不断的自我感悟自己修炼,让我们一起仗剑闯FPGA乃至更大的江湖。
评论
  • 在快速发展的能源领域,发电厂是发电的支柱,效率和安全性至关重要。在这种背景下,国产数字隔离器已成为现代化和优化发电厂运营的重要组成部分。本文探讨了这些设备在提高性能方面的重要性,同时展示了中国在生产可靠且具有成本效益的数字隔离器方面的进步。什么是数字隔离器?数字隔离器充当屏障,在电气上将系统的不同部分隔离开来,同时允许无缝数据传输。在发电厂中,它们保护敏感的控制电路免受高压尖峰的影响,确保准确的信号处理,并在恶劣条件下保持系统完整性。中国国产数字隔离器经历了重大创新,在许多方面达到甚至超过了全球
    克里雅半导体科技 2025-01-03 16:10 117浏览
  • 影像质量应用于多个不同领域,无论是在娱乐、医疗或工业应用中,高质量的影像都是决策的关键基础。清晰的影像不仅能提升观看体验,还能保证关键细节的准确传达,例如:在医学影像中,它对诊断结果有着直接的影响!不仅如此,影像质量还影响了:▶ 压缩技术▶ 存储需求▶ 传输效率随着技术进步,影像质量的标准不断提高,对于研究与开发领域,理解并提升影像质量已成为不可忽视的重要课题。在图像处理的过程中,硬件与软件除了各自扮演着不可或缺的基础角色,有效地协作能够确保图像处理过程既高效又具有优异的质量。软硬件各扮演了什么
    百佳泰测试实验室 2025-01-03 10:39 136浏览
  • 车身域是指负责管理和控制汽车车身相关功能的一个功能域,在汽车域控系统中起着至关重要的作用。它涵盖了车门、车窗、车灯、雨刮器等各种与车身相关的功能模块。与汽车电子电气架构升级相一致,车身域发展亦可以划分为三个阶段,功能集成愈加丰富:第一阶段为分布式架构:对应BCM车身控制模块,包含灯光、雨刮、门窗等传统车身控制功能。第二阶段为域集中架构:对应BDC/CEM域控制器,在BCM基础上集成网关、PEPS等。第三阶段为SOA理念下的中央集中架构:VIU/ZCU区域控制器,在BDC/CEM基础上集成VCU、
    北汇信息 2025-01-03 16:01 173浏览
  • 【工程师故事】+半年的经历依然忧伤,带着焦虑和绝望  对于一个企业来说,赚钱才是第一位的,对于一个人来说,赚钱也是第一位的。因为企业要活下去,因为个人也要活下去。企业打不了倒闭。个人还是要吃饭的。企业倒闭了,打不了从头再来。个人失业了,面对的不仅是房贷车贷和教育,还有找工作的焦虑。企业说,一个公司倒闭了,说明不了什么,这是正常的一个现象。个人说,一个中年男人失业了,面对的压力太大了,焦虑会摧毁你的一切。企业说,是个公司倒闭了,也不是什么大的问题,只不过是这些公司经营有问题吧。
    curton 2025-01-02 23:08 289浏览
  • 光耦合器,也称为光隔离器,是一种利用光在两个隔离电路之间传输电信号的组件。在医疗领域,确保患者安全和设备可靠性至关重要。在众多有助于医疗设备安全性和效率的组件中,光耦合器起着至关重要的作用。这些紧凑型设备经常被忽视,但对于隔离高压和防止敏感医疗设备中的电气危害却是必不可少的。本文深入探讨了光耦合器的功能、其在医疗应用中的重要性以及其实际使用示例。什么是光耦合器?它通常由以下部分组成:LED(发光二极管):将电信号转换为光。光电探测器(例如光电晶体管):检测光并将其转换回电信号。这种布置确保输入和
    腾恩科技-彭工 2025-01-03 16:27 155浏览
  • Matter加持:新世代串流装置如何改变智能家居体验?随着现在智能家庭快速成长,串流装置(Streaming Device,以下简称Streaming Device)除了提供更卓越的影音体验,越来越多厂商开始推出支持Matter标准的串流产品,使其能作为智能家庭中枢,连结多种智能家电。消费者可以透过Matter的功能执行多样化功能,例如:开关灯、控制窗帘、对讲机开门,以及操作所有支持Matter的智能家电。此外,再搭配语音遥控器与语音助理,打造出一个更加智能、便捷的居家生活。支持Matter协议
    百佳泰测试实验室 2025-01-03 10:29 140浏览
  • 在测试XTS时会遇到修改产品属性、SElinux权限、等一些内容,修改源码再编译很费时。今天为大家介绍一个便捷的方法,让OpenHarmony通过挂载镜像来修改镜像内容!触觉智能Purple Pi OH鸿蒙开发板演示。搭载了瑞芯微RK3566四核处理器,树莓派卡片电脑设计,支持开源鸿蒙OpenHarmony3.2-5.0系统,适合鸿蒙开发入门学习。挂载镜像首先,将要修改内容的镜像传入虚拟机当中,并创建一个要挂载镜像的文件夹,如下图:之后通过挂载命令将system.img镜像挂载到sys
    Industio_触觉智能 2025-01-03 11:39 113浏览
  • 前言近年来,随着汽车工业的快速发展,尤其是新能源汽车与智能汽车领域的崛起,汽车安全标准和认证要求日益严格,应用范围愈加广泛。ISO 26262和ISO 21448作为两个重要的汽车安全标准,它们在“系统安全”中扮演的角色各自不同,但又有一定交集。在智能网联汽车的高级辅助驾驶系统(ADAS)应用中,理解这两个标准的区别及其相互关系,对于保障车辆的安全性至关重要。ISO 26262:汽车功能安全的基石如图2.1所示,ISO 26262对“功能安全”的定义解释为:不存在由于电子/电气系统失效引起的危害
    广电计量 2025-01-02 17:18 218浏览
  • 自动化已成为现代制造业的基石,而驱动隔离器作为关键组件,在提升效率、精度和可靠性方面起到了不可或缺的作用。随着工业技术不断革新,驱动隔离器正助力自动化生产设备适应新兴趋势,并推动行业未来的发展。本文将探讨自动化的核心趋势及驱动隔离器在其中的重要角色。自动化领域的新兴趋势智能工厂的崛起智能工厂已成为自动化生产的新标杆。通过结合物联网(IoT)、人工智能(AI)和机器学习(ML),智能工厂实现了实时监控和动态决策。驱动隔离器在其中至关重要,它确保了传感器、执行器和控制单元之间的信号完整性,同时提供高
    腾恩科技-彭工 2025-01-03 16:28 159浏览
  • 物联网(IoT)的快速发展彻底改变了从智能家居到工业自动化等各个行业。由于物联网系统需要高效、可靠且紧凑的组件来处理众多传感器、执行器和通信设备,国产固态继电器(SSR)已成为满足中国这些需求的关键解决方案。本文探讨了国产SSR如何满足物联网应用的需求,重点介绍了它们的优势、技术能力以及在现实场景中的应用。了解物联网中的固态继电器固态继电器是一种电子开关设备,它使用半导体而不是机械触点来控制负载。与传统的机械继电器不同,固态继电器具有以下优势:快速切换:确保精确快速的响应,这对于实时物联网系统至
    克里雅半导体科技 2025-01-03 16:11 162浏览
  • 本文继续介绍Linux系统查看硬件配置及常用调试命令,方便开发者快速了解开发板硬件信息及进行相关调试。触觉智能RK3562开发板演示,搭载4核A53处理器,主频高达2.0GHz;内置独立1Tops算力NPU,可应用于物联网网关、平板电脑、智能家居、教育电子、工业显示与控制等行业。查看系统版本信息查看操作系统版本信息root@ido:/# cat /etc/*releaseDISTRIB_ID=UbuntuDISTRIB_RELEASE=20.04DISTRIB_CODENAME=focalDIS
    Industio_触觉智能 2025-01-03 11:37 137浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦