当前位置:文档之家› 简易电压表设计实验报告

简易电压表设计实验报告

数字电路与逻辑设计实验实验报告课题名称:简易数字电压表的设计学院:信息与通信工程学院班级:姓名:学号:班内序号:一.设计课题的任务要求设计并实现一个简易数字电压表,要求使用实验板上的串行AD 芯片ADS7816。

1. 基本要求:(1)测量对象:1~2 节干电池。

(2)AD 参考电压:2.5V。

(3)用三位数码管显示测量结果,保留两位小数。

(4)被测信号超过测量范围有溢出显示并有声音提示。

(5)按键控制测量和复位。

2. 提高要求:(1)能够连续测量。

(2)自拟其他功能。

二. 系统设计(包括设计思路、总体框图、分块设计)1. 设计思路本次实验利用ADS7816作为电压采样端口,FPGA作为系统的核心器件,用LED数码管进行已测电压值的显示,先把读取的12位串行二进制数据转换成并行的12位二进制数据,然后再把并行的12位二进制数据转换成便利于输出的3位十进制BCD码送给数码管,以显示当前测量电压值。

这些工作由ADS7816转换控制模块、数据转换控制模块、译码显示模块完成。

2. 总体框图3. 分块设计3.1 ADS7816转换控制模块(1)ADS7816工作原理在ADS7816的工作时序中,串行时钟DCLK用于同步数据转换,每位转换后的数据在DCLK 的下降沿开始传送。

因此,从Dout引脚接收数据时,可在DCLK的下降沿期间进行,也可以在DCLK的上升沿期间进行。

通常情况下,采用在DCLK的上升沿接收转换后的各位数据流。

CS 的下降沿用于启动转换和数据变换,CS有效后的最初1至2个转换周期内,ADS7816采样输入信号,此时输出引脚Dout呈三态。

DCLK的第2个下降沿后,Dout使能并输出一个时钟周期的低电平的无效信号。

在第4个时钟的上升沿,Dout开始输出转换结果,其输出数据的格式是最高有效位(B11位)在前。

当最低有效位(B0位)输出后,若CS变为高电位,则一次转换结束,Dout显三态。

(2)元件设计:en:A/D转换启动键,输入。

输入高电平时开始转换。

clk:时钟输入。

ad_dat:ADS7816转换结束后的12位串行二进制数据输入端。

cs:A/D转换结束信号,输出,当A/D转换结束时,此端输出一个高电平(转换期间一直为低电平)。

data_out[11..0]:12位并行二进制数据输出端。

3.2 数据转换控制模块(1)元件设计en:开始测量键,输入。

按键按下为高电平。

reset:复位键,输入。

按键按下为高电平。

clk:时钟输入。

datain[11..0]:12位并行二进制数据输入端。

beef:蜂鸣器,高电平有效。

d2[3..0]:低四位十进制BCD码输出端d3[3..0]:中四位十进制BCD码输出端d4[3..0]:高四位十进制BCD码输出端(2)状态说明reset,en两个按键有四个状态组合00,01,10,11,按键按下为“1”,状态转移图如下所示,当状态为01,10时开始数据转换。

(3)数据处理ADS7816是12位模数转换器,它的输出状态共有4096种,输入信号Ui为0~2.5V 电压范围,则每两个状态值为2.5/(4096-1),约为0.0006V,故测量分辨率为0.006V。

常用测量方法是:当读取到DB11~DB0转换值是XXXH时,电压测量值为U≈XXXH×0.02V;考虑到直接使用乘法计算对应的电压值将耗用大量的FPGA内部组件,本设计用查表命令来得到正确的电压值。

在读取到ADS7816的转换数据后,先用查表指令算出高,中,低4位的3个电压值,并分别用16位BCD码表示;接着设计16位的BCD码加法,如果每4位相加结果超过9需进行减10进1。

这样得到模拟电压的BCD码。

3.3译码显示模块clk1:时钟输入。

doo2[3..0]:低四位十进制BCD码输入端doo3[3..0]:中四位十进制BCD码输入端doo4[3..0]:高四位十进制BCD码输入端CAT[5..0]:片选信号,输出seg[6..0]:7段数码管显示,输出dp:小数点显示,输出三. 仿真波形及波形分析1. ADS7816转换控制模块cs下降沿后的第一个时钟周期上升的计数变量t=1,根据代码,当t=4时开始接收ADS7816传进来的第一个数据B11到data_out(11);t=5时开始接收ADS7816传进来的第二个数据B10到data_out(10);直到t=15时开始接收ADS7816传进来的第十二个数据B0到data_out(0),然后一次性将并行的12个数据data_out传给输出端da_out。

2. 数据转换控制模块如图所示,当en有一个上升沿时,开始数据转换。

例如从ADS转换控制模块接收的数据为“000110111101”时,查表可知输出电压应为0.154+0.106+0.008=0.26V,即d4=“0000”,d3=“0010”,d2=“0110”;而当reset有一个下降沿时,d4=“0000”,d3=“0000”,d2=“0000”;以上预计结果与仿真图输出相同,仿真结果正确。

3. 译码显示模块图1图2仿真图中多个数码管是依次显示,当频率较高,切换速度足够快时,观察到所有数码管都是同时在显示。

如图2,当输入是“000000100000”时,数码管显示“0.20”,CAT为“111110”时,seg为“1111110”,个位显示“0”;CAT为“1111101”时,seg为“1101101”,小数点第二位显示“2”。

四. 源程序1. ADS7816转换控制模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY ads ISPORT(en:in std_logic;clk:in STD_LOGIC;cs:out STD_LOGIC;ad_dat: in std_logic;da_out: out std_logic_vector(11 downto 0));END ads;ARCHITECTURE behave OF ads ISsignal oe:integer range 0 to 1;signal en1,en2,f_en:std_logic;signal t:integer range 0 to 16;signal temp_cs:std_logic;signal data_out:std_logic_vector(11 downto 0);BEGINp1:process(clk) --按键防抖beginif clk'event and clk='0' thenen2<=en1;en1<=en;end if;end process;f_en<=clk and en1 and (not en2);p2:process(f_en,clk,oe) --beginif (f_en'event and f_en='1' )then --接收到开始测量按键的信号oe<=1;end if;if oe=1 thenif clk'event and clk='1' then--将ADS输出的12位串行二进制数据转换为12位并行二进制数据case t iswhen 4=>data_out(11)<=ad_dat; --第4个时钟上升沿ADS开始输出数据 when 5=>data_out(10)<=ad_dat;when 6=>data_out(9)<=ad_dat;when 7=>data_out(8)<=ad_dat;when 8=>data_out(7)<=ad_dat;when 9=>data_out(6)<=ad_dat;when 10=>data_out(5)<=ad_dat;when 11=>data_out(4)<=ad_dat;when 12=>data_out(3)<=ad_dat;when 13=>data_out(2)<=ad_dat;when 14=>data_out(1)<=ad_dat;when 15=>data_out(0)<=ad_dat;da_out<=data_out;when others=>data_out<="000000000000";end case;if t<16 then t<=t+1;else t<=0;end if;end if;if clk'event and clk='0' thencase t iswhen 0=>temp_cs<='1'; --t=0时一次转换结束,cs变为高电平 when 1=>temp_cs<='0'; --t=1时下一次转换开始,cs变为低电平when others=>null;end case;end if;end if;end process;cs<=temp_cs;end behave;2. 数据转换控制模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;ENTITY deal ISPORT(clk: in std_logic;datain:IN STD_LOGIC_VECTOR(11 DOWNTO 0);en: in std_logic;reset: in std_logic;beef: OUT STD_LOGIC;d2,d3,d4:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));END deal;ARCHITECTURE behave OF deal ISSIGNAL data0,data1,data2:STD_LOGIC_VECTOR(15 DOWNTO 0);SIGNAL sum1,sum2,sum3,sum4,do1,do2,do3,do4:STD_LOGIC_VECTOR(4 DOWNTO 0); SIGNAL c1,c2,c3:STD_LOGIC_VECTOR(4 DOWNTO 0);signal flag:integer range 0 to 1;signal r:integer range 0 to 1;signal en1,en2,f_en:std_logic;signal reset1,reset2,f_reset:std_logic;BEGINp2:process(clk) --按键防抖beginif clk'event and clk='0' thenreset2<=reset1;reset1<=reset;en2<=en1;en1<=en;end if;end process;f_reset<=clk and reset1 and (not reset2);f_en<=clk and en1 and (not en2);p3:PROCESS(datain,f_en,f_reset) --reset,en组合的4个状态00,01,10,11转移关系 BEGINif (f_en'event and f_en='1') thenif (r=0 and flag=0)or (r=0 and flag=1) thenflag<=1;end if;if (r=1 and flag=1)or( r=1 and flag=0 ) thenflag<=0;end if;end if;if (f_reset'event and f_reset='0') thenif (r=0 and flag=0)or (r=1 and flag=0) thenr<=0;end if;if (r=1 and flag=1)or( r=0 and flag=1) thenr<=1;end if;end if;if (flag=1 and r=0)or(flag=0 and r=1) then –当状态为01,10时,开始数据转换--将高四位二进制数据所代表的电压值转换为16位BCD码CASE datain(11 DOWNTO 8) ISWHEN "0000"=> data2 <= "0000000000000000";WHEN "0001"=> data2 <= "0000000101010100";WHEN "0010"=> data2 <= "0000001100000111";WHEN "0011"=> data2 <= "0000010001100001";WHEN "0100"=> data2 <= "0000011000010100";WHEN "0101"=> data2 <= "0000011101101000";WHEN "0110"=> data2 <= "0000100100100010";WHEN "0111"=> data2 <= "0001000001110101";WHEN "1000"=> data2 <= "0001001000101001";WHEN "1001"=> data2 <= "0001001110000010";WHEN "1010"=> data2 <= "0001010100110110";WHEN "1011"=> data2 <= "0001011010010000";WHEN "1100"=> data2 <= "0001100001000011";WHEN "1101"=> data2 <= "0001100110010111";WHEN "1110"=> data2 <= "0010000101010000";WHEN "1111"=> data2 <= "0010001100000100";WHEN OTHERS=> data2 <= NULL;END CASE;--将中四位二进制数据所代表的电压值转换为16位BCD码CASE datain(7 DOWNTO 4) ISWHEN "0000"=> data1 <= "0000000000000000";WHEN "0001"=> data1 <= "0000000000010000";WHEN "0010"=> data1 <= "0000000000011001";WHEN "0011"=> data1 <= "0000000000101001";WHEN "0100"=> data1 <= "0000000000111000";WHEN "0101"=> data1 <= "0000000001001000";WHEN "0110"=> data1 <= "0000000001011000";WHEN "0111"=> data1 <= "0000000001100111";WHEN "1000"=> data1 <= "0000000001110111";WHEN "1001"=> data1 <= "0000000010000110";WHEN "1010"=> data1 <= "0000000010010110";WHEN "1011"=> data1 <= "0000000100000110";WHEN "1100"=> data1 <= "0000000100010101";WHEN "1101"=> data1 <= "0000000100100101";WHEN "1110"=> data1 <= "0000000100110100";WHEN "1111"=> data1 <= "0000000101000100";WHEN OTHERS=> data1 <= NULL;END CASE;--将低四位二进制数据所代表的电压值转换为16位BCD码CASE datain(3 DOWNTO 0) ISWHEN "0000"=> data0 <= "0000000000000000";WHEN "0001"=> data0 <= "0000000000000001";WHEN "0010"=> data0 <= "0000000000000001";WHEN "0011"=> data0 <= "0000000000000010";WHEN "0100"=> data0 <= "0000000000000010";WHEN "0101"=> data0 <= "0000000000000011";WHEN "0110"=> data0 <= "0000000000000100";WHEN "0111"=> data0 <= "0000000000000100";WHEN "1000"=> data0 <= "0000000000000101";WHEN "1001"=> data0 <= "0000000000000101";WHEN "1010"=> data0 <= "0000000000000110";WHEN "1011"=> data0 <= "0000000000000111";WHEN "1100"=> data0 <= "0000000000000111";WHEN "1101"=> data0 <= "0000000000001000";WHEN "1110"=> data0 <= "0000000000001000";WHEN "1111"=> data0 <= "0000000000001001";WHEN OTHERS=> data0 <= NULL;END CASE;--将高,中,低分别代表的16位BCD(表示为15-0位)进行加法运算--16位BCD码中的(3-0位)相加,和大于9进1sum1<=('0'&data2(3 DOWNTO 0))+('0'&data1(3 DOWNTO 0))+('0'&data0(3 DOWNTO 0)); IF sum1<"01010" THEN c1<="00000";ELSE c1<="00001";END IF;--16位BCD码中的(7-4位)相加,和大于9进1sum2<=('0'&data2(7 DOWNTO 4))+('0'&data1(7 DOWNTO 4))+('0'&data0(7 DOWNTO 4))+c1;IF sum2<"01010" THEN c2<="00000";ELSE c2<="00001";END IF;--16位BCD码中的(11-8位)相加,和大于9进1sum3<=('0'&data2(11 DOWNTO 8))+('0'&data1(11 DOWNTO 8))+('0'&data0(11 DOWNTO 8))+c2;IF sum3<"01010" THEN c3<="00000";ELSE c3<="00001";END IF;--16位BCD码中的(15-12位)相加,和大于9进1sum4<=('0'&data2(15 DOWNTO 12))+('0'&data1(15 DOWNTO 12))+('0'&data0(15 DOWNTO 12))+c3;IF sum1<"01010" THEN do1<=sum1; --和大于9减10ELSE do1<=sum1-"01010";END IF;IF sum2<"01010" THEN do2<=sum2;ELSE do2<=sum2-"01010";END IF;IF sum3<"01010" THEN do3<=sum3;ELSE do3<=sum3-"01010";END IF;IF sum4<"01010" THEN do4<=sum4;ELSE do4<=sum4-"01010";END IF;d2<=do2(3 DOWNTO 0); --输出十进制BCD码中的低四位d3<=do3(3 DOWNTO 0); --输出十进制BCD码中的中四位d4<=do4(3 DOWNTO 0); --输出十进制BCD码中的高四位-- 量程超过1.5V蜂鸣器报警,溢出显示为“5.55”IF(do4(3 DOWNTO 0)>="0001" and do3(3 DOWNTO 0)>="0101" ) THENbeef<='1';elsebeef<='0';END IF;elsed2<="0000";d3<="0000";d4<="0000";beef<='0';end if;END PROCESS;END behave;3. 译码显示模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;USE IEEE.STD_LOGIC_ARITH.ALL;ENTITY display ISPORT(doo2,doo3,doo4: IN STD_LOGIC_VECTOR(3 DOWNTO 0); CLK1: IN STD_LOGIC;CAT: OUT STD_LOGIC_VECTOR(5 DOWNTO 0);dp: OUT STD_LOGIC;seg: OUT STD_LOGIC_VECTOR(6 DOWNTO 0));END display;ARCHITECTURE V1 OF display ISSIGNAL TMP : INTEGER RANGE 0 TO 3;BEGINp1: PROCESS(CLK1)BEGINIF(CLK1'EVENT AND CLK1 = '1' ) THENIF(TMP = 3) THENTMP <= 1;ELSETMP <= TMP + 1;END IF;END IF;end PROCESS;p2: PROCESS(TMP)BEGINCASE TMP IS--高四位译码WHEN 3 => CAT <= "111011";dp<='1';if (doo4="0000") then seg<="1111110";elsif (doo4="0001") then seg<="0110000";elsif (doo4="0010") then seg<="1101101";elsif (doo4="0011") then seg<="1111001";elsif (doo4="0100") then seg<="0110011";elsif (doo4="0101") then seg<="1011011";elsif (doo4="0110") then seg<="1011111";elsif (doo4="0111") then seg<="1110000";elsif (doo4="1000") then seg<="1111111";elsif (doo4="1001") then seg<="1111011";else seg<="1111110";end if;--中四位译码WHEN 2 => CAT <= "111101";dp<='0';if (doo3="0000") then seg<="1111110";elsif (doo3="0001") then seg<="0110000";elsif (doo3="0010") then seg<="1101101";elsif (doo3="0011") then seg<="1111001";elsif (doo3="0100") then seg<="0110011";elsif (doo3="0101") then seg<="1011011";elsif (doo3="0110") then seg<="1011111";elsif (doo3="0111") then seg<="1110000";elsif (doo3="1000") then seg<="1111111";elsif (doo3="1001") then seg<="1111011";else seg<="1111110";end if;--低四位译码WHEN 1 => CAT <= "111110";dp<='0';if (doo2="0000") then seg<="1111110";elsif (doo2="0001") then seg<="0110000";elsif (doo2="0010") then seg<="1101101";elsif (doo2="0011") then seg<="1111001";elsif (doo2="0100") then seg<="0110011";elsif (doo2="0101") then seg<="1011011";elsif (doo2="0110") then seg<="1011111";elsif (doo2="0111") then seg<="1110000";elsif (doo2="1000") then seg<="1111111";elsif (doo2="1001") then seg<="1111011";else seg<="1111110";end if;WHEN OTHERS => seg <= "1111110";CAT <= "111000"; END CASE;END PROCESS;END V1;4. 12分频模块LIBRARY IEEE;USE IEEE.STD_LOGIC_1164.ALL;USE IEEE.STD_LOGIC_UNSIGNED.ALL;ENTITY div_12 ISPORT(clk: IN STD_LOGIC;clk_out: OUT STD_LOGIC);END div_12;ARCHITECTURE struct OF div_12 ISSIGNAL temp :INTEGER RANGE 0 TO 124;SIGNAL clk_temp: STD_LOGIC;BEGINPROCESS(clk)BEGINIF(clk'event AND clk='1') THENIF temp=11 THENtemp<=0;clk_temp<=NOT clk_temp; ELSEtemp<=temp+1;END IF;END IF;END PROCESS;clk_out<=clk_temp;END struct;五. 功能说明及资源利用情况1.功能说明en:为开始测量按键,连接到BIN6,按下此键开始测量。

相关主题