人人范文网 范文大全

基于FPGA的电压表

发布时间:2020-03-03 01:25:28 来源:范文大全 收藏本文 下载本文 手机版

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 and implementation proces s based on VHDL and FPGA were also described.

Key words: digital voltmeter; VHDL; FPGA 引言

在硬件电子电路设计领域中,电子设计自动化(EDA)工具已成为主要的设计手段,而VHDL语言则是EDA的关键技术之一,它采用自顶向下的设计方法,即从系统总体要求出发,自上至下地将设计任务分解为不同的功能模块,最后将各功能模块连接形成顶层模块,完成系统硬件的整体设计。本文用FPGA芯片和VHDL语言设计了一个数字电压表,举例说明了利用VHDL语言实现数字系统的过程。

1.系统组成及工作原理

整个数字电压表的硬件结构如图1所示。

系统的核心电路由FPGA完成,本设计选用了Altera公司的EPlKl00QC208-3芯片,用VHDL语言对它进行设计,实现三大功能模块:(1)控制模块,激活A/D转换器动作、接收A/D转换器传递过来的数字转换值;(2)数据处理模块,将接收到的转换值调整成对应的数字信号;(3)扫描、显示模块,产生数码管的片选信号,并将数值处理模块输出的BCD码译成相应的7段数码驱动值。

工作时,系统按一定的速率采集输入的模拟电压,经ADC0804转换为8位数字量,此8位数字量经FPGA处理得到模拟电压的数字码,再输入数码管获得被测电压的数字显示。

此电压表的测量范围:0~5V,三位数码管显示。

2.FPGA功能模块的设计

数字电压表的三大模块都是用VHDL语言编程实现的。 2.1控制模块

用状态机作法,产生ADC0804的片选信号、读/写控制信号,通过状态信号INTR判断转换是否结束;转换结束后将转换数据锁存并输出。其状态转换图如图2所示。

State machine viewer

A/D模块如下:

2.2数据处理模块

ADC0804是8位模数转换器,它的输出状态共有28=256种,如果输入信号Vin为0~5V电压范围,则每两个状态值为5/(256-1),约为0.0196V,故测量分辨率为0.02V。常用测量方法是:当读取到DB7~DB0转换值是XXH时,电压测量值为U≈XXH×0.02V;考虑到直接使用乘法计算对应的电压值将耗用大量的FPGA内部组件,本设计用查表命令来得到正确的电压值。

在读取到ADC0804的转换数据后,先用查表指令算出高、低4位的两个电压值,并分别用12位BCD码表示;接着设计12位的BCD码加法,如果每4位相加结果超过9需进行加6调整。这样得到模拟电压的BCD码。

CBD模块如下:

本模块的功能仿真结果如图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段数码驱动值,送数码管显示。

2.4 3选1 数据选择器模块

下图是3选1 数据选择器模块,由sel来选择数据输出,sel的三个状态分别对应选中三个数据A,B,C,同时将选中的数据输出。

2.5位选信号产生器(3进制计数器)

位选信号产生器,实际上时一个3进制计数器,随着时钟的上升沿的到来,它始终在0,1,2之间来回的循环,它的输出作为3选1 数据选择器模块和小数点产生器的输入。以下是仿真和模块。

位选信号产生器的模块:

2.6 7段译码

将输入的数据通过译码电路在数码管上显示出来 7段译码的模块:

2.7小数点产生器

当if selDP=\"10\" then DPout

elsif

selDP=\"01\" then DPout

selDP=\"00\" then DPout

小数点产生器模块:

3.顶层文件的模块如下图:

4.仿真结果

在Quartus II 8.0中,仿真波形如图所示:

5.心得体会

从这次的课程设计中,我受益匪浅。电压表的设计,用EDA仿真工具Quartus II 8.0,用vhdl语言设计,这些对于我们初学者来说,并不是件容易的事情,但是同时巩固了我们对知识的深刻理解。为以后的FPGA设计打下了坚实的基础。所以,总的来说,过程是困难的,不容易的,结果却是很满意的,获得了很宝贵的知识和经验!

6.结束语

本文设计的VHDL语言程序已在Quartus II 8.0工具软件上进行了编译、仿真和调试。经过实验验证,本设计是正确的,其电压显示值误差没有超过量化台阶上限(0.02V)。本文给出的设计思想也适用于其他基于PLD芯片的系统设计。

参考文献

[1]潘松 EDA技术实用教程[M]。北京:科学出版社,2003.[2]卢毅 VHDL与数字电路设计[M]。北京:科学出版社,2001.[3]林敏 VHDL数字系统设计与高层次综合[M]。北京:电子工业出版社,2001.[ 4 ] http://www.edacn.net/bbs/index.php [5 ]齐洪喜,陆颖 VHDL电路设计实用教程[M]。 北京:清华大学出版社,2004 数字电压表设计 VHDL程序如下: A/D0809 LIBRARY ieee;

use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity ad is

port(ST,eoc:in std_logic;

--控制端口

d:in std_logic_vector(7 downto 0);

oe,sta,ale,adda:out std_logic;

q:out std_logic_vector(7 downto 0)); end ad; architecture a of ad is type states is(st0,st1,st2,st3,st4,st5,st6);

--7个状态 signal c_state,n_state:states :=st0; signal regl:std_logic_vector(7 downto 0); signal lock:std_logic; begin adda

case c_state is

when st0=>ale

n_state

when st1=>ale

n_state

when st2=>ale

n_state

when st3=>ale

if(eoc=\'1\') then n_state

else n_state

――eoc为‘1’转换结束 进入下一状态

end if;

――否则 继续转换

when st4=>ale

n_state

when st5=>ale

n_state

when st6=>ale

n_state

when others=>n_state

end case; end proce com; reg:proce(st)

begin

if(st\'event and st=\'1\') then

c_state

end if; end proce reg; lo:proce(lock)

--锁存 begin

if(lock\'event and lock=\'1\') then

regl

end if; end proce lo;

q

end a;

BCD 8位转12 LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY BCD IS PORT (V:IN STD_LOGIC_VECTOR(7 DOWNTO 0);

HB,LB:BUFFER STD_LOGIC_VECTOR(11 DOWNTO 0);

BVALUE:BUFFER STD_LOGIC_VECTOR(11 DOWNTO 0);

BCD_L,BCD_M,BCD_H:OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END BCD; ARCHITECTURE A OF BCD IS BEGIN P1:PROCESS(V(7 DOWNTO 4))

BEGIN

--A/D输出高4位转换

分辨率0.32V

IF V(7 DOWNTO 4)=\"1111\" THEN HB

--4.80V

ELSIF V(7 DOWNTO 4)= \"1110\" THEN HB

ELSIF V(7 DOWNTO 4)= \"1101\" THEN HB

ELSIF V(7 DOWNTO 4)= \"1100\" THEN HB

ELSIF V(7 DOWNTO 4)= \"1011\" THEN HB

ELSIF V(7 DOWNTO 4)= \"1010\" THEN HB

ELSIF V(7 DOWNTO 4)= \"1001\" THEN HB

ELSIF V(7 DOWNTO 4)= \"1000\" THEN HB

ELSIF V(7 DOWNTO 4)= \"0111\" THEN HB

ELSIF V(7 DOWNTO 4)= \"0110\" THEN HB

ELSIF V(7 DOWNTO 4)= \"0101\" THEN HB

ELSIF V(7 DOWNTO 4)= \"0100\" THEN HB

ELSIF V(7 DOWNTO 4)= \"0011\" THEN HB

ELSIF V(7 DOWNTO 4)= \"0010\" THEN HB

ELSIF V(7 DOWNTO 4)= \"0001\" THEN HB

ELSIF V(7 DOWNTO 4)= \"0000\" THEN HB

ELSE HB

--0.00V

END IF;

END PROCESS P1; P2:PROCESS(V(3 DOWNTO 0))

BEGIN

--A/D输出低4位转换 分辨率0.02V

IF V(3 DOWNTO 0)= \"1111\" THEN LB

--0.30V

ELSIF V(3 DOWNTO 0)= \"1110\" THEN LB

ELSIF V(3 DOWNTO 0)= \"1101\" THEN LB

ELSIF V(3 DOWNTO 0)= \"1100\" THEN LB

ELSIF V(3 DOWNTO 0)= \"1011\" THEN LB

ELSIF V(3 DOWNTO 0)= \"1010\" THEN LB

ELSIF V(3 DOWNTO 0)= \"1001\" THEN LB

ELSIF V(3 DOWNTO 0)= \"1000\" THEN LB

ELSIF V(3 DOWNTO 0)= \"0111\" THEN LB

ELSIF V(3 DOWNTO 0)= \"0110\" THEN LB

ELSIF V(3 DOWNTO 0)= \"0101\" THEN LB

ELSIF V(3 DOWNTO 0)= \"0100\" THEN LB

ELSIF V(3 DOWNTO 0)= \"0011\" THEN LB

ELSIF V(3 DOWNTO 0)= \"0010\" THEN LB

ELSIF V(3 DOWNTO 0)= \"0001\" THEN LB

ELSIF V(3 DOWNTO 0)= \"0000\" THEN LB

ELSE LB

--0V

END IF; END PROCESS P2;

BVALUE

BEGIN

JJ:=BVALUE;

IF (JJ(3 DOWNTO 0)>\"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

BCD_M

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 is begin

proce(sel) begin

if

sel=\"10\" then Mselout

elsif

sel=\"01\" then Mselout

elsif

sel=\"00\" then Mselout

else null;

end if; end proce; 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

proce(clk,clr) begin if(clr=\'0\')then qout

qout

if(qout=2)then qout

end if; end if; end proce; end behave;

7段译码

LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all; ENTITY del7 IS PORT ( input : IN STD_LOGIC_vector(3 downto 0);

output : OUT

STD_LOGIC_vector(6 downto 0) ); END del7; ARCHITECTURE a OF del7 IS

BEGIN PROCESS (input) BEGIN

CASE input IS

WHEN \"0000\" =>output

WHEN \"0001\" =>output

WHEN \"0010\" =>output

WHEN \"0011\" =>output

WHEN \"0100\" =>output

WHEN \"0101\" =>output

WHEN \"0110\" =>output

WHEN \"0111\" =>output

WHEN \"1000\" =>output

WHEN \"1001\" =>output

WHEN OTHERS=>NULL;

END CASE; end proce;

END a;

小数点产生器

LIBRARY ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; entity DP is port(SELDP:in std_logic_vector(1 downto 0);

DPout:out std_logic); end DP; architecture a of DP is begin

proce(selDP) begin

if

selDP=\"10\" then DPout

elsif

selDP=\"01\" then DPout

elsif

selDP=\"00\" then DPout

else null;

――小数点DP

end if; end proce; end a;

顶层文件

library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; use ieee.std_logic_arith.all; entity V_WATCH is

port( clkK,EOCC:in std_logic;

DD:IN std_logic_vector(7 downto 0);

clk3,CLR3:IN STD_LOGIC;

OEE,START,ALEE,ADDAA:OUT STD_LOGIC;

DPOUT:OUT STD_LOGIC;

Qoutput:out std_logic_vector(6 downto 0);

Qselout:out std_logic_vector(1 downto 0)); end V_WATCH; architecture a of V_WATCH is

――元件例化 COMPONENT DP port(SELDP:in std_logic_vector(1 downto 0);

DPout:out std_logic); END COMPONENT; COMPONENT del7 PORT(input : IN STD_LOGIC_vector(3 downto 0);

output

: OUT STD_LOGIC_vector(6 downto 0)); END COMPONENT; COMPONENT mux3_1 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 COMPONENT; COMPONENT ad port(st,eoc:in std_logic;

d:in std_logic_vector(7 downto 0);

oe,sta,ale,adda:out std_logic;

q:out std_logic_vector(7 downto 0)); END COMPONENT; COMPONENT C3 PORT (clk,clr: IN STD_LOGIC;

qout: OUT std_logic_vector(1 downto 0)); END COMPONENT; COMPONENT BCD PORT (V:IN STD_LOGIC_VECTOR(7 DOWNTO 0);

HB,LB:BUFFER STD_LOGIC_VECTOR(11 DOWNTO 0);

BVALUE:BUFFER STD_LOGIC_VECTOR(11 DOWNTO 0);

BCD_L,BCD_M,BCD_H:OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END COMPONENT; signal a:

std_logic_vector(1 downto 0); SIGNAL SBCD_L,SBCD_M,SBCD_H: STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL b:

STD_LOGIC_VECTOR(3 DOWNTO 0); SIGNAL q:

STD_LOGIC_VECTOR(7 DOWNTO 0); SIGNAL BBCD:

STD_LOGIC_VECTOR(11 DOWNTO 0);

BEGIN U1:AD

PORT MAP(CLKK,EOCC,DD,OEE,START,ALEE,ADDAA, q); U2:BCD

PORT MAP(q,BCD_L=>SBCD_L,BCD_M=>SBCD_M,BCD_H=>SBCD_H); U3:C3

PORT MAP(CLK3,CLR3,a);

U4:MUX3_1 PORT MAP(SELOUT,SBCD_L,SBCD_M,SBCD_H,DI); U5:DEL7

PORT MAP(b, Qoutput); U6:DP

PORT MAP(a,DPOUT); QSELOUT

电压表名称

电压表教案

物理教案电压表

电压表主程序模块

电压、电压表教案

FPGA学习心得

FPGA学习心得

FPGA教学大纲

FPGA实验报告

个人FPGA学习心得

基于FPGA的电压表
《基于FPGA的电压表.doc》
将本文的Word文档下载到电脑,方便编辑。
推荐度:
点击下载文档
点击下载本文文档