第一篇:数字频率计
//*********************************************************************
//* 标题: 简易数字频率计 //* 文件: topdesign.v
//* 作者: SJ&QJY
//* 日期: 2009.06.10 //* 修改: 2009.12.20
//* 软件: Xilinx ISE 7.1 SP4
//* 芯片: Xilinx Spartan2 FPGA(XC2S200-pq208)
//* 说明: 测频率并用LCD显示,从信号源接入一个信号(正弦波,三角波或者方波),经过AD1转换后,送入FPGA中。
//在FPGA中,使用双值法整形,得到标准的方波,然后测出频率,并送入1602中显示。经测试,其测频误差小于0.5%,其测频范围为10Hz-10MHz。
//********************************************************************* //* 注意: 输入信号电压峰峰值不要超过AD输入范围,即4V。
//*********************************************************************
//---------------module topdesign(clk, rst, lcd_rs, lcd_rw, lcd_en, lcd_d, ad1_clk, ad1_d);
input clk;
//时钟信号40MHz input rst;
//全局复位信号
output lcd_rs;//LCD数据/命令选择信号,'1'表示数据输入,'0'表示命令输入
output lcd_rw;
//LCD读/写信号,'1'表示读,'0'表示写
output reg lcd_en;
//LCD使能信号,'1'有效
output[7:0] lcd_d;
//LCD数据总线(8位)
output ad1_clk;
//AD时钟信号
input[11:0] ad1_d;
//AD9224,12位AD输入
//LCD时序常量信号
parameter[10:0] IDLE = 11'b00000000000;
//初始化
parameter[10:0] CLEAR = 11'b00000000001;
//清屏
parameter[10:0] RETURNCURSOR = 11'b00000000010;//归位
parameter[10:0] SETMODE = 11'b00000000100;
//设置输入模式。此状态为完成一个字符码传送后,AC自动减1,显示不发生移位
parameter[10:0] SWITCHMODE = 11'b00000001000;//显示开关控制
parameter[10:0] SHIFT = 11'b00000010000;//光标或显示移位
parameter[10:0] SETFUNCTION = 11'b00000100000;//功能设置:数据总线选8位还是4位
parameter[10:0] SETCGRAM = 11'b00001000000;//CGRAM的地址设置
parameter[10:0] SETDDRAM = 11'b00010000000;
//DDRAM地址设置
parameter[10:0] READFLAG = 11'b00100000000;//读忙标志BF和AC
parameter[10:0] WRITERAM = 11'b01000000000;
//写数据到CGRAM或DDRAM
parameter[10:0] READRAM = 11'b10000000000;
parameter cur_inc = 1'b1;
parameter cur_dec = 1'b0;
parameter cur_shift = 1'b1;
parameter cur_noshift = 1'b0;
parameter open_display = 1'b1;
parameter open_cur = 1'b0;
parameter blank_cur = 1'b0;
parameter shift_display = 1'b1;
parameter shift_cur = 1'b0;
parameter right_shift = 1'b1;
parameter left_shift = 1'b0;
parameter datawidth8 = 1'b1;
parameter datawidth4 = 1'b0;
parameter twoline = 1'b1;
parameter oneline = 1'b0;
parameter font5x10 = 1'b1;
parameter font5x7 = 1'b0;
reg[10:0] state;
//时序信号
reg[5:0] counter;
reg[3:0] div_counter;
reg flag;
//辅助时序信号
parameter DIVSS = 4'd15;
reg[5:0] char_addr;
reg[7:0] data_in;
//延迟参量信号
reg clk_int;
reg[19:0] clkcnt;
parameter[19:0] divcnt = 20'b***00000;
reg clkdiv;
wire tc_clkcnt;
//测频部分
parameter[15:0] ad_d_chankao1 = 16'b***1;
parameter[15:0] ad_d_chankao2 = 16'b***1;
reg[15:0] ad1_d_r;
//计数部分
reg[25:0] yimiao;
//用来计数
reg rukou;
//整形方波
reg[3:0] odata7;
//记录数据
reg[3:0] odata6;
reg[3:0] odata5;
reg[3:0] odata4;
reg[3:0] odata3;
reg[3:0] odata2;
//将近-25mV //将近25mV
reg[3:0] odata1;
reg[3:0] odata0;
reg[7:0] data7;
reg[7:0] data6;
reg[7:0] data5;
reg[7:0] data4;
reg[7:0] data3;
reg[7:0] data2;
reg[7:0] data1;
reg[7:0] data0;
reg yimiao_rst;
//将记录的数据转换成ASCII码,以便显示
//数据清零信号
//主程序
assign ad1_clk = clk;
always @(posedge clk)
begin
yimiao_rst =(yimiao == 26'b***00111111111)? 1'b0 : 1'b1;//一秒时清零信号有效
end //测频部分
always @(posedge clk)
begin
ad1_d_r <= {ad1_d, 4'b0000};
if(ad1_d_r > ad_d_chankao2)
rukou <= 1'b1;
if(ad1_d_r < ad_d_chankao1)
rukou <= 1'b0;
end //1秒钟测频
always @(posedge clk)
//每1秒钟循环一次
begin
if(yimiao == 26'b***01000000000)
yimiao <= 26'b***00000000000;
else
yimiao <= yimiao + 1;
end
//计数部分
always @(posedge rukou or negedge yimiao_rst)
if(~yimiao_rst)
begin
odata0 <= 4'b0000;
odata1 <= 4'b0000;
odata2 <= 4'b0000;
odata3 <= 4'b0000;
odata4 <= 4'b0000;
odata5 <= 4'b0000;
odata6 <= 4'b0000;
odata7 <= 4'b0000;
end
else if(yimiao < 26'b***00111111111)
begin
begin
if(odata0 == 4'b1001)
begin
odata0 <= 4'b0000;
if(odata1 == 4'b1001)
begin
odata1 <= 4'b0000;
if(odata2 == 4'b1001)
begin
odata2 <= 4'b0000;
if(odata3 == 4'b1001)
begin
odata3 <= 4'b0000;
if(odata4 == 4'b1001)
begin
odata4 <= 4'b0000;
if(odata5 == 4'b1001)
begin
odata5 <= 4'b0000;
if(odata6 == 4'b1001)
begin
odata6 <= 4'b0000;
if(odata7 == 4'b1001)
begin
odata7 <= 4'b0000;
end
else
begin
odata7 <= odata7 + 1;
end
end
else
begin
odata6 <= odata6 + 1;
end
end
else
begin
odata5 <= odata5 + 1;
end
end
else
begin
odata4 <= odata4 + 1;
end
end
else
begin
odata3 <= odata3 + 1;
end
end
else
begin
odata2 <= odata2 + 1;
end
end
else
begin
odata1 <= odata1 + 1;
end
end
else
begin
odata0 <= odata0 + 1;
end
end
end
//码制转换
always @(posedge clk)
begin
if(yimiao == 26'b***00111110110)
begin
data7 <= {4'b0011, odata7};
//将二进制BCD码转换成ASCII码,即1602可以显示的码值
data6 <= {4'b0011, odata6};
data5 <= {4'b0011, odata5};
data4 <= {4'b0011, odata4};
data3 <= {4'b0011, odata3};
data2 <= {4'b0011, odata2};
data1 <= {4'b0011, odata1};
data0 <= {4'b0011, odata0};
end
end
//时钟分频
always @(posedge clk)
begin
if(clkcnt == divcnt)
begin
clkcnt <= 20'b***00000;
end
else
begin
clkcnt <= clkcnt + 1;
end
end
assign tc_clkcnt =(clkcnt == divcnt)? 1'b1 : 1'b0;//tc_clkcnt 0.016s产生一次脉冲
always @(posedge tc_clkcnt)
begin
clkdiv <= ~clkdiv;
0.032s
end
always @(posedge clkdiv)
begin
clk_int <= ~clk_int;
end
//显示界面设置
always @(negedge clkdiv)
begin
lcd_en <= ~lcd_en;
end
always @(char_addr)
begin
case(char_addr)
6'b000000 : //I
//clkdiv 0.016s翻转一次,周期为
//clk_int 0.032s翻转一次,周期为0.064s
begin
data_in <= 8'b01001001;
end
6'b000001 ://n
begin
data_in <= 8'b01101110;
end
6'b000010 : //p
begin
data_in <= 8'b01110000;
end
6'b000011 :
//u
begin
data_in <= 8'b01110101;
end
6'b000100 :
//t
begin
data_in <= 8'b01110100;
end
6'b000101 : //空格
begin
data_in <= 8'b00100000;
end
6'b000110 :
//F
begin
data_in <= 8'b01100110;
end
6'b000111 :
//r
begin
data_in <= 8'b01110010;
end
6'b001000 :
//e
begin
data_in <= 8'b01100101;
end
6'b001001 :
//q
begin
data_in <= 8'b01110001;
end
6'b001010 :
//u
begin
data_in <= 8'b01110101;
end
6'b001011 : //e
begin
data_in <= 8'b01100101;
end
6'b001100 : //n
begin
data_in <= 8'b01101110;
end
6'b001101 : //c
begin
data_in <= 8'b01100011;
end
6'b001110 : //y
begin
data_in <= 8'b01111001;
end
6'b001111 :
//空格
begin
data_in <= 8'b00100000;
end
6'b101000 :
//“=”
begin
data_in <= 8'b00111101;
end
6'b101001 :
//若为零则显示空格
begin
if(data7 == 8'b00110000)
begin
data_in <= 8'b00100000;
end
else
begin
data_in <= data7;
end
end
6'b101010 : //若为零则显示空格
begin
data_in <= data6;
if(data6 == 8'b00110000 & data7 == 8'b00110000)
begin
data_in <= 8'b00100000;
end
else
begin
data_in <= data6;
end
end
6'b101011 :
//若为零则显示空格
begin
data_in <= data5;
if(data5 == 8'b00110000 & data6 == 8'b00110000 & data7 == 8'b00110000)
begin
data_in <= 8'b00100000;
end
else
begin
data_in <= data5;
end
end
6'b101100 : //若为零则显示空格
begin
data_in <= data4;
if(data4 == 8'b00110000 & data5 == 8'b00110000 & data6 == 8'b00110000 & data7 == 8'b00110000)
begin
data_in <= 8'b00100000;
end
else
begin
data_in <= data4;
end
end
6'b101101 :
//若为零则显示空格
begin
data_in <= data3;
if(data3 == 8'b00110000 & data4 == 8'b00110000 & data5 == 8'b00110000 & data6 == 8'b00110000 & data7 == 8'b00110000)
begin
data_in <= 8'b00100000;
end
else
begin
data_in <= data3;
end
end
6'b101110 :
//若为零则显示空格
begin
data_in <= data2;
if(data2 == 8'b00110000 & data3 == 8'b00110000 & data4 == 8'b00110000 & data5 == 8'b00110000 & data6 == 8'b00110000 & data7 == 8'b00110000)
begin
data_in <= 8'b00100000;
end
else
begin
data_in <= data2;
end
end
6'b101111 :
//若为零则显示空格
begin
data_in <= data1;
if(data1 == 8'b00110000 & data2 == 8'b00110000 & data3 == 8'b00110000 & data4 == 8'b00110000 & data5 == 8'b00110000 & data6 == 8'b00110000 & data7 == 8'b00110000)
begin
data_in <= 8'b00100000;
end
else
begin
data_in <= data1;
end
end
6'b110000 :
begin
data_in <= data0;
end
6'b110110 :
//H
begin
data_in <= 8'b01001000;
end
6'b110111 :
//z
begin
data_in <= 8'b01111010;
end
default :
begin
data_in <= 8'b00100000;
end
endcase
end
assign lcd_rs =(state == WRITERAM | state == READRAM)? 1'b1 : 1'b0;
assign lcd_rw =(state == CLEAR | state == RETURNCURSOR | state == SETMODE | state ==
SWITCHMODE | state == SHIFT | state == SETFUNCTION | state == SETCGRAM | state == SETDDRAM | state == WRITERAM)? 1'b0 : 1'b1;
assign lcd_d =(state == CLEAR)? 8'b00000001 :(state == RETURNCURSOR)? 8'b00000010 :(state == SETMODE)? {6'b000001, cur_inc, cur_noshift} :(state == SWITCHMODE)? {5'b00001, open_display, open_cur, blank_cur} :(state == SHIFT)? {4'b0001, shift_display, left_shift, 2'b00} :(state == SETFUNCTION)? {3'b001, datawidth8, twoline, font5x10, 2'b00} :(state == SETCGRAM)? 8'b01000000 :(state == SETDDRAM & counter == 0)? 8'b10000000 :(state == SETDDRAM & counter!= 0)? 8'b11000000 :(state == WRITERAM)? data_in : 8'bZZZZZZZZ;
//时序进程
always @(posedge clk_int or posedge rst)
begin
if(rst)
begin
state <= IDLE;
counter <= 0;
div_counter <= 0;
flag <= 1'b0;
char_addr <= 6'b000000;
end
else
case(state)
IDLE :
begin
if(flag == 1'b0)
begin
state <= SETFUNCTION;
flag <= 1'b1;
counter <= 0;
div_counter <= 0;
end
else
begin
if(div_counter < DIVSS)
begin
div_counter <= div_counter + 1;
state <= IDLE;
end
else
begin
div_counter <= 0;
state <= IDLE;
end
end
end
CLEAR :
begin
state <= SETMODE;
end
SETMODE :
begin
state <= WRITERAM;
end
RETURNCURSOR :
begin
state <= WRITERAM;
end
SWITCHMODE :
begin
state <= CLEAR;
end
SHIFT :
begin
state <= IDLE;
end
SETFUNCTION :
begin
state <= SWITCHMODE;
end
SETCGRAM :
begin
state <= IDLE;
end
SETDDRAM :
begin
state <= WRITERAM;
end
READFLAG :
begin
state <= IDLE;
end
WRITERAM :
//可用来修改,实现1602的输出显示
begin
if((counter >= 6'd0 & counter <= 6'd14)|(counter >= 6'd40 & counter <= 6'd54))
begin
state <= WRITERAM;
//一行同时只能显示16个字符,第二行的首地址为40
char_addr <= char_addr + 1;
counter <= counter + 1;
end
else if(counter > 6'd14)
//换到第二行显示
begin
state <= SETDDRAM;
counter <= 6'd40;
char_addr <= 6'b101000;
end
else
begin
state <= SHIFT;
state <= READRAM;
end
end
READRAM :
begin
state <= IDLE;
end
default :
begin
state <= IDLE;
end
endcase
end endmodule
第二篇:数字频率计设计
数字频率计设计 1.设计任务
设计一简易数字频率计,其基本要求是:
1)测量频率范围1Hz~10Hz,量程分为4档,即×1,×10,×100,×1000。2)频率测量准确度fx2103.fx3)被测信号可以是下弦波、三角波和方波。4)显示方式为4位十进制数显示。5)使用EWB进行仿真。2.设计原理及方案
频率的定义是单位时间(1s)内周期信号的变化次数。若在一定时间间隔T内测得周期信号的重复变化次数为N,则其频率为
f=N/T 据此,设计方案框图如图1所示。
图1 数字频率计组成框图
其基本原理是,被测信号ux首先经整形电路变成计数器所要求的脉冲信号,频率与被测信号的频率fx相同。时钟电路产生时间基准信号,分频后控制计数与保持状态。当其高电平时,计数器计数;低电平时,计数器处于保持状态,数据送入锁存器进行锁存显示。然后对计数器清零,准备下一次计数。其波形逻辑关系图如图2所示。3.基本电路设计 1)整形电路
整形电路是将待测信号整形变成计数器所要求的脉冲信号。电路形式采用由555定时器所构成的施密特触发器,电路如图XXX所示。若待测信号为三角波,输入整形电路,设置分析为瞬态分析,启动电路,其输入、输出波形如图XXX所示。可见输出为方波,二者频率相同。
2)时钟产生电路
时钟信号是控制计数器计数的标准时间信号,其精度很大程度上决定了频率计的频率测量精度。当要求频率测量精度较高时,应使用晶体振荡器通过分频获得。在此频率计中,时钟信号采用555定时器构成的多谐振荡器电路,产生频率为1Kz的信号,然后再进行分频。多谐振荡器电路如图XXX所示。由555定时器构成多谐振荡器的周期计算公式为
XXXXXXXXXX 取XXXXXXXXXXXXXX,则得到振荡频率为1Kz的负脉冲,其振荡波形如图XXX所示。3)分频器电路
采用计数器构成分频电路,对1Kz的时钟脉冲进行分频,取得不同量程所需要的时间基准信号,实现量程控制。1Kz的时钟脉冲,对其进行3次10分频,每个10分频器的输出信号频率分别为100Hz,10Hz,1Hz三种时间基准信号。对应于以1Kz,100Hz,10Hz,1Hz的信号作为时间基准信号时,相应的量程为×1000,×100,×10,×1。
构成10分频带电路是采用十进制计数器74LS160实现的。具体电路及其输入、输出波形如图XXX所示。
(1)T触发器
T触发器电路是用来将分频带器输出阻抗的窄脉冲整形为方波,因为计数器需要用方波来控制其计数/保持状态的切换。整形后方波的频率为频器输出信号频率的一半,则对应于1Kz,100Kz,10Kz,1Hz的信号,T触发器输出信号的高电平持续时间分别为0.001s,0.01s,0.1s,1s。T触发器采用JK触发器7473为实现,其电路连接图及其输入、输出波形如图XXX所示。
(2)单稳触发器
单稳触发器用于产生一窄脉冲,以触发锁存器,使计数器在计数完毕后更新锁存器数值。单稳触发器电路采用555定时器实现,为了保证系统正常工作,单稳电路产生的脉冲宽度不能大于该量程分频带器输出信号的周期。例如,计数器的最大量程是×1000,对应分频带器输出的时间基准信号频率为1000Hz,周期是1ms。取单稳电路输出脉冲宽度TW=0.1ms。根据TW=1.1RC,取C=0.01Uf,则R=9.8KΩ,取标称什为10KΩ。单稳触发器输入信号是T触发器输出信号经Rd、Cd组成的微分器将方波变成尖脉冲后加到555定时器的触发器。电路图及输入、输出波形如图XXX所示。
(3)延迟反相器
延时反相器的功能是为了得到一个对计数器清零的信号。由于计数器清零是低电平有效,而且计数器清零必须在单稳触发信号之后,故延迟反相器是在上述单稳电路之后,再加一级单稳触发电路,且在其输出端加反相器输出。其输入、输出波形如图XXX所示。(4)计数器
计数器在T触发器输出信号的控制下,对经过整形的待测信号进行脉冲计数,所得结果乘以量程即为待测信号频率。
根据精度要求,采用4个十进制计数器级联,构成N=1000计数器。十进制计数器仍采用74LS160实现。其电路图如图XXX所示。其中计数器的清零信号由延迟反相器提供,控制信号由T触发器提供,计数器输出结果送入锁存器。
(5)锁存器和显示
计数器的结果进入锁存器锁存,4个七段数码管显示测试信号的频率。锁存器使用了两片8D集成触发器实现,其控制信号来自于延迟反相器,具体电路如图XXX所示。
(6)数字频率计的总体电路
图XXX是数字频率计的总体电路图。
4.测试
搭建好以上电路以后,进行调试,首先分模块进行调试,待每一个模块调试正确后,不规则进行联调。因为整个电路的分析是瞬态分析,故总体电路的分析需要较长时间。以上仅仅是学生所做综合电路分析与设计的例子,由于EWB5.12教学版本库元件的限制,有些电路与系统无法进行全部电路的仿真(例如收发信通信系统等),但有些局部电路也可以进行仿真,从而节省对这部分电路设计化费的时间。
第三篇:数字频率计实验报告
数字电路与系统课程设计
大连理工大学城市学院
数字电路与系统课程设计
设计题目:数字频率计
学 院:电子与自动化学院 专 业: 自动化 学 生: 揣智涵 同 组 人: 王晓宁 周英茹 指导教师: 于海霞 完成日期: 2012年3月26日
数字电路与系统课程设计
目 录
第一章 设计任务
1.1项目名称 1.2项目设计说明 1.2.1设计任务和要求 1.2.2进度安排 1.3项目总体功能模块图
第二章 需求分析
2.1问题基本描述
(要求分析得出整个系统流程图)2.2系统模块分解及各模块功能的基本要求
第三章 设计原理
3.1 设计原理 3.2 MAXPLUSII介绍
第四章 系统功能模块设计
4.1 FEN模块
4.1.1 FEN模块流程图
4.1.2 输入输出引脚及其功能说明 4.1.3 程序代码实现 4.2 SEL模块
4.2.1 SEL模块流程图
4.2.2输入输出引脚及其功能说明 4.2.3程序代码实现
数字电路与系统课程设计
4.3 CORNA模块
4.3.1 CORNA模块流程图
4.3.2 输入输出引脚及其功能说明 4.3.3 程序代码实现 4.4 LOCK模块
4.4.1 LOCK模块流程图
4.4.2 输入输出引脚及其功能说明 4.4.3 程序代码实现 4.5 CH模块
4.5.1 输入输出引脚及其功能说明 4.5.2 程序代码实现 4.6 DISP模块
4.6.1 输入输出引脚及其功能说明 4.6.2 程序代码实现
第五章调试并分析结果
5.1输入说明 5.2预计输出 5.3测试结果记录 5.4测试结果分析
第六章 结论 心得体会 参考文献
数字电路与系统课程设计
第一章 设计任务
1.1 项目名称:数字频率计 1.2 项目设计说明
1.2.1 设计任务和要求 此频率计共分4档: 一档:0~9999Hz;二档:10~99.99kHZ;三档:100.0~999.9kHz;,四档:1.000~999MHz;在换挡的设计方面,此程序突破了以往改变闸门时间的方法,使自动换挡的实现更加简单可靠。1.2.2 进度安排
第一节课:画出模块及程序流程图
第二节课:调试各模块程序使其无误
第三节课:连接整个程序并下载到试验箱是数字频率计的功能实现
第四节课:改进程序设计实现创新,然后完成课程设计报告
第五节课:完成答辩 1.3 项目总体功能模块图如下
数字电路与系统课程设计
图1-1
数字电路与系统课程设计
第二章 需求分析
2.1 问题基本描述
所谓频率,就是周期信号在单位时间(1秒)内变化的次数。频率计的测量范围为1MHZ,为了测量精确量程分别为10KHZ,100KHZ,1000KHZ和1MHZ四个档。即最大读数分别为9.999KHZ,99.99KHZ,999.9KHZ,999MHZ。要求两成自动换挡。其具体功能如下:
(1)当量程超过999时,自动增大一档,下一次测量时量程大一档;
(2)当超过测量范围时,显示溢出,报警器报警。(3)小数点位置随量程变化自动移位。
(4)采用记忆显示方法,在测量过程中不显示数据,在测量完成以后显示测频结果,并将此结果 保存到下次测量结束,显示时间不少于1秒。
(5)根据频率计的测频原理,可以选择合适的时基信号即阀门时间,对输入信号脉冲进行计数,实现测频的目的。
(6)根据数字频率计的设计原理,可以将数字频率计设计分为五个模块来实现其功能。即分频模块,控制模块,计数模块,锁存模块和显示模块。用CLDH语言进行编程。
(7)弄清什么情况下是测频率,就是选择合适的时基信号的问题。测频率时以输入信号作为时钟信号,因为输入信号的频率大于频率计的基准频率。:
数字电路与系统课程设计
数字频率计的系统流程图如下
图2-1
数字电路与系统课程设计
2.2 系统模块分解及各模块功能的基本要求
计数器在各个档是被反复应用的,如果在各个档分别设计计数器就造成资源的浪费,而且在测周期和频率的时候,计数器的时基信号和输入信号要进行调换,但计数功能是一样的,所以将计数器设为单独的模块。七段译码器也是被重复使用的,也设成单独的模块,这样的话就不用在重复使用的时候重复书写译码电路了。总体来说数字频率计分为五个模块来设计,即分频模块计数 模块,锁存模块,预测控制信号发生器,显示模块。
分频模块为计数模块提供1秒的阀门时间。计数模块是整个程序的核心,它完成在1秒的时间里对被测信号计数的功能,并通过选择输出数据实现自动换挡的功能。锁存模块在信号L的下降沿到来时将信号A4,A3,A2,A1锁存。显示模块对应于数码管片选信号,将相应的数据送出,其中档位也通过数码管显示。
数字电路与系统课程设计
第三章 设计原理
3.1 设计原理
众所周知,频率信号易于传输,抗干扰性强,可以获得较好的测量精度。因此,频率检测是电子测量领域最基本的测量之一。频率计的基本原理是用一个频率稳定度高的频率源作为基准时钟,对比测量其他信号的频率。通常情况下计算每秒内待测信号的脉冲个数,即闸门时间为1 s。闸门时间可以根据需要取值,大于或小于1 s都可以。闸门时间越长,得到的频率值就越准确,但闸门时间越长,则每测一次频率的间隔就越长。闸门时间越短,测得的频率值刷新就越快,但测得的频率精度就受影响。一般取1 s作为闸门时间。
数字频率计的关键组成部分包括测频控制信号发生器、计数器、锁存器、译码驱动电路和显示电路,其原理框图如图3-1所示。
图3-1数字频率计原理图
3.2 MAXPLUSII介绍
MAX+PLUSⅡ(Multiple Array and Programming Logic User System)开发工具是Altera公司推出的一种EDA工具,具有灵活高效、使用便捷和易学易用等特点。Altera公司在推出各种CPLD的同时,也在不断地升级相应的开发工具软件,已从早起的第一代A+PLUS、第二代MAX+PLUS发展到第三代MAX+PLUSⅡ和第四代
数字电路与系统课程设计
Quartus。使用MAX+PLUSⅡ软件,设计者无需精通器件内部的复杂结构,只需用业已熟悉的设计输入工具,如硬件描述语言、原理图等进行输入即可,MAX+PLUSⅡ就会自动将设计转换成目标文件下载到器件中去。MAX+PLUSⅡ开发系统具有以下特点。(1)多平台。MAX+PLUSⅡ软件可以在基于PC机的操作系统如Windows95、Windows98、Windows2000、Windows NT下运行,也可以在Sun SPAC station等工作站上运行。
(2)开放的界面。MAX+PLUSⅡ提供了与其他设计输入、综合和校验工具的接口,借口符合EDIF 200/300、LPM、VHDL、Verilog-HDL等标准。目前MAX+PLUSⅡ所支持的主流第三方EDA工具主要有Synopsys、Viewlogic、Mentor、Graphics、Cadence、OrCAD、Xilinx等公司提供的工具。
(3)模块组合式工具软件。MAX+PLUSⅡ具有一个完整的可编程逻辑设计环境,包括设计输入、设计处理、设计校验和下载编程4个模块,设计者可以按设计流程选择工作模块。(4)与结构无关。MAX+PLUSⅡ开发系统的核心——Compiler(编译器)能够自动完成逻辑综合和优化,它支持Altera的Classic、MAX7000、FLEX8000和FLEX10K等可编程器件系列,提供一个与结构无关的PLD开发环境。
(5)支持硬件描述语言。MAX+PLUSⅡ支持各种HDL设计输入语言,包括VHDL、Verilog-HDL和Altera的硬件描述语言AHDL。(6)丰富的设计库。MAX+PLUSⅡ提供丰富的库单元供设计者调用,其中包括一些基本的逻辑单元,74系列的器件和多种特定功能的宏功能模块以及参数化的兆功能模块。调用库单元进行设计,可以大大减轻设计人员的工作量,缩短设计周期。
数字电路与系统课程设计
第四章 系统功能模块
4.1 FEN 模块
4.1.1 FEN 模块流程图
图4-1
数字电路与系统课程设计
4.1.2输入输出引脚及其功能说明
模块FEN如图9-87所示。通过对4MHz时钟的分频得到0.5Hz时钟,为模块CORNA提供1s的闸门时间。CLK:输入时钟信号;Q:输出分频后的基准信号。程序代码的实现如下
library ieee;use ieee.std_logic_1164.all;entity fen is
port(clk:in std_logic;
q: out std_logic);
end fen;architecture fen_arc of fen is begin process(clk)variable cnt: integer range 0 to 999999;variable x: std_logic;begin
if clk'event and clk = '1' then
if cnt<999999 then
cnt:=cnt+1;
else
cnt:=0;
x:= not x;
end if;
end if;
q<=x;end process;end fen_arc;
图4-2
数字电路与系统课程设计
4.2 SEL模块
4.2.1 SEL 模块流程图
图4-3 4.2.2 SEL模块输入输出引脚及其功能说明
CLK:基准时钟信号; Q[2..0]:产生数码管的片选信号。4.2.3 程序代码实现
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity sel is port(clk: in std_logic;
图4-4 q:out std_logic_vector(2 downto 0));
end sel;
数字电路与系统课程设计
architecture sel_arc of sel is begin process(clk)variable cnt:std_logic_vector(2 downto 0);begin
if clk'event and clk='1' then
cnt:=cnt+1;
end if;
q<=cnt;end process;end sel_arc;4.3 模块CORNA 4.3.1 CORNA 模块流程图
图4-5 14
数字电路与系统课程设计
4.3.2 输入输出引脚及其功能说明
该模块是整个程序的核心,它完成在1s的时间里对被测信号计数的功能,并通过选择输出数据实现自动换挡的功能输入输出引脚及其功能说明CLR:复位按钮;SIG:待测频率信号;DOOR:基准时钟频率;ALM:蜂鸣器;DANG[3..0]:档位值;Q0~4[3..0]:计算后的频率值。4.3.3程序代码实现
library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity corna is port(clr,sig,door : in std_logic;
alm : out std_logic;
q3,q2,q1,q0,dang : out std_logic_vector(3 downto 0));end corna;
architecture corn_arc of corna is begin process(door,sig)variable c0,c1,c2,c3,c4,c5,c6: std_logic_vector(3 downto 0);variable x:std_logic;
begin
if sig'event and sig='1' then
if door='1' then
if c0<“1001”then
c0:=c0+1;
else
c0:=“0000”;
if c1<“1001” then
c1:=c1+1;
else
c1:=“0000”;
图4-6
数字电路与系统课程设计
if c2<“1001” then
c2:=c2+1;
else
c2:=“0000”;
if c3<“1001” then
c3:=c3+1;
else
end if;
end if;
end if;
end if;end if;end if;end if;else if clr = '0' then
alm <= '0';end if;c6:=“0000”;c5:=“0000”;c4:=“0000”;c3:=“0000”;c2:=“0000”;
c3:=“0000”;if c4<“1001” then c4:=c4+1;else c4:=“0000”;if c5<“1001” then
c5:=c5+1;else
c5:=“0000”;if c6<“1001” then
c6:=c6+1;else
c6:=“0000”;
alm<='1';
数字电路与系统课程设计
c1:=“0000”;c0:=“0000”;end if;if c6/=“0000” then q3<=c6;q2<=c5;q1<=c4;q0<=c3;dang<=“0100”;elsif c5/=“0000” then q3<=c5;q2<=c4;q1<=c3;q0<=c2;dang<=“0011”;elsif c4/=“0000” then q3<=c4;q2<=c3;q1<=c2;q0<=c1;dang<=“0010”;else q3<=c3;q2<=c2;q1<=c1;q0<=c0;dang<=“0001”;end if;end if;end process;end corn_arc;
数字电路与系统课程设计
4.4 模块LOCK 4.4.1 LOCK 模块流程图
图4-7 4.4.2 输入输出引脚及其功能说明
该模块实现锁存器的功能,在信号L的下降沿到来时信号A4、A3、A2、A1锁存。输入输出引脚及其功能说明L:基准时钟信号;A0~4[3..0]:接受计数器CORNA传过来的值并锁存;Q0~4[3..0]:向数据选择器传值。4.4.3 程序代码实现
library ieee;use ieee.std_logic_1164.all;entity lock is
数字电路与系统课程设计
port(l: in std_logic;
a4,a3,a2,a1,a0:in std_logic_vector(3 downto 0);
q4,q3,q2,q1,q0:out std_logic_vector(3 downto 0));end lock;architecture lock_arc of lock is begin process(l)variable t4,t3,t2,t1,t0:std_logic_vector(3 downto 0);begin
if l'event and l='0' then
t4:=a4;
t3:=a3;
t2:=a2;
t1:=a1;
t0:=a0;
end if;
q4<=t4;
q3<=t3;
q2<=t2;
q1<=t1;
q0<=t0;end process;
图4-8 end lock_arc;4.5 模块CH
4.5.1 输入输出引脚及其功能说明
该模块对应于数码管片选信号,将相应的数据送出,其中档位也通过数码管显示。输入输出引脚及其功能说明SEL[2..0]:接受SEL模块传来的数码管片选信号;A[3..0]:接受锁存器传来的数码管片选信号;DANG[3..0]:接受锁存器传来的档位信号;Q[3..0]:传出数码管位选信号。4.5.2 程序代码实现
library ieee;
数字电路与系统课程设计
use ieee.std_logic_1164.all;entity ch is port(sel:in std_logic_vector(2 downto 0);
a3,a2,a1,a0,dang:in std_logic_vector(3 downto 0);
q:out std_logic_vector(3 downto 0));end ch;
architecture ch_arc of ch is begin process(sel)begin
case sel is
when “110” =>q<=a0;
when “010” =>q<=a1;when “100” =>q<=a2;
图4-9
when “000” =>q<=a3;
when “101” =>q<=dang;
when others =>q<= “1111”;end case;end process;end ch_arc;4.6 DISP模块
4.6.1输入输出引脚及其功能说明
D[3..0]:接受CH传出的数码管位选信号;Q[6..0]:译码出数码管位选信号; 4.6.2程序代码实现
use ieee.std_logic_1164.all;entity disp is port(d:in std_logic_vector(3 downto 0);
q:out std_logic_vector(6 downto 0));
图4-10 end disp;
数字电路与系统课程设计
architecture disp_arc of disp is
begin process(d)begin
case d is
when “0000” =>q<=“0111111”;
when “0001” =>q<=“0000110”;
when “0010” =>q<=“1011011”;
when “0011” =>q<=“1001111”;
when “0100” =>q<=“1100110”;
when “0101” =>q<=“1101101”;
when “0110” =>q<=“1111101”;
when “0111” =>q<=“0100111”;
when “1000” =>q<=“1111111”;
when “1001” =>q<=“1101111”;
when others =>q<=“0000000”;
end case;end process;end disp_arc;
数字电路与系统课程设计
第五章
5.1输入说明
调试并分析结果
SIG:接1KHz频率;CLR:接开关;CLK:接4MHz频率。
5.2预计输出
低两位数码管显示‘1’;高四位数码管显示‘1000’。
5.3 测试结果记录
低两位数码管显示‘1’;高四位数码管显示‘1000’。
5.4 测试结果分析
本频率计满足试验要求,使用周期和直接测量法进行测量,这样会减小误差。实验中也遇到了很多问题,在器件在线编程过程中,program各项操作无法进行,如果是首次编程,则需要设置下载端口,如果还比能进行操作,可能是芯片或者试验箱出现问题,所以应该换芯片或试验箱。在连接引脚是要特别注意,否则显示管无法显示。此外此试验还有需要改进的地方,比如测量频率的精度和灵敏度。
待测信号给的是1KHz,数码管档位显示为一档(0~9999Hz);频率显示为‘1000’;与预计输出完全一样。因为基准信号和待测信号是同一个信号源,故如此准确。也论证了上述设计的正确性。
数字电路与系统课程设计
图5-1 如上图,待测信号sig 10KHz,clk接1MHz显示如图,第一行和第二行为脉冲频率,第三行为档位,10KHz的待测信号档位为二档。
数字电路与系统课程设计
第六章 结论
心得体会
经过这次的实验课程设计,我学到了如何将多个程序绑在一起使用并构成一个完整的系统。在老师的指导下、在我们实验设计小组的共同努力下、在其他同学的热情帮助下,我们完整滴完成了《数字频率计》的设计、组装,并做了些创新。
虽然实验成功,我们同样在实验过程中遇到了一些问题: 1.刚开始时候的设计是每组组员做一部分,但是问题就是有些系数不能同一。因此造成了一开始实验进展缓慢。2.在实验过程中,器材的问题也被我们遇到了。因此也得到了些经验:要对自己的实验成果由信心,不要一出问题就从程序中找问题。可能对你最大的阻碍就是你没有考虑到的器材问题。
3.在最后仿真时候,导线的顺序也是常出问题的地方。由于没有及时发现问题的所在,我们小组花费了整整一节课的时间在改程序,浪费了许多宝贵时间。
参考文献
【1】VHDL数字电路设计与应用与实践教程 【2】第2版王振红 主编机械工业出版社
数字电路与系统课程设计
第四篇:简易数字频率计(数字电路课程设计)
数字电路课程设计报告
1)设计题目
简易数字频率计
2)设计任务和要求
要求设计一个简易的数字频率计,测量给定信号的频率,并用十进制数字显示,具体指标为:
1)测量范围:1HZ—9.999KHZ,闸门时间1s;
HZ—99.99KHZ,闸门时间0.1s;
HZ—999.9KHZ,闸门时间10ms;
KHZ—9999KHZ,闸门时间1ms;
2)显示方式:四位十进制数
3)当被测信号的频率超出测量范围时,报警.3)原理电路和程序设计:
(1)整体电路
数显式频率计电路
(2)单元电路设计;
(a)时基电路
(b)放大逻辑电路
(c)计数、译码、驱动电路
(3)说明电路工作原理;
四位数字式频率计是由一个CD4017(包含一个计数器和一个译码器)组成逻辑电路,一个555组成时基电路,一个9014形成放大电路,四个CD40110(在图中是由四个74LS48、四个74LS194、四个74LS90组成)及数码管组成。
两个CD40110串联成一个四位数的十进制计数器,与非门U1A、U1B构成计数脉冲输入电路。当被测信号从U1A输入,经过U1A、U1B两级反相和整形后加至计数器U13的CP+,通过计数器的运算转换,将输入脉冲数转换为相应的数码显示笔段,通过数码管显示出来,范围是1—9。当输入第十个脉冲,就通过CO输入下一个CD40110的CP+,所以此四位计数器范围为1—9999。
其中U1A与非门是一个能够控制信号是否输入的计数电路闸门,当一个输入端输入的时基信号为高电平的时候,闸门打开,信号能够通过;否则不能通过。
时基电路555与R2、R3,R4、C3组成低频多谐振荡器,产生1HZ的秒时基脉冲,作为闸门控制信号。计数公式:来确定。
与非门U2A与CD4017组成门控电路,在测量时,当时基电路输出第一个时基脉冲并通过U2A反相后加至CD4017的CP,CD4017的2脚输出高电平从而使得闸门打开。1s后,时基电路送来第二个脉冲信号,CD4017的2脚变为低电平,闸门关闭,测量结束。数码管显示即为所测频率。当555第三个脉冲送过来的时候,电路保持间歇1S,第四个脉冲后高电平加至R,使计数器复位。为下一次计算准备。
(4)元件选择。
资
料
元
件
标号
封装
数量
芯片
CD40110
GK7491AG
陶瓷熔扁平
CD4017
62F2X6KE4
陶瓷熔扁平
74LS00
陶瓷熔扁平
74LS10
陶瓷熔扁平
NE555
K104G4
双列直插型号
显示器
七段共阴数码管
电阻
300Ω
1KΩ
5.1KΩ
10KΩ
100KΩ
1MΩ
10KΩ(滑动)
电容
1000PF
0.1μF
100μF
二极管
1N4148
发光LED
开关
单刀双掷
导线
导线
若干
三极管
9014
电源
12V直流电源
4)电路和程序调试过程与结果:
a)、设计逻辑流程:
b)、理论波形图:
c)、仿真波形图:
1)、时基电路
2)、未、已经过施密特的波形:
d)、误差分析:
本实验的误差来自多方面的原因:一、时基电路NE555的滑动变阻器调节导致误差;二、闸门开放时间与信号输入时间的冲突导致测量不准确;三、整体电路的阻抗、容抗对电路信号的影响。
对于第一点,先计算相关的滑动变阻器的相应阻值大小,然后可以在关闭电源的情况下用万用表测量后才进行测量;第二点有点系统的偶然性;第三点可以尽量减少电路布局,从而减少相应的影响。
5)总结
这个电路多处使用了集成IC芯片,让电路更加简洁明了,并且提高了电路的安全性、可行性,减少了整个电路的功耗和整个电路的布线。但是此电路没有完全地符合实验要求:首先,整个电路没有施密特触发器,输入信号放大电路,数码管的小数点驱动,满位报警电路。因此我首先加入以三极管9014为核心的放大电路;然后用74LS00两个双输入与非门构成施密特触发器,对输入信号进行整形;对于报警电路,由于集成IC没有译码电路引脚,所以选择了一个8输入与非门和一个74LS00结成,这样可以充分考虑到唯一性;还有就是它的计数不是直接显示频率,而是显示一个数字,再与闸门的时候计算才可以得出真正的频率。
总体来说,电路还是存在一点小问题没有得到很好的解决,因为74LS00组成的施密特触发器没有很好地整形波,在示波器上出现脉冲波,还得于计算,可以改为以NE555组成的施密特电路。改用其他的数码管驱动,从而驱动小数点。
通过这次实验,让我认识到数字电路的万千变化,集成IC的推出,大大提高安全性和可行性。理解了科学就是力量。最主要是学习到设计电路的思想以为加强自己的焊接能力。让自己的电子技术更上一层楼。
附录:完整的电路PCB图,完整的源程序名列表(不需要把源程序打印出来,作为电子文档提交)。
附录一:
附录二:
第五篇:verilog简易数字频率计报告
一、实验原理
根据原理图,将计数器模块、显示模块、扫描模块、译码器模块等分别做出。其原理是在1S内用待测信号给计数器计数,并在一秒结束时给计数器清零,计出来用缓存器缓存,在数码管中显示出来。
二、方案论证
一、通过50M的时钟进行计数获得精密的1HZ——计数器用Verilog HDL语言实现在1HZ为底电平时计数——门控电路用或门开启——1HZ为高电平时进行数据锁存与显示——利用Verilog HDL语言使前面的0不显示。
计数器用Verilog HDL语言在写代码时可以用复制粘贴的方法可以简便的实现。通过50M的时钟进行计数获得精密的1HZ后只是经过很短的时间内进行计数器的清零及数据的琐存,并且得到的是1HZ的精密时钟。把锁存的数据进行清0的转换后利用分时扫描,后通过数码管译码显示。
说明:
Cnt9999:0000~9999计数器; Buffer:锁存器; Scan:扫描显示 共8个模块
三、实验步骤
一、计数器模块 计数器模块的仿真波形
二、锁存模块
利用32位的D触发器进行储存计数器送给它的数据。在时钟为上升沿的时候触发保存数据。锁存模块的源代码:
module buffer_32(clr,clear,in,out);input
clear,clr;input[31:0] in;output[31:0] out;reg[31:0]
out;always@(posedge clear or negedge clr)
if(!clr)out<=0;
//else if(clear)out=in;
else out<=in;
endmodule
三、转化清零模块 波形仿真波形
module cnt9999(clr,clk,q,c);
input clr,clk;output c;output [15:0]q;reg c;reg [15:0]q;
always @(posedge clk or negedge clr)begin
if(!clr)begin q[15:0]<=0;c<=1'b0;end
else if(q[15:0]==16'H9999)begin q[15:0]<=0;c<=1'b1;end
else if(q[11:0]==12'H999)begin q[15:0]<=q[15:0]+12'H667;c<=1'b0;end
else if(q[7:0]== 8'H99)begin q[15:0]<=q[15:0]+8'H67;c<=1'b0;end
else if(q[3:0]== 4'H9)begin q[15:0]<=q[15:0]+4'H7;c<=1'b0;end
else begin q[15:0]<=q[15:0]+1'b1;c<=1'b0;end end endmodule
四、扫描显示模块
把存储的数据分别分给8个数码管,利用循环扫描即可显示出所要显示的数据。
扫描显示模块的仿真波形
module scan(clk,q);input clk;output [2:0]q;reg
[2:0]q;
always @(posedge clk)
begin
q=q+1;
end
endmodule
四、引脚分配
五、实验总结
频率就是信号在1s内发生相同变化的次数,简易频率计就是基于这个原理设计的。我们先产生一个低电平为1s,高电平为1/50M秒的周期信号clk,用该信号与待测信号相与作为计数器的输入时钟,并把clk的上升沿作为缓存器的开关,把clk的高电平作为计数器的清零信号,这样就能保证缓冲器中存放的始终是待测信号在一秒内的跳变次数,也即待测信号的频率。
实验的原理尽管很清楚,但真正看到实验现象还是经历了一番波折,在写8选1数据选择器的时候,定义模块端口时,由于疏忽,把四位位宽漏写成了1位,结果在数码管上显示的始终只有0和1两种数字。为了改正这个错误,我把程序的主要模块都检查了一遍,结果不管怎么改实验现象都没有出来,这让我郁闷了很长一段时间,原理明明是对的,为什么就没有效果呢?最后我把整个程序都打印出来,一行一行地检查,最后终于找到了症结所在,就是8选1数据选择器的位宽弄错了!经历了这次错误,让我明白了写程序还是不能大意,8选1数据选择器虽然简单,却因为位宽这个小小的错误让我浪费了很长的时间,检查错误时也因为其简单而没有认真对待。