西工大数电实验5课设电压测量Word文件下载.docx
《西工大数电实验5课设电压测量Word文件下载.docx》由会员分享,可在线阅读,更多相关《西工大数电实验5课设电压测量Word文件下载.docx(21页珍藏版)》请在冰豆网上搜索。
3、误差小于0.1V。
(二)设计要求
1、电压在0-1V:
LED0按1Hz闪烁;
2、电压在1-2V:
LED1按1Hz闪烁;
3、电压在2-3V:
LED2按1Hz闪烁;
4、电压在3-4V:
LED3按1Hz闪烁;
5、电压在4-5V:
蜂鸣器报警;
6、显示测量结果。
三、方案设计与论证
要使用PCF8591以及DE0板完成电压测量的任务,首先需要使用DE0板与PCF8591进行通讯,使得其工作在D/A转换状态,使用DE0板收集PCF8591采集到的8位二进制数。
然后需要一个模块对收集来的数据进行计算转换,使其转换成为容易理解方便使用的十进制数。
下一步,使用个位数控制LED和蜂鸣器模块。
与之同时使用七段数码管译码模块将个位数以及十分位显示在两个七段数码管上。
蜂鸣器模块接收到1的信号时就通过模块里面编好的频率节奏发出声音。
方案一
使用一个模块按顺序实现各个功能,但是发现整个任务的任务量比较大,内容比较多,这个方案实际完成是比较困难,所以没有采用。
方案二
将任务分成数据的采集,数据处理,数码管显示,蜂鸣器控制四个模块,分别完成各个模块后再组合到一起,这个方案思路清晰,操作相对比较简单,所以我们将采用方案二,如下图所示
4、单元电路设计与参数计算
1.数据采集模块
PCF8591是一种具有I2C总线接口的8位A/DD/A转换芯片,在CPU的信息传输过程中仅靠时钟线SCL和数据线SDA就可以实现。
I2C总线是Philips(飞利浦)公司推出的串行总线,它与传统的通信方式相比具有读写方便,结构简单,可维护性好,易实现系统扩展,易实现模块化标准化设计,可靠性高等优点。
I2C通信中只涉及两条信号线,即时钟线SCL和数据线SDA。
时钟线的下降沿锁存数据。
当时钟线SCL高电平时,如果把数据线SDA从高电平拉到低电平,则表示通信开始;
如果把数据线SDA从低电平拉到高电平,则表示通信结束。
A/D转换数据操作格式
A/D转换逻辑操作波形时序图
该模块的接口定义如下表所示
信号名称
方向
描述
CLK
Input
时钟信号,50MHz
RST_N
复位信号,低电平有效
REN
按键,低电平有效,进行读写操作
SCL
output
PCF8591的时钟端口
SDA
Inout
PCF8591的数字端口
Data_out
数据输出
2.数据转化模块
将PCF8591芯片对电压采集的8位二进制数字信号转化为容易理解方便使用的十进制数(分为四位数,个位,十分位,百分位,千分位.但是这里我们后面只需要用到个位以及十分位即可。
其中使用个位数控制LED和蜂鸣器模块(个位数为0时LED0闪烁,
个位数为1时LED1闪烁,
个位数为2时LED2闪烁,
个位数为3时LED3闪烁,
个位数为4时给蜂鸣器一个1信号.)
3.数码管显示模块
两个数码管转换器组成分别都有一个数字输入,一个数字输出,可以实现将测量的电压的个位数,小数显示在DE0板的数码管上。
4.LED显示和蜂鸣器控制模块
这个模块有三个输入信号,分别是clk(50MHz时钟信号),clr(复位信号)和Va[3:
0](表示高位的4位二进制数字信号)。
有四个输出信号,分别为led0,led1,led2,led3(LED灯显示)。
实现的功能是,当电压位于不同的区间时,所对应的led灯闪烁。
当Va为1~2V,led0闪烁;
当Va为2~3V,led1闪烁;
当Va为3~4V,led2闪烁;
当Va为4~5V,led3闪烁。
在之前的设置中,如果蜂鸣器模块接收到1的信号时就通过模块里面编好的频率节奏发出声音。
五、电路的安装与调试
完成各模块的设计与单独调试之后,新建block框图为顶层文件,连接各模块如下:
配置针脚如下:
将程序进行调试运行完毕以后,下载到DE0板之后进行电压测量测试,首先进行电路连接,使用杜邦线将PCF8591的SDA,SDL,VCC,GND分别接到DE0板拓展区分配的针脚或者是已经指定的针脚,然后连接5个等值电阻的直流分压电路,最后确认连接无误后进行电压测量测试,分别测试每个电阻两只引脚的电压值与实际值对比。
同时注意观察电压值不同时其对应的LED灯的闪烁情况以及蜂鸣器的工作情况。
最终成功的完成了实验。
6、遇到问题的解决方法
1.刚开始看到题目时感觉无从下手,对PCF8591的特性并不熟悉,并且不知道怎么把采集信号,对此,我们通过查阅老师给的资料,并且从网上查询相关的资料,一步一步了解了相应的实现方法。
2.实验中,我们最大的问题就在于如何构建整个系统,即将每个部分有效地连接在一起并产生我们所要的结果。
进一步的了解了整个系统的构建和编译过程,使我们对VHDL语句和Quartus的使用有了进一步的认识。
3.之前的实验一直使用VHDL语言编写,VHDL语言不够简洁,有些表示比较麻烦。
所以这次采用了VHDL与Verilog相结合来编写程序,对我们来说是一个很大的挑战。
4.注意一些细节的问题。
在端口定义里最好把端口的名字写的详细一点以方便阅读,使用case时一定要加入default来防止latch的发生。
7、结论与心得
通过一个学期的数字电路和实验的学习,对数字电路有了初步的了解,也能够自己做一些东西了。
体会的数电在实际生活中的发挥很大的作用。
从开始对FPGA,PCF8591,DE0板一无所知,之前只学过C语言,对VHDL不了解,后来在不断的学习中发现,许多语言都有很多的相似之处,感觉Verilog语言和C语言更相似一些,与VHDL语言相比比较简单,容易上手操作,数电实验还锻炼了我们自己查阅资料学习的能力,除了老师讲的内容之外,还需要很多东西自己了解,只能利用课下的时间,现在发达的网络技术也让我们更容易查到想要的资料,或许这就是科技的力量吧。
查阅资料理解是一回事,但是能够自己成功的把要求做出来就是另外一回事了,尤其是在编代码的时候,有的时候自己觉得写的没有什么问题但是程序运行就是有很多错误,并且在最后连接FPC8591板的时候,一定要小心,如果连错了很容易把板子烧坏掉。
八、参考文献
[1]童诗白,华成英.模拟电子技术基础[M].北京:
高等教育出版社,2001.414-417.
[2]彭介华。
电子技术课程设计指导[M].北京:
高等教育出版社,1997.3-45.
[3]阎石,数字电子技术基础[M].北京:
高等教育出版社,1998.348-352.
9、附录
源程序代码:
//voltagecollect
moduleAD(clk,rst_n,ren,scl,sda,data_out);
inputclk,rst_n,ren;
inoutsda;
outputscl;
output[7:
0]data_out;
reg[7:
regscl,sda;
parameterfre=8'
d50;
//T=1us
0]cnt;
regclk_in;
//I2CSerialBUS
//-------------------------------------
reg[2:
0]start_check;
//dismissjitterofswitch,getsynchronizingsignalstart_en
wirestart_en;
always@(posedgeclkornegedgerst_n)
if(!
rst_n)start_check<
=3'
d0;
else
begin
start_check[0]<
=ren;
start_check[1]<
=start_check[0];
start_check[2]<
=start_check[1];
end
//en=1
assignstart_en=start_check[2]&
start_check[1]&
start_check[0];
//-----------------------------------------
always@(posedgeclk)//frequencydivider,T(clk_in)=1us,usedinI2CBUS
if(start_en)
begin
cnt<
=cnt+1'
b1;
if(cnt==fre>
>
1)begin
clk_in=~clk_in;
end
elseif(cnt==fre)
begin
cnt<
=8'
end
/*--------------------------------------------------
I2CBUStorealizeADCofPCF8591with4states
ack=2'
b00start()+write(AddrWr)//0x90
b01write(ControlByte)//0x02
b10start()+write(AddrRd)//0x91
b10Read(data)//dataistheADCoutput
--------------------------------------------------*/
reg[1:
0]ack;
0]data,delay;
regtemp;
always@(posedgeclk_inornegedgerst_n)//1us
rst_n)begin
delay<
ack<
=2'
b00;
delay<
=delay+1'
if(ack==2'
b00)
case(delay)
8'
d1:
sda<
=1;
d2:
scl<
//scl<
d6:
=0;
d9:
d11:
//addwrh90/1
d15:
d19:
d21:
//0
d25:
d29:
d31:
//0
d35:
d39:
d41:
//1
d45:
d49:
d51:
//0
d55:
d59:
d61:
d65:
d69:
d71:
d75:
d79:
d81:
d85:
d89:
//end
d91:
=1'
bz;
d95:
d98:
temp<
=sda;
default:
if((delay>
100))//&
&
(delay<
255)&
(temp==0)
beginack<
b01;
delay<
end
endcase
elseif(ack==2'
b01)
//h02controlbyte
d10:
d12:
d16:
d20:
d22:
d26:
d30:
d32:
d36:
d40:
d42:
d46:
d50:
d52:
d56:
d60:
d62:
d66:
d70:
d72:
d76:
d80:
d82:
d86:
90))//&
b10;
b10)
//addwrh91/1
100))//&
(temp==0)
b11;
//sda<
scl<
b0;
b11)//readADC
d3:
d5:
data[7]<
d8:
d13:
data[6]<
d18:
d23:
data[5]<
d28:
d33:
data[4]<
d38:
d43:
data[3]<
d48:
d53:
data[2]<
d58:
d63:
data[1]<
d68:
d73:
data[0]<
d78:
//ack
d83:
d88:
//querenwanbi
if(delay>
90)begin
delay<
//data_out<
=data;
ack<
//xunhuan
ack<
data_out<
end
endcase
end
endmodule
//displayinLED
moduleled_and_buzzer(Va,clk,led0,led1,led2,led3,buzzer,clr);
inputclk,clr,Va;
outputled0,led1,led2,led3,buzzer;
wire[3:
0]Va;
regled0,led1,led2,led3,buzzer;
regclk_1;
reg[25:
always@(clk_1)
begin
if(clk_1)
begin
led0<
led1<
led2<
led3<
buzzer<
end
elseif(Va<
4'
d1)
begin
d2)
d3)
d4)
else
end
always@(posedgeclkornegedgeclr)
if(!
clr)
cnt=25'
elseif(cnt==25'
d25000000)//T=1
clk_1=~clk_1;
else
cnt=cnt+1'
--三、数据转换
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
USEIEEE.STD_LOGIC_ARITH.ALL;
ENTITYtransIS
PORT(datain:
INSTD_LOGIC_VECTOR(7DOWNTO0);
q1,q2,q3,q4:
OUTSTD_LOGIC_VECTOR(3DOWNTO0));
ENDtrans;
ARCHITECTUREbehaveOFtransIS
SIGNALdata0,data1:
STD_LOGIC_VECTOR(15DOWNTO0);
SIGNALsum1,sum2,sum3,sum4:
STD_LOGIC_VECTOR(4DOWNTO
0);
SIGNALc1,c2,c3:
STD_LOGIC_VECTOR(4DOWNTO0);
BEGIN
data1<
="
0000000000000000"
WHENdatain(7DOWNTO4)="
0000"
ELSE
"
0000001100010100"
0001"
0000011000100111"
WHENdata