设计题目: 数字电压表电路的设计
专业班级: 测控技术与仪器
学 号: 20072341905
姓 名: 申前垒
指导教师: 葛化敏
数字电压表电路设计报告
一、题目及设计要求
1、题目:数字电压表
2、利用双积分式A/D转换器ICL7107设计一数字电压表,量程为-1.999— +1.999,通过四位数码管显示。
二、主要技术指标
1、数字芯片A/D转换技术
2、单片机控制的数码管显示技术
3、单片机的数据处理技术
三、方案论证及选择
1、主控芯片
方案1:选用专用电压转化芯片INC7107实现电压的测量和实现。用四位数码管显示出最后的转换电压结果。缺点是精度比较低,且内部电压转换和控制部分不可控制。优点是价格低廉。
方案2:选用单片机AT89S52和A/D转换芯片ADC0809实现电压的转换和控制,用四位数码管显示出最后的转换电压结果。缺点是价格稍贵;优点是转换精度高,且转换的过程和控制、显示部分可以控制。
基于课程设计的要求,我们优先选用了:方案1
2、显示部分
方案1:选用4个单体的共阳数码管。优点是价格比较便宜;缺点是焊接时比较麻烦,容易出错。
方案2:选用一个四联的共阳数码管,外加四个三极管驱动。这个电路几乎没有缺点;优点是便于控制,价格低廉,焊接简单。
基于课程设计的要求,我们优先选用了:方案1
四、主要元器件的介绍
1、芯片INC7107
双积分型A/D转换器ICL7107是一种间接A/D转换器。它通过对输入模拟电压和参考电压分别进行两次积分,将输入电压平均值变换成与之成正比的时间间隔,然后利用脉冲时间间隔,进而得出相应的数字性输出。它包括积分器、比较器、计数器,控制逻辑和时钟信号源。
计数器对反向积分过程的时钟脉冲进行计数。控制逻辑包括分频器、译码器、相位驱动器、控制器和锁存器。
分频器用来对时钟脉冲逐渐分频,得到所需的计数脉冲fc和共阳极LED数码管公共电极所需的方波信号fc。
译码器为BCD-7段译码器,将计数器的BCD码译成LED数码管七段笔画组成数字的相应编码。
驱动器是将译码器输出对应于共阳极数码管七段笔画的逻辑电平变成驱动相应笔画的方波。
控制器的作用有三个:第一,识别积分器的工作状态,适时发出控制信号,使各模拟开关接通或断开,A/D转换器能循环进行。第二,识别输入电压极性,控制LED数码管的负号显示。第二,当输入电压超量限时发出溢出信号,使千位显示“1" ,其余码全部熄灭。
钓锁存器用来存放A/D转换的结果,锁存器的输出经译码器后驱动LED 。它的每个测量周期自动调零(AZ)、信号积分(INT)和反向积分(DE)三个阶
INC7107的结构电路图
1.2 下面分别介绍芯片INC7107各个引脚的功能和注意事项
ICL7107 安装电压表头时的一些要点:按照测量=±199.9mV 来说明。
1.辨认引脚:芯片的第一脚,是正放芯片,面对型号字符,然后,在芯片的左下方为第一脚。
也可以把芯片的缺口朝左放置,左下角也就是第一脚了。
许多厂家会在第一脚旁边打上一个小圆点作为标记。
知道了第一脚之后,按照反时针方向去走,依次是第 2 至第 40 引脚。(1 脚与 40 脚遥遥相对)。
2.牢记关键点的电压:芯片第1脚是供电,正确电压是 DC5V 。第 36 脚是基准电压,正确数值是 100mV,第 26 引脚是负电源引脚,正确电压数值是负的,在 -3V 至 -5V 都认为正常,但是不能是正电压,也不能是零电压。芯片第 31 引脚是信号输入引脚,可以输入 ±199.9mV 的电压。在一开始,可以把它接地,造成“0”信号输入,以方便测试。
3.注意芯片 27,28,29 引脚的元件数值,它们是 0.22uF,47K,0.47uF 阻容网络,这三个元件属于芯片工作的积分网络,不能使用磁片电容。芯片的 33 和 34 脚接的 104 电容也不能使用磁片电容。
4.注意接地引脚:芯片的电源地是 21 脚,模拟地是 32 脚,使用时一般与输入信号的负端以及基准电压的负极相连。
信号地是 30 脚,基准地是 35 脚,通常使用情况下,这 4 个引脚都接地,在一些有特殊要求的应用中(例如测量电阻或者比例测量),30 脚或 35 脚就可能不接地而是按照需要接到其他电压上。
5、比例读数:把 31 脚与 36 脚短路,就是把基准电压作为信号输入到芯片的信号端,观察此时数码管的读数
6、其他引脚的功能简要说明:
20引脚PM:液晶显示器背面公共电极的驱动端,简称背电极. a1-g1,a2-g2,a3-g3:分别为个位、十位、百位笔画的驱动信号,依次接个位、十位、百位LED显示器的相应笔画电极
19脚Bc4:千位笔画驱动信号。接千位LEO显示器的相应的笔画电极。
37脚TEST :测试端,该端经过500欧姆电阻接至逻辑电路的公共地,故也称“逻辑地”或“数字地”。
27脚INT:27是一个积分电容器,必须选择温度系数小不致使积分器的输入电压产生漂移现象的元件
28脚BUF:缓冲放大器输出端,接积分电阻Rint。其输出级的无功电流( idling current )是100μA,而缓冲器与积分器能够供给20μA的驱动电流,从此脚接一个Rint至积分电容器,其值在满刻度200mV时选用47K,而2V满刻度则使用470K。
AZ:积分器和比较器的反向输入端,接自动调零电容(29脚)CAz 。如果应用在200mV满刻度的场合是使用0.47μF,而2V满刻度是0.047μF。
2、电压显示电路:
设计中采用的是4段LED数码管来显示电压值。LED具有耗电低、亮度高、视角大、线路简单、耐震及寿命长等优点,它由4个发光二极管组成,其中3个按‘8’字型排列,另一个发光二极管为圆点形状,位于右下角,常用于显示小数点。把4个发光二极管连在一起,公共端接高电平,叫共阳极接法,相反,公共端接低电平的叫共阴极接法,我们采用共阴极接法。当发光二极管导通时,相应的一段笔画或点就发亮,从而形成不同的发光字符。其8段分别命名为dp g f e d c b a。例如,要显示“0”,则dp g f e d c b a分别为:00111111B;若要显示多个数字,只要让若干个数码管的位码循环为高电平就可以了。
下图是数码管的结构图
其他元器件:
三端可调分流基准源一个
0.22uF、0.047 uF,103PF,104PF,100PF的电容各一个
470K,1M,10K,15K,1K,100K,1K的电阻各一个
开关一个
TL431A三极管一个
五、电路原理图
六,调试过程及测试结果
1、 首先根据电路原理图焊接出实际电路,然后进行电路的调试,在实际的电路中,芯片一脚接+5V的电源,26引脚接-5V的电压,在电阻R2一端接入一个测试电压,接地端接测试电压的负极。
2、 现在将在调试过程中的问题总结:测试数码管显示的数据是否正确,将编好的程序写进单片机后,观察数码管,发现码型显示不正确,通过改正硬件电路,是数码管显示正确的数据。
3、 通过以上硬件电路调试,最终达到了设计的要求,实现了从-1.999V-- +1.999V的显示,并且精度比较高。
4、实验结果如下图
七、总结
本次课程设计对点阵显示电路认真的学习以及对单片机技术有了更进一步的熟悉,实际操作和课本上的知识有很大联系,但又高于课本,一个看似很简单的电路,要动手把它设计出来就比较困难了,因为是设计要求我们在以后的学习中注意这一点,要把课本上所学到的知识和实际联系起来,同时通过本次电路的设计,不但巩固了所学知识,也是我们把理论与实践从真正意义上结合起来,增强了学习的综合能力。通过这次设计不仅锻炼了我们的团队协作精神,而且提高了创新能力。
在这四周的试验中,在收获知识的同时,还收获了阅历,收获了成熟。在此过程中,我们通过查找大量资料,请教老师,以及不懈的努力,不仅培养了独立思考、动手操作的能力。在各种其他方面的能力上也都有了提高,而且在与老师和同学的交流过程中,互动学习,将知识融会贯通。更重要的是我们学会了很多学习的方法,而这是日后最实用的,真的是受益匪浅。要面对社会的挑战,只有不断学习、实践、再学习、再实践。不管怎样,这些都是一种锻炼,一种知识的完全积累,可以把这个当做基础东西,只有掌握了这些最基础的,才可以更进一步,取得更好的成绩。
八、参考文献
1、单片机原理及应用 张毅刚、刘杰 《哈尔滨工业大学》
2、DSP芯片的原理与开发应用 彭启棕 《高等教育出版社》
3、单片机基础第三版 李广弟、朱月秀、冷祖祁 《人民邮电》
第二篇:数字电压表实验报告
数字电压表的综合设计
一、设计题目:
基于FPGA的数字电压表设计
二、设计任务:
1、具有0—2.5v的电压量程;
2、通过LED灯显示2进制数字量;
3、用FPGA设计制作成数字电压表的专用集成芯片,结合LED数码管构成一个能够实时显示的电压表。
三、总体设计框图:
1、总体框图
22、分模块设计框图:
LED数码管显示模块
TL549A/D处理模块
3、程序代码:
查找表程序代码
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
entity chazhaobiao is
port(V:in std_logic_vector(7 downto 0);
q:out std_logic_vector(11 downto 0)
);
end entity chazhaobiao;
architecture behav of chazhaobiao is
signal c30,c74,c117,d0,d1:std_logic;
signal HB,LB:std_logic_vector(11 downto 0);
begin --A/D值的高4位转换成3位BCD码
HB<="001001000000" WHEN V(7 DOWNTO 4)="1111" ELSE --2.40
"001000100100" WHEN V(7 DOWNTO 4)="1110" ELSE --2.24
"001000001000" WHEN V(7 DOWNTO 4)="1101" ELSE --2.08
"000110010010" WHEN V(7 DOWNTO 4)="1100" ELSE --1.92
"000101110110" WHEN V(7 DOWNTO 4)="1011" ELSE --1.76
"000101100000" WHEN V(7 DOWNTO 4)="1010" ELSE --1.60
"000101000100" WHEN V(7 DOWNTO 4)="1001" ELSE --1.44
"000100101000" WHEN V(7 DOWNTO 4)="1000" ELSE --1.28
"000100010010" WHEN V(7 DOWNTO 4)="0111" ELSE --1.12
"000010010110" WHEN V(7 DOWNTO 4)="0110" ELSE --0.96
"000010000000" WHEN V(7 DOWNTO 4)="0101" ELSE --0.80
"000001100100" WHEN V(7 DOWNTO 4)="0100" ELSE --0.64
"000001001000" WHEN V(7 DOWNTO 4)="0011" ELSE --0.48
"000000110010" WHEN V(7 DOWNTO 4)="0010" ELSE --0.32
"000000010110" WHEN V(7 DOWNTO 4)="0001" ELSE --0.16
"000000000000"; --0.00
--A/D值低4位变为3位BCD码
LB<="000000010101" WHEN V(3 DOWNTO 0)="1111" ELSE --0.15
"000000010100" WHEN V(3 DOWNTO 0)="1110" ELSE --0.14
"000000010011" WHEN V(3 DOWNTO 0)="1101" ELSE --0.13
"000000010010" WHEN V(3 DOWNTO 0)="1100" ELSE --0.12
"000000010001" WHEN V(3 DOWNTO 0)="1011" ELSE --0.11
"000000010000" WHEN V(3 DOWNTO 0)="1010" ELSE --0.10
"000000001001" WHEN V(3 DOWNTO 0)="1001" ELSE --0.09
"000000001000" WHEN V(3 DOWNTO 0)="1000" ELSE --0.08
"000000000111" WHEN V(3 DOWNTO 0)="0111" ELSE --0.07
"000000000110" WHEN V(3 DOWNTO 0)="0110" ELSE --0.06
"000000000101" WHEN V(3 DOWNTO 0)="0101" ELSE --0.05
"000000000100" WHEN V(3 DOWNTO 0)="0100" ELSE --0.04
"000000000011" WHEN V(3 DOWNTO 0)="0011" ELSE --0.03
"000000000010" WHEN V(3 DOWNTO 0)="0010" ELSE --0.02
"000000000001" WHEN V(3 DOWNTO 0)="0001" ELSE --0.01
"000000000000" ; --0.00
c30<='1' when HB(3 downto 0)+LB(3 downto 0)>"01001" else
'0';
d1<='1' when HB(3 downto 0)>="1000" and LB(3 downto 0)>="1000" else
'0';
c74<='1' when HB(7 downto 4)+LB(7 downto 4)>"01001" else
'0';
d0<='1' when HB(7 downto 4) + LB(7 downto 4) ="01001" else
'0';
c117<='1' when HB(11 downto 8)+LB(11 downto 8)>"01001" else
'0';
q(3 downto 0)<=
HB(3 downto 0)+LB(3 downto 0)+"0110" when
c30='1' else
HB(3 downto 0)+LB(3 downto 0)+"0110" when
d1='1' else
HB(3 downto 0)+LB(3 downto 0);
q(7 downto 4)<=
HB(7 downto 4)+LB(7 downto 4)+"0111" when
c74='1' and c30='1' else
HB(7 downto 4)+LB(7 downto 4)+"0110" when
c74='1' and c30='0' else
HB(7 downto 4)+LB(7 downto 4)+"0110" when
c74='0' and c30='1' and d0='1' else
HB(7 downto 4)+LB(7 downto 4)+"0001" when
c74='0' and (c30='1'or d1='1') and d0='0' else
HB(7 downto 4)+LB(7 downto 4);
q(11 downto 8)<=
HB(11 downto 8)+LB(11 downto 8)+"0111" when
c117='1' and c74='1' else
HB(11 downto 8)+LB(11 downto 8)+"0110" when
c117='1' and c74='0' else
HB(11 downto 8)+LB(11 downto 8)+"0001" when
c117='0' and c74='1' else
HB(11 downto 8)+LB(11 downto 8)+"0001" when
c117='0' and c74='0' and (c30='1'or d1='1') and d0='1' else
HB(11 downto 8)+LB(11 downto 8);
end ;
译码器程序代码
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
entity yima is
port(clk:in std_logic;
d:in std_logic_vector(11 downto 0);
seg: out std_logic_vector(7 downto 0);
sel: out std_logic_vector(2 downto 0));
end entity yima;
architecture behav of yima is
signal wei:std_logic_vector(2 downto 0);
signal num:std_logic_vector(3 downto 0);
signal a:std_logic_vector(2 downto 0);
begin
num<=d(3 downto 0) when a="000" else
d(7 downto 4) when a="001" else
d(11 downto 8) ;
seg(7)<='0' when wei="011" else
'1';
wei<="110" when a="000" else
"101" when a="001" else
"011";
sel<=wei;
COM1: process(clk)
begin
if clk'event and clk='1' then
a<=a+1;
if a="010" then a<="000";
end if;
end if;
end process COM1;
COM2: process(num)
begin
case num is
when "0000"=>seg(6 downto 0)<="1000000";--0
when "0001"=>seg(6 downto 0)<="1111001";--1
when "0010"=>seg(6 downto 0)<="0100100";--2
when "0011"=>seg(6 downto 0)<="0110000";--3
when "0100"=>seg(6 downto 0)<="0011001";--4
when "0101"=>seg(6 downto 0)<="0010010";--5
when "0110"=>seg(6 downto 0)<="0000010";--6
when "0111"=>seg(6 downto 0)<="1111000";--7
when "1000"=>seg(6 downto 0)<="0000000";--8
when "1001"=>seg(6 downto 0)<="0010000";--9
--when "1010"=>seg(6 downto 0)<="1110111";
--when "1011"=>seg(6 downto 0)<="1111100";
--when "1100"=>seg(6 downto 0)<="0111001";
--when "1101"=>seg(6 downto 0)<="1011110";
--when "1110"=>seg(6 downto 0)<="1111001";
--when "1111"=>seg(6 downto 0)<="1110001";
--when others=>seg(6 downto 0)<="0111111";
when others=>seg(6 downto 0)<="1000000";
end case;
end process COM2;
end;
电压表顶层程序代码:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity dianyabiao is
Port (clk : in std_logic; --50m系统时钟
din : in std_logic; --(tlc549)串行数据输出端
clk_tlc549 : out std_logic;
cs_tlc549 : out std_logic; --tlc549的片选信号输入端
shift : out std_logic_vector(3 downto 0);--动态扫描时的位选信号
cs_led : out std_logic_vector(1 downto 0);--发光二极管及数码管的片选信号输入端
dout_led : out std_logic_vector(7 downto 0));--惧的发光器件的信号输出端
end dianyabiao;
architecture Behavioral of dianyabiao is
type state is (st1,st2);
signal current_state : state;
type state1 is (st0,st1,st2);
signal current_state1 : state1;
type state2 is (st0,st1,st2,st3,st4);
signal current_state2 : state2;
signal reg_datain : std_logic_vector(7 downto 0);
signal reg_dout : std_logic_vector(15 downto 0);
signal dout : std_logic_vector(4 downto 0);
signal reg_din : integer range 0 to 80000;
signal clk1m,clk1k,clk100 : std_logic;
begin
--分频部分
process(clk) --产生1MHz的频率
variable cnt : integer range 0 to 50;
begin
if clk'event and clk='1' then cnt:=cnt+1;
if cnt<50 then
if cnt<25 then clk1m<='0';
else clk1m<='1';
end if;
else cnt:=0;
end if;
end if;
end process;
process(clk1m) --产生1KHz的频率
variable cnt : integer range 0 to 1000;
begin
if clk1m'event and clk1m='1' then cnt:=cnt+1;
if cnt<1000 then
if cnt<500 then clk1k<='0';
else clk1k<='1';
end if;
else cnt:=0;
end if;
end if;
end process;
process(clk1k) --产生100Hz的频率
variable cnt : integer range 0 to 10;
begin
if clk1k'event and clk1k='1' then cnt:=cnt+1;
if cnt<10 then
if cnt<5 then clk100<='0';
else clk100<='1';
end if;
else cnt:=0;
end if;
end if;
end process;
--tlc549的控制部分
process(clk1k)
variable cnt : integer range 0 to 7;
variable datain : std_logic_vector(7 downto 0);
begin
if clk1k'event and clk1k='1' then
case current_state is
when st1=> --将数据进行串并转换
cs_tlc549<='0';
datain:=datain(6 downto 0)&din; --将读取的数据向高位移位
clk_tlc549<='1';
current_state<=st2;
when st2=>
cs_tlc549<='0';
clk_tlc549<='0';
current_state<=st1;
if cnt<7 then cnt:=cnt+1; --读取8位数据
else cnt:=0;
reg_din<=conv_integer(datain)*195; --每单位数字量乘以系数=当前电压值;
reg_datain<=not(datain);
end if;
when others=>
current_state<=st1;
end case;
end if;
end process;
--十进制-BCD码转换;
process(clk100)
variable reg : integer range 0 to 80000;
variable d1,d2,d3,d4 : std_logic_vector(3 downto 0);
begin
if clk100'event and clk100='1' then
case current_state1 is
when st0=>
reg:=reg_din;
d1:="0000";d2:="0000";d3:="0000";d4:="0000";
current_state1<=st1;
when st1=>
if reg>9999 then reg:=reg-10000;d1:=d1+1;
elsif reg>999 then reg:=reg-1000;d2:=d2+1;
elsif reg>99 then reg:=reg-100;d3:=d3+1;
elsif reg>9 then reg:=reg-10;d4:=d4+1;
else current_state1<=st2;
end if;
when st2=>
reg_dout<=d1&d2&d3&d4;
current_state1<=st0;
when others=>
current_state1<=st0;
end case;
end if;
end process;
--动态扫描控制;
process(clk1k)
begin
if clk1k'event and clk1k='1' then
case current_state2 is
when st0=> --在发光二极管上显示模数转换后的数字量
cs_led<="01"; --熄灭数码管
shift<="1111";
dout<="11111";
current_state2<=st1;
when st1=> --在数码管的最高位显示数据
cs_led<="10"; --熄灭发光二极管
shift<="0111"; --最高位数码管显示
dout<='0'®_dout(15 downto 12); --小数点显示,并且将最高位的数据送给译码器
current_state2<=st2;
when st2=> --在数码管的次高位显示数据
cs_led<="10"; --熄灭发光二极管
shift<="1011"; --次高位数码管显示
dout<='1'®_dout(11 downto 8); --小数点不显示,将次高位的数据送给译码器
current_state2<=st3;
when st3=> --在数码管的次低位显示数据
cs_led<="10"; --熄灭发光二极管
shift<="1101"; --次低位数码管显示
dout<='1'®_dout(7 downto 4); --小数点不显示,将次低位的数据送给译码器
current_state2<=st4;
when st4=> --在数码管的最低位显示数据
cs_led<="10"; --熄灭发光二极管
shift<="1110"; --最低位数码管显示
dout<='1'®_dout(3 downto 0); --小数点不显示,将最低位的数据送给译码器
current_state2<=st0;
when others=>
current_state2<=st0;
end case;
end if;
end process;
--**将BCD码进行8段译码(包括小数点) **--
--**dout(4)代表小数点,低电平点亮 **--
code1: process (dout,reg_datain)
begin
case dout(3 downto 0) is
when "0000"=>dout_led<=dout(4)&"0000001";
when "0001"=>dout_led<=dout(4)&"1001111";
when "0010"=>dout_led<=dout(4)&"0010010";
when "0011"=>dout_led<=dout(4)&"0000110";
when "0100"=>dout_led<=dout(4)&"1001100";
when "0101"=>dout_led<=dout(4)&"0100100";
when "0110"=>dout_led<=dout(4)&"0100000";
when "0111"=>dout_led<=dout(4)&"0001111";
when "1000"=>dout_led<=dout(4)&"0000000";
when "1001"=>dout_led<=dout(4)&"0000100";
--"DOUT_LED"送给数码管;
when others=>dout_led<=reg_datain(7)®_datain(0)®_datain(1)®_datain(2)®_datain(3)®_datain(4)®_datain(5)®_datain(6);
--"DOUT_LED"送给发光二极管;
end case;
end process;
end Behavioral;
四、波形仿真图:
五、结论:
本次实验达到了实验的基本要求,能够通过调节高精密变阻器实现0—2.5v的电压测量及显示。
六、心得体会:
通过本次实验我明白了任何一个实验的成功完成都是要经过认真的准备和预习的,再者就是理论和实践还是有一定的差距,只有通过实践才能更加好的理解理论知识,达到学以致用的目的。