简易电压表设计实验报告.docx
《简易电压表设计实验报告.docx》由会员分享,可在线阅读,更多相关《简易电压表设计实验报告.docx(21页珍藏版)》请在冰豆网上搜索。
![简易电压表设计实验报告.docx](https://file1.bdocx.com/fileroot1/2022-12/6/ae325b4e-855c-4a3f-a03e-474e00448c8d/ae325b4e-855c-4a3f-a03e-474e00448c8d1.gif)
简易电压表设计实验报告
数字电路与逻辑设计实验
实验报告
课题名称:
简易数字电压表的设计
学院:
信息与通信工程学院
班级:
姓名:
学号:
班内序号:
一.设计课题的任务要求
设计并实现一个简易数字电压表,要求使用实验板上的串行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.1ADS7816转换控制模块
(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码。
二进制数据
高4位电压
中4位电压
低4位电压
0000
0.000
0.000
0.000
0001
0.154
0.010
0.001
0010
0.307
0.019
0.001
0011
0.461
0.029
0.002
0100
0.614
0.038
0.002
0101
0.768
0.048
0.003
0110
0.922
0.058
0.004
0111
1.075
0.067
0.004
1000
1.229
0.077
0.005
1001
1.382
0.086
0.005
1010
1.536
0.096
0.006
1011
1.690
0.106
0.007
1100
1.843
0.115
0.007
1101
1.997
0.125
0.008
1110
2.150
0.134
0.008
1111
2.304
0.144
0.009
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转换控制模块
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_ARITH.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYadsIS
PORT(
en:
instd_logic;
clk:
inSTD_LOGIC;
cs:
outSTD_LOGIC;
ad_dat:
instd_logic;
da_out:
outstd_logic_vector(11downto0));
ENDads;
ARCHITECTUREbehaveOFadsIS
signaloe:
integerrange0to1;
signalen1,en2,f_en:
std_logic;
signalt:
integerrange0to16;
signaltemp_cs:
std_logic;
signaldata_out:
std_logic_vector(11downto0);
BEGIN
p1:
process(clk)--按键防抖
begin
ifclk'eventandclk='0'then
en2<=en1;
en1<=en;
endif;
endprocess;
f_en<=clkanden1and(noten2);
p2:
process(f_en,clk,oe)--
begin
if(f_en'eventandf_en='1')then--接收到开始测量按键的信号
oe<=1;
endif;
ifoe=1then
ifclk'eventandclk='1'then
--将ADS输出的12位串行二进制数据转换为12位并行二进制数据
casetis
when4=>data_out(11)<=ad_dat;--第4个时钟上升沿ADS开始输出数据
when5=>data_out(10)<=ad_dat;
when6=>data_out(9)<=ad_dat;
when7=>data_out(8)<=ad_dat;
when8=>data_out(7)<=ad_dat;
when9=>data_out(6)<=ad_dat;
when10=>data_out(5)<=ad_dat;
when11=>data_out(4)<=ad_dat;
when12=>data_out(3)<=ad_dat;
when13=>data_out
(2)<=ad_dat;
when14=>data_out
(1)<=ad_dat;
when15=>data_out(0)<=ad_dat;
da_out<=data_out;
whenothers=>data_out<="000000000000";
endcase;
ift<16thent<=t+1;
elset<=0;
endif;
endif;
ifclk'eventandclk='0'then
casetis
when0=>temp_cs<='1';--t=0时一次转换结束,cs变为高电平
when1=>temp_cs<='0';--t=1时下一次转换开始,cs变为低电平
whenothers=>null;
endcase;
endif;
endif;
endprocess;
cs<=temp_cs;
endbehave;
2.数据转换控制模块
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
USEIEEE.STD_LOGIC_ARITH.ALL;
ENTITYdealIS
PORT(
clk:
instd_logic;
datain:
INSTD_LOGIC_VECTOR(11DOWNTO0);
en:
instd_logic;
reset:
instd_logic;
beef:
OUTSTD_LOGIC;
d2,d3,d4:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));
ENDdeal;
ARCHITECTUREbehaveOFdealIS
SIGNALdata0,data1,data2:
STD_LOGIC_VECTOR(15DOWNTO0);
SIGNALsum1,sum2,sum3,sum4,do1,do2,do3,do4:
STD_LOGIC_VECTOR(4DOWNTO0);
SIGNALc1,c2,c3:
STD_LOGIC_VECTOR(4DOWNTO0);
signalflag:
integerrange0to1;
signalr:
integerrange0to1;
signalen1,en2,f_en:
std_logic;
signalreset1,reset2,f_reset:
std_logic;
BEGIN
p2:
process(clk)--按键防抖
begin
ifclk'eventandclk='0'then
reset2<=reset1;
reset1<=reset;
en2<=en1;
en1<=en;
endif;
endprocess;
f_reset<=clkandreset1and(notreset2);
f_en<=clkanden1and(noten2);
p3:
PROCESS(datain,f_en,f_reset)--reset,en组合的4个状态00,01,10,11转移关系
BEGIN
if(f_en'eventandf_en='1')then
if(r=0andflag=0)or(r=0andflag=1)then
flag<=1;
endif;
if(r=1andflag=1)or(r=1andflag=0)then
flag<=0;
endif;
endif;
if(f_reset'eventandf_reset='0')then
if(r=0andflag=0)or(r=1andflag=0)then
r<=0;
endif;
if(r=1andflag=1)or(r=0andflag=1)then
r<=1;
endif;
endif;
if(flag=1andr=0)or(flag=0andr=1)then–当状态为01,10时,开始数据转换
--将高四位二进制数据所代表的电压值转换为16位BCD码
CASEdatain(11DOWNTO8)IS
WHEN"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";
WHENOTHERS=>data2<=NULL;
ENDCASE;
--将中四位二进制数据所代表的电压值转换为16位BCD码
CASEdatain(7DOWNTO4)IS
WHEN"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";
WHENOTHERS=>data1<=NULL;
ENDCASE;
--将低四位二进制数据所代表的电压值转换为16位BCD码
CASEdatain(3DOWNTO0)IS
WHEN"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";
WHENOTHERS=>data0<=NULL;
ENDCASE;
--将高,中,低分别代表的16位BCD(表示为15-0位)进行加法运算
--16位BCD码中的(3-0位)相加,和大于9进1
sum1<=('0'&data2(3DOWNTO0))+('0'&data1(3DOWNTO0))+('0'&data0(3DOWNTO0));
IFsum1<"01010"THENc1<="00000";
ELSEc1<="00001";
ENDIF;
--16位BCD码中的(7-4位)相加,和大于9进1
sum2<=('0'&data2(7DOWNTO4))+('0'&data1(7DOWNTO4))+('0'&data0(7DOWNTO4))+c1;
IFsum2<"01010"THENc2<="00000";
ELSEc2<="00001";
ENDIF;
--16位BCD码中的(11-8位)相加,和大于9进1
sum3<=('0'&data2(11DOWNTO8))+('0'&data1(11DOWNTO8))+('0'&data0(11DOWNTO8))+c2;
IFsum3<"01010"THENc3<="00000";
ELSEc3<="00001";
ENDIF;
--16位BCD码中的(15-12位)相加,和大于9进1
sum4<=('0'&data2(15DOWNTO12))+('0'&data1(15DOWNTO12))+('0'&data0(15DOWNTO12))+c3;
IFsum1<"01010"THENdo1<=sum1;--和大于9减10
ELSEdo1<=sum1-"01010";
ENDIF;
IFsum2<"01010"THENdo2<=sum2;
ELSEdo2<=sum2-"01010";
ENDIF;
IFsum3<"01010"THENdo3<=sum3;
ELSEdo3<=sum3-"01010";
ENDIF;
IFsum4<"01010"THENdo4<=sum4;
ELSEdo4<=sum4-"01010";
ENDIF;
d2<=do2(3DOWNTO0);--输出十进制BCD码中的低四位
d3<=do3(3DOWNTO0);--输出十进制BCD码中的中四位
d4<=do4(3DOWNTO0);--输出十进制BCD码中的高四位
--量程超过1.5V蜂鸣器报警,溢出显示为“5.55”
IF(do4(3DOWNTO0)>="0001"anddo3(3DOWNTO0)>="0101")THEN
beef<='1';
else
beef<='0';
ENDIF;
else
d2<="0000";
d3<="0000";
d4<="0000";
beef<='0';
endif;
ENDPR