简易电压表设计实验报告
- 格式:docx
- 大小:315.17 KB
- 文档页数:19
数字电路与逻辑设计实验实验报告课题名称:简易数字电压表的设计学院:信息与通信工程学院班级:姓名:学号:班内序号:一.设计课题的任务要求设计并实现一个简易数字电压表,要求使用实验板上的串行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转换启动键,输入。
科目物理年级班级组别时间实验名称用电压表测电压
实验目的1.练习用电压表测干电池电压和一段电路两端的电压。
2.研究干电池串联和并联时的电压关系。
实验器材电源(干电池)、电池夹、灯座、小灯泡、开关、导线、电流表
实验过程
实验步骤:
一、先取三节干电池,分别测出每节电池的电压。
再将这三节干电池按图1-1串联
成电池组,测出串联电池组的电压,将测得的数据记到表1内。
分析串联电池组的电压
跟各节干电池电压之间的关系,写出结论。
二、将两节相同的干电池按图1-2并联组成电池组,用电压表测这个并联电池组的电压,
将测量数据填入表2内。
分析并联电池组的电压跟每节电池的电压之间的关系,写出结
论。
实验记录(实验数据、观察到的现象)
表1:串联电池组的电压
干电池Ⅰ的电压(V) 干电池Ⅱ的电压(V) 干电池Ⅲ的电压(V) 串联电池组的电压(V)
[结论]:。
表2:并联电池组的电压
干电池Ⅰ的电压(V) 干电池Ⅱ的电压(V) 并联电池组的电压(V)
[结论]:。
实验完毕,断开电源,整理仪器,进行总结。
实验结论由学生汇报实验数据和所得到的结论。
(1) 串联电池组的电压等于各节电池的电压之和。
(2) 并联电池组的电压等于每节电池的电压。
简易数字电压表设计实验报告姓名陈秀秀学号 201203870404指导教师贾立新专业班级电气1202 学院信息工程学院一.实验要求采用C8051F360单片机最小系统设计一简易数字电压表,实现对0~3.3V直流电压的测量,原理框图如图3-1所示。
模拟输入电压通过一只1 kΩ电位器产生,ADC0将模拟电压转换成数字量后换算成电压值,用十进制的形式在LCD上显示。
进一步,将单片机最小系统与PC通过RS-232通信电缆连接,将A/D转换的数字量在PC终端显示。
图3-1二.实验设计设计方案:由主程序、T0中断服务程序、ADC0中断服务程序组成。
具体流程图如下图3-2所示。
图3-2三.具体设计1.简易数字电压表设计F360初始化及LCD初始化(详细程序代码见附录)①内部振荡器初始化:OscInit()②I/O端口初始化:PortIoInit()③外部数据存储器接口初始化:XramInit()④定时器初始化:TimerInit()⑤中断系统初始化:Int0Init()⑥ADC0初始化:ADC_Init()⑦PCA初始化:PcaInit()2.电压转换方式(将电压转换为十进制)ADCDAT=ADC0H*256+ADC0L;VOLT=ADCDAT*2.4/1024=ADCDAT*0.002344;VOLTOUT=VOLT*1000;for(i=0;i<4;i++){VOLTBCD[i]=VOLTOUT%10;VOLTOUT=VOLTOUT/10;}3.LCD显示程序设计①检查LCD是否空闲子程序void CheckLcd(){uchar temp=0x00;uchar xdata *addr;while(1){addr=RCOMADDR;temp=*addr;temp&=0x80;if(temp==0x00)break;}}②电压值显示WriteCom(0x9C);WriteData(VOLTBCD[3]+0x30);WriteData(0x2E);WriteData(VOLTBCD[2]+0x30);WriteData(VOLTBCD[2]+0x30);WriteData(VOLTBCD[0]+0x30);WriteData(0x56);4.实验中AD转换方式选用逐次逼近型,A/D转换完成后得到10位数据分为高低字节存放在寄存器ADCOH和ADC0L中,此处选择右对齐,转换时针为2MHZ。
摘要--------------------------------------------------------2 1.数字电压表的简介------------------------------------------31.1数字电压表的发展--------------------------------------31.2数字电压表的分类--------------------------------------42.设计的目的------------------------------------------------53.设计的内容及要求------------------------------------------54.数字电压表的基本原理--------------------------------------54.1数字电压表各模块的工作原理----------------------------54.2数字电压表各模块的功能--------------------------------54.3数字电压表的工作过程----------------------------------65.实验器材--------------------------------------------------76.电路设计实施方案------------------------------------------76.1.实验步骤---------------------------------------------76.2各个模块设计------------------------------------------86.2.1 基准电压模块-----------------------------------86.2.2 3 1/2位A/D电路模块---------------------------106.2.3 字形译码驱动电路模块--------------------------126.2.4 显示电路模块----------------------------------136.2.5 字位驱动电路模块------------------------------167.总结-----------------------------------------------------17 参考文件---------------------------------------------------18 附录-------------------------------------------------------19本文介绍了一种简易数字电压表的设计。
附页:
一、学生实验报告
14)8通道,10位高速ADC,速度可达25万次/秒,2路PWM还可当2路D/A使用。
15)2通道捕获/比较单元(PWM/PCA/CCP),也可用来再实现2个定时器或2个外部中断(支持上升沿/下降沿中断)。
16)4个16位定时器,兼容普通8051的定时器T0/T1,2路PCA实现2个定时器。
17)可编程时钟输出功能,T0在P3.4输出时钟,T1在P3.5输出时钟,BRT 在P1.0输出时钟。
18)硬件看门狗(WDT)。
19)高速SPI串行通信端口。
20)全双工异步串行口(UART),兼容普通8051的串口。
21)通用I/O口(36/40/44个),复位后为:准双向口/弱上拉(普通8051传统I/O口)。
可设置成四种模式:准双向口/弱上拉,推挽/强上拉,仅为输入/高阻,开漏。
每个I/O口驱动能力均可达到20mA,但整个芯片最大不得超过120mA。
二、学生参加实验室开放项目的体会与建议。
直流电压表的设计实验报告直流电压表的设计实验报告引言:直流电压表是一种测量电路中直流电压的仪器。
在电子工程领域中,直流电压表是一种常用的测试工具。
本实验旨在设计并制作一台简单实用的直流电压表,以便能够准确测量电路中的直流电压。
一、实验目的:本实验的目的是设计并制作一台直流电压表,通过实验验证其准确性和可靠性。
具体目标如下:1. 理解直流电压表的工作原理;2. 学会使用电流表、电阻器等元器件进行电路设计;3. 测试直流电压表的灵敏度和测量范围。
二、实验原理:直流电压表是基于毫伏表的原理设计的。
毫伏表是一种电压测量仪器,它通过将待测电压与已知电阻串联,通过测量电流大小来计算待测电压的值。
直流电压表的关键是选择合适的电阻值,以确保测量电流的幅度适中,既能够保证测量精度,又不会对待测电路产生明显的影响。
三、实验材料和仪器:1. 直流电源;2. 电流表;3. 电阻器;4. 连接线;6. 待测电路。
四、实验步骤:1. 将直流电源的正极与待测电路的正极连接,负极与待测电路的负极连接;2. 将电流表的正极与待测电路的正极连接,负极与电阻器的一端连接;3. 将电阻器的另一端与待测电路的负极连接;4. 打开直流电源,调节电压大小,观察电流表的读数;5. 记录电流表的读数和待测电压的实际值;6. 重复步骤4和步骤5,改变待测电压的大小,以验证直流电压表的准确性和可靠性。
五、实验结果和分析:通过实验测量,我们得到了一系列的待测电压和电流表的读数。
根据实验数据,我们可以绘制出待测电压和电流表读数的关系曲线。
通过分析曲线,我们可以得出以下结论:1. 直流电压表的灵敏度较高,能够准确测量待测电压的变化;2. 直流电压表的测量范围较广,能够满足大部分实际测量需求;3. 直流电压表的测量精度较高,能够满足精确测量的要求。
六、实验总结:通过本实验,我们成功设计并制作了一台直流电压表。
实验结果表明,该直流电压表具有较高的灵敏度、较广的测量范围和较高的测量精度。
程序:#include<p18f45k20.h>#define uchar unsigned char#define uint unsigned int#define ADGO ADCON0bits.GO #define fmq PORTEbits.RE0#define m1l 57904 //低8度#define m2l 58736#define m3l 59472#define m4l 59804#define m5l 60432#define m6l 60992#define m7l 61488#define m1 61712 //中#define m2 62168#define m3 62500#define m4 62672#define m5 62984#define m6 63264#define m7 63512#define m1h 63624 //高8度#define m2h 63832#define m3h 64048#define m4h 64104#define m5h 64260#define m6h 64400#define m7h 64524#define p 1000 //节拍时长#define ph p/2 //半拍#define pd p*2 //双拍#define pf p*3/4#define pg p/4uintsong[]={m6l,m1,m3,m4,m2,m3,m4,m6,m5,m4,m3,m1,m1,m2,m3,m5,m4,m3,m2,m2,m2,m7l,m1, m2,m4,m3,m2,m2,m2,m2,m3,m3,m3,m5,m6,m3,m3,m3,m3,m5,m2,m2,m2,m3,m5,m2,m2,m3,m6 l,m6l};//《手掌心》简谱uinttime[]={p,ph,ph,pf*2,pg,pg,ph,ph,ph,ph,p,ph,pg,pg,ph,ph,ph,pg,pg,p,ph,pg,pg,ph,ph,pg,pg,pg,pg, pg,pf,pd,ph,ph,pg,pg,pg,pg,pg,ph,pg,p,ph,ph,ph,ph,pg,ph,pg,p};//对应的歌曲节拍uint total = 50;uint counter = 0,num = 0, i = 0;uint flag=0;uint a1=0,a2=0,a3=0,a4=0;uint lednum=0;uchar num_h[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};//共阳数码管“0.—9.”定义uchar num_l[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳数码管“0 --9”定义void Delay25us(unsigned int x);//延时函数声明unsigned int AD_Trs();//Ad转换函数声明void display(void);//数码管显示函数声明void Tmr_Init(void);//定时器初始化函数声明void High_Interrupt(void);//定时器中断跳转函数声明void Stopwatch(void);//定时器中断执行函数声明void main(void)//主函数{WDTCONbits.SWDTEN = 0;//关闭看门狗TRISC=0X00;//输入输出端口初始化TRISD=0X00;PORTC=0X00;TRISE=0X00;PORTEbits.RE0=0;//用于音乐输出TRISAbits.TRISA0=1; //AD转换采集电压输入PORTAbits.RA0=0;ADCON0=0x01;//使能ADC,模拟通道选择AN0(RA0)ADCON1 = 0x00;//正负参考电压从单片机内部获取ADCON2 = 0xa5;//A/D 转换结果格式为右对齐//采样周期8TAD//AD转换时钟频率FOSC/16Tmr_Init();//定时器初始化while(1)//等待中断{ClrWdt();lednum = AD_Trs();//获取AD转换得到的数据if(lednum >= 3300)//测得电压达最大量程3.3V时开定时器,播音乐{fmq = 0 ; //拉低INTCONbits.TMR0IE = 1;T0CONbits.TMR0ON = 1;display();//数码管显示当前电压}else//不足3.3V时关闭定时器{fmq = 1 ; //拉高T0CONbits.TMR0ON = 0;INTCONbits.TMR0IE = 0;INTCONbits.TMR0IF = 0;//定时器溢出标志位清零i = 0;//重新定位音乐至开头num = 0;TMR1H = song[num]/256;//定时器赋初值TMR1L = song[num]%256;display();}}}unsigned int AD_Trs()//AD转换程序{unsigned int adval;float advalf;ADGO = 1; //启动AD转化while(ADGO); //说明AD转化完成adval= ADRESH;adval = adval<<8|ADRESL;advalf = adval/1023.0*3.3; //因为参考电压为3.3伏adval = advalf*1000; //转化为整数,以便显示return (adval);}void Delay25us(uint x) //延时函数{unsigned int a,b;for(a=x;a>0;a--)for(b=110;b>0;b--);//执行空语句实现延时}void Tmr_Init(void)//定时器初始化函数{i = 0;num = 0;INTCON = 0XF0;//开全局中断,允许定时器0溢出中断T0CON = 0X08;//配置Timer0为16 位定时器TMR0H = song[num]/256;TMR0L = song[num]%256;}#pragma code high_vector = 0x0008void High_Interrupt(void)//定时器溢出时跳转{if(INTCONbits.TMR0IF && INTCONbits.TMR0IE){_asmgoto Stopwatch_endasm}}#pragma code#pragma interrupt Stopwatchvoid Stopwatch(void)//中断执行函数{if(INTCONbits.TMR0IF && INTCONbits.TMR0IE) {T0CONbits.TMR0ON = 0;//关中断,以便为定时器赋初值INTCONbits.TMR0IF = 0;//溢出标志位清零counter++;if(counter == time[i])//实现音乐节拍{counter = 0;i++;num++;if(i >= total || num >= total)//音乐播完后重头开始{i = 0;num = 0;}}TMR0H = song[num]/256;TMR0L = song[num]%256;if(flag){flag=0;PORTEbits.RE0=0;//蜂鸣器驱动端输出低电平}else{flag=1;PORTEbits.RE0=1;//蜂鸣器驱动端输出高电平}T0CONbits.TMR0ON = 1;//开中断INTCONbits.TMR0IE = 1;}}#pragma codevoid display(void)//数码管显示函数{uint j=20;//数码管扫描时间变量a1 = lednum/1000; //此算法用于取出一个整数的各个位,来显示在数码管上a2 = lednum%1000/100;a3 = lednum%100/10;a4 = lednum%10;PORTC=0X00;PORTC=0x01;//依次选通数码管PORTD=num_h[a1];//查找表并显示数值Delay25us(j); //延时PORTC=0X00;PORTC=0x02;PORTD=num_l[a2];Delay25us(j);PORTC=0X00;PORTC=0x04;PORTD=num_l[a3];Delay25us(j);PORTC=0X00;PORTC=0x08;PORTD=num_l[a4];Delay25us(j);}。
设计制作一个简易数字电压表目录一、设计要求................................................................................................... 错误!未定义书签。
二、设计方案、电路图和工作原理............................................................... 错误!未定义书签。
三、软件仿真................................................................................................... 错误!未定义书签。
四、PCB设计.................................................................................................. 错误!未定义书签。
五、元器件清单表........................................................................................... 错误!未定义书签。
五、焊接和调试............................................................................................... 错误!未定义书签。
六、过程照片................................................................................................... 错误!未定义书签。
七、总结、心得及其他................................................................................... 错误!未定义书签。
数字电路与逻辑设计实验实验报告课题名称:简易数字电压表的设计学院:信息与通信工程学院班级:姓名:学号:班内序号:一.设计课题的任务要求设计并实现一个简易数字电压表,要求使用实验板上的串行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,按下此键开始测量。