1、 1 FPGA 控制的数字 电压表 电路 设计 李培 ( 河南科技大学电子信息工程学院 河南洛阳 471003) 摘 要: 介绍数字电压表的组成及工作原理,论述了基于 VHDL 语言和 FPGA 芯片的数字系统的设计思想和实现过程。 关键词: 数字电压表; VHDL 语言; FPGA VHDL Realization of Digital Voltmeter Abstract: The composition and working principle of digital voltm eter were introduced in this paper, the designing idea
2、 and implementation proces s based on VHDL and FPGA were also described. Key words: digital voltmeter; VHDL; FPGA 引言 在硬件电子电路设计领域中,电子设计自动化 (EDA)工具已成为主要的设计手段,而VHDL 语言则是 EDA 的关键技术之一,它采用自顶向下的设计方法,即从系统总体要求出发,自上至下地将设计任务分解为不同的功能模块 ,最后将各功能模块连接形成顶层模块,完成系统硬件的整体设计。本文用 FPGA 芯片和 VHDL 语言设计了一个数字电压表,举例说明了利用 VHDL 语言
3、实现数字系统的过程。 1 系统组成及工作原理 整个数字电压表的硬件结构如图 1 所示。 系统的核心电路由 FPGA 完成,本设计选用了 Altera 公司的 EPlKl00QC208-3 芯片,用VHDL 语言对它进行设计,实现三大功能模块: (1)控制模块,激活 A/D 转换器动作、接收A/D 转换器传递过来的数字转换值; (2)数据处理模块,将接收到的转换值调整成对应的数字信号; (3)扫描、显示模块,产生数码管的片选信号,并将数值处理模块输出的 BCD 码译2 成相应的 7 段数码驱动值。 工作时,系统按一定的速率采集输入的模拟电压,经 ADC0804 转换为 8 位数字量,此8 位数字
4、量经 FPGA 处理得到模拟电压的数字码,再输入数码管获得被测电压的数字显示。 此电压表的测量范围: 0 5V,三位数码管显示。 2 FPGA 功能模块的设计 数字电压表的三大模块都是用 VHDL 语言编程实现的。 2.1 控制模块 用状态机作法,产生 ADC0804 的片选信号、读 /写控制信号,通过状态信号 INTR 判断转换是否结束;转换结束后将转换数据锁存并输出。其状态转换图如图 2 所示。 State machine viewer A/D 模 块 如下: 2.2 数据处理模块 ADC0804 是 8 位模数转换器,它的输出状态共有 28=256 种,如果输入信号 Vin 为 05V
5、电压范围,则每两个状态值为 5/(256-1),约为 0.0196V,故测量分辨率为 0.02V。常用测3 量方法是:当读取到 DB7 DB0 转换值是 XXH 时,电压测量值为 U XXH0.02V;考虑到直接使用乘法计算对应的电压值将耗用大量的 FPGA 内部组件,本设计用查表命令来得到正确的电压值。 在读取到 ADC0804 的转换数据后,先用查表指令算出高、低 4 位的两个电压值 ,并分别用 12 位 BCD 码表示;接着设计 12 位的 BCD 码加法,如果每 4 位相加结果超过 9 需进行加 6 调整。这样得到模拟电压的 BCD 码。 CBD 模块 如下: 本模块的功能仿真结果如图
6、 3 所示;当转换数据为 00010101,通过查表高 4 位 0001 是0.32V,而低 4 位 0101 是 0.1V,最后的电压输出结果是 0.32V+0.1V=0.42V,它的 BCD 码表示为 000001000010,仿真结果正确。 2.3 扫描、显示模块 如图 4 所示, CLK是扫描时钟,其频率为 1kHz,由给定的 40MHz 时钟分频得到; DATAIN是数据处理模块输出的电压值的 BCD 码; SEL 是数码管的片选信号; POINT 是数码管小数点驱动;通过扫描分别输出 3 位电压值的 BCD 码 DATAOUT,并通过 DISP 将 BCD 码译成相应的 7 段数码
7、驱动值,送数码管显示。 4 2.4 3 选 1 数据选择器 模块 下 图是 3 选 1 数据选择器 模块,由 sel 来选择数据输出, sel 的三个状态分别对应选中三个数据 A,B,C,同时将选中的数据输出。 2.5 位选信号产生器( 3 进制计数器) 位选信号产生器 ,实际上时一个 3 进制计数器,随着时钟的上升沿的到来,它始终在 0,1, 2 之间来回的循环,它的输出作为 3 选 1 数据选择器 模块 和小数点产生器的输入。 以下是仿真和模块。 位选信号产生器 的模块: 2.6 7 段译码 将 输入的数据通过译码电路在数码 管上显示出来 7 段译码的模块: 5 2.7 小数点产生器 当
8、if selDP=“10“ then DPoutalealealealealealealen_state“1001“) THEN 如果 12 位结果中,低 4 位 JJ:=JJ+“000000000110“; 大于 9 则低 4 位加 6 END IF; IF(JJ(7 DOWNTO 4)“1001“) THEN 如果中间的 4 位大于 9 JJ:=JJ+“000001100000“; 则中 4 位加 6 END IF; BCD_L=JJ(3 DOWNTO 0); BCD_M=JJ(7 DOWNTO 4); BCD_H=JJ(11 DOWNTO 8); END PROCESS P3; END
9、A; 10 3 选 1 数据选择器 LIBRARY ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity mux3_1 is port(sel:in std_logic_vector(1 downto 0); A,B,C:in std_logic_vector(3 downto 0); Mselout:out std_logic_vector(3 downto 0); end mux3_1; architecture a of mux3_1
10、 is begin process(sel) begin if sel=“10“ then Mselout=A; elsif sel=“01“ then Mselout=B; elsif sel=“00“ then Mselout=C; else null; end if; end process; end a; 位选信号产生器( 3 进制计数器) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity c3 is port(clk,clr:in std_logic; qout:buffer std_logic_vector(1 downto 0) ); end c3; architecture behave of c3 is begin process(clk,clr) begin if(clr=0)then qout=“00“; elsif(clkevent and clk=1)then qout=qout+1; if(qout=2)then qout=“00“; end if;