基于FPGA的数字电压表设计.docx
《基于FPGA的数字电压表设计.docx》由会员分享,可在线阅读,更多相关《基于FPGA的数字电压表设计.docx(65页珍藏版)》请在冰豆网上搜索。
基于FPGA的数字电压表设计
基于FPGA数字电压表设计
摘要:
系统基于EDA技术的智能数字电压表实现,以现场可编程门阵列(FPGA)为设计核心,集成于一片Xilinx公司的SpartanⅡE系列XC2S100E-6PQ208芯片上,在ISE环境下采用超高速硬件描述语言(VHDL)模块化编程,实现了电压的数据采集、转换、处理、显示等功能。
本设计的特点在于能够测量的电压范围宽(0~50VDC),主要采用了分压原理,该系统具有集成度高、灵活性强、易于开发和维护等特点。
关键字:
FPGAVHDL数字电压表AD转换
Abstract:
ThesystemaccordingtotheEDAtechnicalachievethedigitalvoltager,ItisbaseonFPGA(FieldProgrammableGateArray),adoptingVHDL(VHSICHardwareDescriptionLanguage)undertheundertheenvironmentofISE.mostofthedesignsgatherintheSpartanⅡEseriesXC2S100E-6PQ208chipoftheXilinxcompany.Thewholedesigniscomposedofthedataprocessingmodule,thecorrespondencechoicemodulek,thekeymoldmoduleandtheA/Dconvertmodule.Itcanbecarryoutthefunctionsuchasconversion,handleanddisplay.Itisacharacteristicthatisthesystemcanbemeasuretherangeofthevoltagefrom0Vto50V,whichmainlyadoptingtheprincipleindividingvoltage.Thesystemhashighaccuracyandstability,itisprovedtoreliableandofhighvalueandfeasibilityaftertesting.
Key–word:
FPGAVHDLDVMADconversion
1系统设计3
1.1控制模块方案的比较3
1.2A/D转换方案的比较4
1.3显示方案的比较4
1.4总体方案设计5
1.5系统的基本原理5
2单元电路设计6
2.1A/D转换部分6
2.1.1ADC0809工作原理6
2.1.2ADC0809工作时序7
2.1.3档位控制电路8
2.2FPGA功能模块的设计8
2.2.1码制变换模块8
2.2.2显示控制及驱动模块9
3软件设计9
3.1开发软件及编程语言简介9
3.2程序流程图9
4系统测试10
4.1测试仪器清单10
4.2测试及误差计算10
参考文献11
附录1程序清单11
1系统设计
1.1控制模块方案的比较
方案一:
采用3位半数字电压表。
采用此方案电路结构简单,易于实现且易于维护。
它的核心器件是一个双积分式A/D转换,双积分式DVM属于V—T变换式,其基本原理是在一个测量周期内,首先将被测电压UX加到积分器的输入端,在确定的时间内进行积分,也称定时积分;然后切断UX,在积分器的输入端加与UX极性相反的电压UR,由于UR一定,所以称为定值积分,但积分方向相反,直到积分输出达到起始电平为止,从而将UX转换成时间间隔进行测量。
只要用计数器累计时间间隔内的脉冲数,即为UX之值。
其原理方框图如图1.1.1所示。
输入信号
图1.1.13位半电压表原理图
方案二:
采用单片机为控制核心。
目前单片机技术比较成熟,功能也比较强大,配合一定的外围电路可实现数字电压表,原理图如图1.1.2所示。
输入信号经AD转换器转换后送到单片机进行数据处理,系统根据不同电压信号计算出不同的数值,并将其显示出来。
采用这种方案优点是呆以依赖地成熟的单片机技术、运算功能较强、软件编程灵活、自由度大、设计成本也较低,能较准确地测量输入电压。
缺点是在传统的单片机设计系统中必须使用许多分立元件组成单片机的外围电路,因此整个系统显得十分复杂,不易于实现。
图1.1.2单片机控制的数字电压表原理图
方案三:
采用FPGA作为系统控制的核心。
现场可编程门阵列(FPGA)将所有器件集成在一块芯片上,体积大大减小、逻辑单元灵活、集成度高以及适用范围广等特点,可实现大规模和超大规模的集成电路,而且编程灵活、调试方便。
综合上述分析,方案三为本设计最佳选择方案。
1.2AD转换方案的比较
方案一:
采用双积分型AD转换器。
双积分型A/D转换器的原理是将输入电压转换成时间(脉冲宽度信号)或频率(脉冲频率),然后由定时器/计数器获得数字值,积分时间常数较大,具有滤波作用,消除了干扰,故双积分A/D转换具有较强的抗干扰能力。
缺点是由于积分过程是个缓慢的过程,转换速度慢。
方案二:
采用逐次比较型AD转换。
这是目前应用十分广泛的集成ADC,逐次比较型AD转换内部电路由一个比较器、DA转换器、时钟、逐次比较寄存器SAR、输出寄存器和控制逻辑电路等部分组成。
具有速度高、功耗低。
输出位数多等特点,其原理图如图1.2.1所示。
图1.2.1逐次比较ADC原理图
经比较,采用逐次比较的A/D转换器
1.3显示器方案的比较
方案一:
采用LED数码管,采用数码管动态显示,数码管具有结构简单、低损耗、寿命长、耐老化、成本低、对外界要求低、易于维护、操作简单,编程简单等优点。
但是也有一个明显的缺点,即显示的信息量非常有限,只能显示几个有限的阿拉伯数字与字母,电路图如图1.3.1所示。
图1.3.八段发光二极管显示器原理结构
方案二:
运用LCD液晶显示,液晶显示屏是以若干个5×8或5×11点阵块组成的显示字符群,每个点阵块为一个字符位.字符间距的行距都为一个点的宽度.采用这种液晶显示功耗低、可靠性高、轻薄短小、辐射小、可视面积大,可以同时显示多种信息。
综上所述,拟定第二种方案,即采用LCD液晶显示电压值及相关信息。
1.4总体方案设计
由上节分析、比较、论证,决定了系统的最终方案:
(1).控制部分:
采用FPGA为控制核心
(2)AD转换部分:
采用逐次逼近(比较)型AD转换器ADC0809;
(3)显示部分:
采用液晶LCD显示
系统基本框图如图1.4所示
电压输入
图1.4系统总体框图
1.5系统的基本原理
测量信号(电压信号)送入AD转换器,控制信号模块发出控制信号,启动A/D的START进行转换,A/D采样得到的数字信号数据在数据处理模块中转换为相应的显示代码,最后经显示译码驱动模块发出控制与驱动信号,推动外部的显示模块(LCD)显示相应的数据。
通过外部的键盘可以对系统进行复位控制和显示档位选择,不同的档位选择不同的输入电压范围(0~5、5~50)。
2单元电路设计
2.1A/D转换部分
2.1.1ADC0809工作原理
ADC0809是一种8位ADC,采用CMOS工艺制成的8位八通道A/D转换器,片内有8路模拟采样开关,可控制8个模拟量中的一个进入转换器中。
其内部结构图和引脚图分别如图2.1.1.1和2.1.1.2所示。
图2.1.1.1ADC0809内部结构
片内有8路开关、模拟开关的地址锁存与译码电路、比较器、256R电阻T型网络、树状电子开关、逐次逼近寄存器SAR、三态输出锁存缓冲储存器、定时和控制电路等。
ADC0809通过引脚IN0,IN1,…,IN7可输入8路单边模拟输入电压。
ALE将3位地址线ADDA,ADDB,ADDC进行锁存。
图2.1.1.2ADC0809引脚图
在ADC0809片内的256R电阻T型网络和电子开关树它相当一个D/A转换器。
它把预测的8位二进制数转换为模拟的电压幅值,送入比较器中与实际电压相比较。
ADC0809主要引脚功能如下:
IN0~IN7:
通道0~7的模拟量输入
D0~7:
数字量输出
ADDC、ADDB、ADDA:
通道(0~7)选择
ALE:
通道地址锁存,正脉冲有效
START:
启动信号,正脉冲有效,上升沿所有寄存器清0,下降沿开始转换
EOC:
转换结束,高电平有效
OE:
允许输出,高民平有效
2.1.2ADC0809的工作时序
ADC0809的工作时序如图2.1.2.1所示。
主要控制信号说明:
,START是转换启动信号,高电平有效;ALE是3位通道选择地址(ADDC、ADDB、ADDA)信号的锁存信号。
当模拟量送至某一输入端,由3位地址信号选择,而地址信号由ALE锁存;EOC是转换情况状态信号,当转换结束后,EOC输出高电平,以示转换结束;在EOC的上升沿后,若使能输出信号OE为高电平,则控制打开三态缓冲器,把转换好的8位数据结果输至数据总线。
至此ADC0809的一次转换结束。
图2.1.2.1ADC0809的工作时序图
2.1.3档位控制电路
为了增加DVM的测量范围,设计了档位选择电路,其主要原理是采用电阻分压,原理上ADC0809有八路数据输入端口,也就是说可以分为八档,为了简化设计,只分了两档(1档,10档)
图2.1.3.1档位控制电路原理图
图中的电位器R25是用来校准的,因为各电阻的值不可能很精确,用电位器来微调校准以保证测量精度。
ADC0809的输入范围为(0—5)V.由于档位的切换是通过程序来控制ADC0809各通道的选通来自动实现的,所以只要输入的电压范围超过5V,则档位自动切换到10档,即选通通道IN1。
当输入电压范围为0~5V时,IN0导通,此时,
UI=U26
而当输入电压范围为5—50V时,FPGA判断选择档位,IN1导通,
此时
UI=U27
即UI=
=
由于ADC0809数字量输出为8位,数字量化范围为0~255,当输入电压为满量程5V时,转换电路对输入电压的分辨能力为
2.2FPGA功能模块的设计
2.2.1码制变换模块
在此码制变换模块DATA_CONVERSION中主要实现的功能是将AD0809采样送来的8位二进制数转换为可被LCD识别的字符型LCD码。
为了达到这一目的,首先要将8位二进制码变换为BCD码,然后再分别进行转换,得到字符型码,并送入译码显示模块。
2.2.2显示控制及驱动模块
电压值的显示可由LCD实现。
本系统选用了一块8×5字符型液晶显示模块LMB162ABA实现了低功耗,而且可带单位双排显示,字体美观大方。
整个电路十分简洁。
系统工作过程首先由FPGA对ADC0809及LCD进行初始化,然后当有输入信号Vi,由FPGA通过接口向ADC0809控制信号控制字,使其对输入的模拟信号进行转换,变为8位的数字信号送到输出端,由FPGA经过码制变换等处理后,再通过与LCD的接口驱动并发送数据。
当ADC0809采样完成后,由码字变换模块将采样数字信号转换为LCD可识别的字符型数据后,送至驱动模块,再由其驱动LCD,将字符型数据送到LCD的D0~D7端,实现显示。
3、软件设计
3.1开发软件及编程语言简介
系统采用硬件描述语言VHDL按模块化方式进行设计,并将各模块集成于FPGA芯片中,然后通过XilinxISE4.2软件开发平台和ModelSimXilinxEdition5.3dXE仿真工具,对设计文件自动地完成逻辑编译、逻辑化简、综合及优化、逻辑布局布线、逻辑仿真,最后对FPGA芯片进行编程,实现系统的设计要求。
采用VHDL(VeryHighSpeedIntegratedCircuitHardwareDescriptiponLanguage)超高速集成电路硬件描述语言设计复杂数字电路的方法具有很多优点,VHDL语言的设计技术齐全、方法灵活、支持广泛。
VHDL语言的系统硬件描述能力很强,具有多层次描述系统硬件功能的能力,可以从系统级到门级电路,而且高层次的行为描述可以与低层次的RTL描述混合使用。
VHDL在描述数字系统时,可以使用前后一致的语义和语法跨越多层次,并且使用跨越多个级别的混合描述模拟该系统。
因此,可以对高层次行为描述的子系统及低层次详细实现子系统所组成的系统进行模拟。
3.2程序流程图
图3.2.1系统程序流程图
4、系统测试
4.1测试仪器清单
测试使用的仪器设备如表4.1.1所示
表4.1.1测试使用的仪器设备
序号
名称
型号
数量
备注
1
3位半数字万用表
UNI-T
1
深圳胜利公司
2
直流稳压电源
DF1731SC2A
1
江苏扬中电子仪器厂
4.2测试及误差计算
系统的测试主要是测试硬件是否能正常工作,软件和硬件是否匹配,是否合乎设计的要求。
在频率测试过程中,系统的测量范围系统的精度是两个较重要的指标。
系统的测量结果如表4.2.1所示
表4.2.1系统测量数据表
序号
标准电压值(U/V)
测量电压值(Ux/V)
误差(%)
1
2
3
4
5
6
7
8
9
10
参考文献
[1]潘松,黄继业.EDA实用教程.北京.科学出版社.2002年10月第一版
[2]黄智伟.全国大学生电子设计竞赛训练教程.北京:
电子工业出版式社.2005年1月第1版;
[3]高吉祥,〈〈数字电子技术〉〉北京:
电子工业出版社,2003年8谭浩强月第1版;
附录1:
源程序清单
顶层:
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
--Uncommentthefollowinglinestousethedeclarationsthatare
--providedforinstantiatingXilinxprimitivecomponents.
--libraryUNISIM;
--useUNISIM.VComponents.all;
entitytopis
Port(clk,reset:
instd_logic;
key1,eoc:
instd_logic;
D:
instd_logic_vector(7downto0);
ale,start,oe,clk500k:
outstd_logic;
cba:
outstd_logic_vector(2downto0);---0809通道选择
xs:
outstd_logic_vector(8downto0);---发光二极管显示状态
lcden:
outstd_logic;--接LCD使能端
lcdda:
outstd_logic;--接LCD_da信号输入端
lcdrw:
outstd_logic;--接LCD读写信号输入端
lcddata:
inoutstd_logic_vector(7downto0));--接LCD数据输入位
endtop;
architectureBehavioraloftopis
componentkeyis
Port(clk,reset:
instd_logic;
key1:
instd_logic;
clkz:
outstd_logic;
dw1:
outintegerrange0to2;
cba:
outstd_logic_vector(2downto0));
endcomponent;
componentad0809is
Port(clk,reset:
instd_logic;
eoc:
instd_logic;
D:
instd_logic_vector(7downto0);
ale,start,oe,clk500k:
outstd_logic;
xs:
outstd_logic_vector(8downto0);---0809工作状态显示
Q:
outstd_logic_vector(7downto0));
endcomponent;
componentyimais
Port(clk:
instd_logic;
clkz:
instd_logic;
Q:
instd_logic_vector(7downto0);
v1,v2,v3,v4,v5:
outintegerrange0to9);
endcomponent;
componentlcdis
generic(delay:
integer:
=100);---类属说明
Port(clk,reset:
instd_logic;
dw1:
inintegerrange0to2;
v1,v2,v3,v4,v5:
inintegerrange0to9;
lcden:
outstd_logic;--接LCD使能端
lcdda:
outstd_logic;--接LCD_da信号输入端
lcdrw:
outstd_logic;--接LCD读写信号输入端
lcddata:
inoutstd_logic_vector(7downto0));--接LCD数据输入位
endcomponent;
signalclkz_load:
std_logic;
signaldw1_load:
integerrange0to2;
signalQ_load:
std_logic_vector(7downto0);
signalv1_load,v2_load,v3_load,v4_load,v5_load:
integerrange0to9;
begin
u1:
keyportmap
(clk=>clk,reset=>reset,key1=>key1,clkz=>clkz_load,dw1=>dw1_load,cba=>cba);
u2:
ad0809portmap
(clk=>clk,reset=>reset,eoc=>eoc,D=>D,ale=>ale,start=>start,oe=>oe,clk500k=>clk500k,xs=>xs,Q=>Q_load);
u3:
yimaportmap
(clk=>clk,clkz=>clkz_load,Q=>Q_load,v1=>v1_load,v2=>v2_load,v3=>v3_load,v4=>v4_load,v5=>v5_load);
u4:
lcdportmap
(clk=>clk,reset=>reset,dw1=>dw1_load,v1=>v1_load,v2=>v2_load,v3=>v3_load,v4=>v4_load,v5=>v5_load,
lcden=>lcden,lcdda=>lcdda,lcdrw=>lcdrw,lcddata=>lcddata);
endBehavioral;
按键:
libraryIEEE;
useIEEE.STD_LOGIC_1164.ALL;
useIEEE.STD_LOGIC_ARITH.ALL;
useIEEE.STD_LOGIC_UNSIGNED.ALL;
--Uncommentthefollowinglinestousethedeclarationsthatare
--providedforinstantiatingXilinxprimitivecomponents.
--libraryUNISIM;
--useUNISIM.VComponents.all;
entitykeyis
Port(clk,reset:
instd_logic;
key1:
instd_logic;
clkz:
outstd_logic;
dw1:
outintegerrange0to2;
cba:
outstd_logic_vector(2downto0));
endkey;
architectureBehavioralofkeyis
signalclkk:
std_logic;
begin
process(clk,reset)
variableclk1:
std_logic;
variablecnt:
integerrange0to50000000;
begin
ifreset='1'then
ifclk'eventandclk='1'then
ifcnt<49999999then
clk1:
='1';cnt:
=cnt+1;
elsifcnt<=50000000then
clk1:
='0';cnt:
=0;
endif;
endif;
endif;
clkz<=clk1;
endprocess;
process(clk,reset)
variableclk0:
std_logic;
variablecnt:
integerrange0to3125000;---0.125s
begin
ifreset='0'thencnt:
=0;clk0:
='0';
elsifclk'eventandclk='1'then
ifcnt=3125000then
cnt:
=0;clk0:
=notclk0;
elsecnt:
=cnt+1;
endif;
endif;
clkk<=clk0;
endprocess;
process(clkk,reset,key1)
variablecnt:
integerrange0to3;
begin
ifreset='1'then
ifrising_edge(clkk)then
ifcnt>2thencnt:
=0;
elsifkey1='0'then
cnt:
=cnt+1;
casecntis
when1=>cba<="000";dw1<=1;
when2=>cba<="001";dw1<=2;
whenothers=>cba<="000";dw1<=1;
endcase;
endif;
endif;
end