湖南科技学院
课程设计任务书
课 题 名 称 数字电压表设计
系 别 电子工程系 专 业 电子科学与技术 班 级 电科1001班 学 号 ************ 姓 名 安启祥
指 导 老 师 梁晓琳
2012年12月9日
基于FPGA数字电压表的设计
一、前言
EDA是电子设计自动化(Electronic Design Automation)的缩写,在20世纪60年代中期从计算机辅助设计(CAD)、计算机辅助制造(CAM)、计算机辅助测试(CAT)和计算机辅助工程(CAE)的概念发展而来的。 EDA技术就是以计算机为工具,设计者在EDA软件平台上,用硬件描述语言VHDL完成设计文件,然后由计算机自动地完成逻辑编译、化简、分割、综合、优化、布局、布线和仿真,直至对于特定目标芯片的适配编译、逻辑映射和编程下载等工作。本电压表的电路设计正是用VHDL语言完成的 。此次设计采用的是Altera公司 的Quartus II 7.0软件。本次设计的参考电压为2.5V,精度为0.01V。此电压表的设计特点为开发效率高。
通过软件编程下载到硬件实现,设计周期短,
二、设计要求
设计一个数字电压表,利用8位A/D转换器,将连续的模拟电信号转换成离散的数字电信号,并加以显示,要求其量程为0-2.5V,分辨率约为0.01V,三位数码管显示。其中一位为整数,两位为小数能正确显示小数点。
三、整体设计
1.数字电压表的基本原理
数字电压表整体设计框图,如下图所示,数字电压表系统由A/D(TLC549)转换模块、FPGA控制模块、数码显示模块三部分构成。FPGA控制模块控制外部A/D转换器自动采样模拟信号,通过A/D芯片转换为数字信号,再由FPGA控制模块控制数码管动态扫描向外部数码管显示电路输出数据。 控制 控制 TLC549 FPGA 数码显示 A/D转换器负责采集模拟电压,转换成8位数字信号送入FPGA转换控制模块,FPGA转换控制模块负责A/D转换的启动、地址锁存、输入通道选择、数据读取、转换等工作,数码显示模块负责显示当前的电压值。
2.A/D(TLC549)转换模块
TLC549是 TI公司生产的一种低价位、高性能的8位 A/D转换器,它以8位开关电容逐次逼近的方法实现 A/D转换,其转换速度小于
17us,最大转换速率为 40000HZ,4MHZ典型内部系统时钟,电源为 3V至 6V。它能方便地采用三线串行接口方式与各种微处理器连接,构成各种廉价的测控应用系统。 TLC549各引脚功能
REF+:正基准电压输入 2.5V≤REF+≤Vcc+0.1。
REF-:负基准电压输入端,-0.1V≤REF-≤2.5V。且要求:(R EF+)-(REF-)≥1V。
VCC:系统电源3V≤Vcc≤6V。 GND:接地端。
/CS:芯片选择输入端,要求输入高电平 VIN≥2V,输入低电平 VIN≤0.8V。
DATA OUT:转换结果数据串行输出端,与 TTL 电平兼容,输出时高位在前,低位在后。
ANALOGIN:模拟信号输入端,0≤ANALOGIN≤Vcc,当 ANALOGIN≥REF+电压时,转换结果为全“1”(0FFH),ANALOGIN≤REF-电压时,转换结果为全“0”(00H)。
I/O CLOCK:外接输入/输出时钟输入端,同于同步芯片的输入输出操作,无需与芯片内部系统时钟同步。
四、模块设计
1、部分设计程序 TLC549模块:
module TLC549(clk,reset,sdata,cs,dataout,clk_ad); input clk;
input reset,sdata; output [7:0]dataout; output clk_ad,cs;
reg [7:0]dataout,dataout_r;
reg cs;
reg clk_ad_r,clk_r; reg [7:0]count; reg [2:0]temp; reg [3:0]cnt; reg mark; reg flag;
parameter[2:0]s0=0,s1=1,s2=2;
reg [2:0]c_st;
//
内部逻辑功能描述
always@(posedge clk) //
begin if(count<119) count<=count+1; else begin count<=0;clk_r<=~clk_r;end end
always@(posedge clk) //
begin clk_ad_r<=~clk_r; end
机
always@(posedge clk_r or negedge reset) //begin if(!reset) c_st<=s0; else case(c_st)
s0:begin cs<=1;mark<=0;
if(temp==3)begin temp<=0; c_st<=s1;end else begin temp<=temp+1;c_st<=s0;end end
s1:begin cs<=0;mark<=1;c_st<=s2;end s2:begin cs<=0;mark<=1; if(flag==1)c_st<=s0; else c_st<=s2; end
default:c_st<=s0; endcase end
A/D转换模块: module lookup(V,q); input [7:0]V; output [11:0]q;
分频电路 时钟信号 状态 reg [11:0]q;
reg [11:0]HB,LB; wire d1,d2,d3;
always@(V)
begin case(V[7:4]) //--A/D值的高4位转换成3位BCD码
4'b1111: HB<=12'b001001000000; //--2.40 4'b1110: HB<=12'b001000100100; //--2.24 4'b1101: HB<=12'b001000001000; //--2.08 4'b1100: HB<=12'b000110010010; //--1.92 4'b1011: HB<=12'b000101110110; //--1.76 4'b1010: HB<=12'b000101100000; //--1.60 4'b1001: HB<=12'b000101000100; //--1.44
4'b1000: HB<=12'b000100101000; //--1.28 4'b0111: HB<=12'b000100010010; //--1.12
4'b0110: HB<=12'b000010010110; // --0.96 4'b0101: HB<=12'b000010000000; // --0.80 4'b0100: HB<=12'b000001100100; //--0. 4'b0011: HB<=12'b000001001000; //--0.48 4'b0010: HB<=12'b000000110010; //--0.32 4'b0001: HB<=12'b000000010110; //--0.16
4'b0000: HB<=12'b000000000000; // --0.00 default: HB<=12'b111111111111; Endcase
数码显示模块:
module scan_led(clk_1k,d,dig,seg); //模块名scan_led input clk_1k; //输入时钟
input[11:0] d; //输入要显示的数据 output[7:0] dig; //数码管选择输出引脚 output[7:0] seg; //数码管段输出引脚
reg[7:0] seg_r; //定义数码管输出寄存器 reg[7:0] dig_r; //定义数码管选择输出寄存器
reg[3:0] disp_dat; //定义显示数据寄存器 reg[2:0]count; //定义计数寄存器
assign dig = dig_r; //输出数码管选择
assign seg = seg_r; //输出数码管译码结果
always @(posedge clk_1k) //定义上升沿触发进程 begin
if(count<2)
count <= count + 1'b1; else count<=0; end
always @(posedge clk_1k)
begin
case(count) //选择扫描显示数据
3'd0:disp_dat = d[11:8]; //第一个数码管 3'd1:disp_dat = d[7:4]; //第二个数码管 3'd2:disp_dat = d[3:0]; //第三个数码管 endcase
case(count) //选择数码管显示位
3'd0:dig_r = 8'b01111111; //选择第一个数码管显示 3'd1:dig_r = 8'b10111111; //选择第二个数码管显示 3'd2:dig_r = 8'b11011111; //选择第三个数码管显示 endcase
case(count)
3'd0:seg_r[7]=0; 3'd1:seg_r[7]=1; 3'd2:seg_r[7]=1; endcase end
always @(disp_dat) begin
case(disp_dat) //七段译码
4'h0:seg_r[6:0] = 7'b1000000; 4'h1:seg_r[6:0] = 7'b1111001; 4'h2:seg_r[6:0] = 7'b0100100; 4'h3:seg_r[6:0] = 7'b0110000; 4'h4:seg_r[6:0] = 7'b0011001; 4'h5:seg_r[6:0] = 7'b0010010; 4'h6:seg_r[6:0] = 7'b0000010; 4'h7:seg_r[6:0] = 7'b1111000; 4'h8:seg_r[6:0] = 7'b0000000; default:seg_r[6:0] = 7'b1111111; 4'h9:seg_r[6:0] = 7'b0010000; endcase end
Endmodule
////显示显示0 1 //显示2 ////显示显示3 4 //显示5 ////显示显示6 7 //显示8 //显示9 2、仿真波形
CLK为TLC549的时钟输入信号,sdata为TLC549的数据输入信号,将其置为高电平,reset为复位信号,也置为高电平。Clk_ad为TLC549的输出时钟信号,cs为TLC549的片选信号,低电平有效;data_out为TLC549的8位数据输出端;c_st为状态机的状态。
五、结论
1.实验数据 数码管显示电压值 万用表测得电压值 2.总结
通过对FPGA芯片进行VHDL语言编程,控制TLC549A/D转换芯片,来实现数字电压表的功能。通过设计表明,VHDL具有很强的电路描述和建模能力.能从多个层次对数字系统进行建模和描
2.51V 2.447V 1.26V 1.221V 0.33V 0.320V 述,从而大大简化了硬件设计任务,提高了设计效率和可靠性。这种设计方法必将在未来的数字系统设计中发挥越来越重要的作用。
六、心得体会
经过这次设计,让我对FPGA人设计流程又有了一个全新的认识。FPGA需要由软件去设计,再由硬件来验证,这种模式正是我们所喜欢的。比如你去设计一个东西,如果只在软件上面仿真成功,而不拿去又硬件验证的话,那学起来兴趣也不大,当你一步一步去调试,使其实际效果与自己的设想完全吻合时,你便会有一种无比的成就感,这也会成为你不断去学习的源泉。