基于FPGA的数字频率计.docx
- 文档编号:7237103
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:14
- 大小:84.01KB
基于FPGA的数字频率计.docx
《基于FPGA的数字频率计.docx》由会员分享,可在线阅读,更多相关《基于FPGA的数字频率计.docx(14页珍藏版)》请在冰豆网上搜索。
基于FPGA的数字频率计
摘要
介绍了一种运用FPGA开发软件QuartusⅡ设计的数字频率计。
使用VerilogHDL硬件描述语言编程,该数字频率计能够准确的测量1Hz~3MHz脉冲信号,测量误差小。
关键词:
数字频率计fpgaVerilogHDL
引言
频率测量是电子测量领域里的一项重要内容,而高精度频率计的应用尤为广泛。
目前,宽范围、高精度数字式频率计的设计方法大都采用单片机加高速、专用计数器芯片来实现。
本文设计的高精度频率计除了对被测信号的整形部分、键输入和最后的数码显示部分必须用硬件实现以外,其余全部采用VerilogHDL编程设计,并下载在一片FPGA(FieldProgrammableGatesArray———现场可编程门阵列)芯片上,整个系统非常精简,并能够达到同样的技术指标。
根据不同的需要还可以重新编程下载,进行升级。
FPGA器件作为系统控制的核心,其灵活的现场可更改性,可再配置能力,对系统的各种改进非常方便,在不更改硬件电路的基础上还可以进一步提高系统的性能。
具有高速、精确、可靠、抗干扰性强和现场可编程等优点。
设计原理
本文设计了一个数字频率计的模型,其接口信号如图
(一)所示。
图
(一) 数字频率计模型方框图
数字频率计设计框图如图1所示,主要由分频器、测量频率控制电路、十
进制计数器、寄存器、液晶驱动等六个模块组成。
当系统正常工作时,
系统时钟经分频得到的IHZ:
标准方波信号,作为频率测量控制电路的输人信
号,用1S的时间使能计数器计数,将结果保存到锁存器,就可以保证输出显示稳定。
将计数值转换为ASCII码,采用LCD12864显示待测信号的频率。
设计内容
一)源程序
1.分频计数模块
本模块主要是把50M的信号分频为1hz和1/1.2khz。
。
分频计数的模块的功能结构框图如图1-1所示。
图1-1计算里程和车费模块的功能结构框图
根据模块实现的功能设计VerilogHDL源代码如下:
modulejishu(
clk,rst,
clk_1s,clk_1ms2
);
inputclk,rst;
outputclk_1s,clk_1ms2;
regclk_1ms2;
regclk_1s;
reg[25:
0]count_1s;
reg[14:
0]count_1ms2;
//parametercen_1ms2=30000;
//parametercen_1s=50000000;
always@(posedgeclkornegedgerst)
begin
if(!
rst)count_1s<=0;
elsebegin
if(count_1s==50000000)
begin
count_1s<=0;
clk_1s=~clk_1s;
end
elsecount_1s<=count_1s+1'b1;
end
end
always@(posedgeclkornegedgerst)
begin
if(!
rst)count_1ms2<=0;
elsebegin
if(count_1ms2==30000)
begin
count_1ms2<=0;
clk_1ms2=~clk_1ms2;
end
elsecount_1ms2<=count_1ms2+1'b1;
end
end
endmodule
该模块定义输入输出端口如下:
■clk:
全局时钟信号,这里为50MHz的时钟。
■rst:
外部复位信号。
■clk_1s:
由50MHZ的信号分频得到。
■clk_1ms2:
由50MHZ的信号分频得到。
在Altera公司的软件工具QuartusⅡ(WindowsXP环境下)中编译和波形仿真后得到的波形如图2-2所示:
图2-2待测信号输入计数的仿真波形
2.待测信号输入计数模块
本模块主要是将待测信号输入,然后对待测信号进行计数。
待测信号输入计数模块的功能结构框图如图2-1所示:
图2-1待测信号输入计数模块的功能结构框图
根据模块实现的功能设计VerilogHDL源代码如下:
modulefm_jishu(clk_1s,rst,fm_in,fm_count);
inputfm_in,clk_1s,rst;
output[26:
0]fm_count;
reg[26:
0]fm_count;
reg[26:
0]count;
always@(posedgefm_inornegedgerst)
begin
if(!
rst)count<=0;
elseif(!
clk_1s)count<=0;
elsebegin
count<=count+1'b1;
end
end
always@(negedgeclk_1sornegedgerst)
begin
if(!
rst)fm_count<=0;
elsefm_count<=count;
end
endmodule
该程序定义输入输出端口如下:
■clk_1s:
分频得到的输入信号1HZ。
■fm_in:
待测输入信号。
■fm_count:
输入信号的计数。
■rst:
外部复位信号。
在Altera公司的软件工具QuartusⅡ(WindowsXP环境下)中编译和波形仿真后得到的波形如图2-2所示:
图2-2待测信号输入计数的仿真波形
3.液晶显示模块
本模块为动态显示,时间间隔为5秒。
动态显示模块的功能结构框图如图3-1所示。
图3-1动态显示模块的功能结构图
根据模块实现的功能设计VerilogHDL源代码如下:
moduleLCD_12864(
inputclk_1ms2,//1.2ms时钟
input[26:
0]data,//数据输入
inputrst_n,//复位
outputreg[7:
0]LCD_data,//LCD12864的数据线
outputregLCD_RS,//LCD12864的寄存器选择:
H:
数据寄存器L:
指令寄存器
outputLCD_RW,//LCD12864的读写信号线:
H:
读L:
写
outputLCD_EN,//LCD12864的使能端:
下降沿触发,锁存数据
outputLCD_PSB,//LCD12864串/并选择H:
并行L:
串行
outputLCD_RST//LCD12864复位端:
低电平有效
);
//++++++++++++++++++++++++++++++++++++++++++++++++
//LCD12864驱动部分开始
//++++++++++++++++++++++++++++++++++++++++++++++++
parameterinit=3'd0,//初始化写指令
write_data_1=3'd1,//第一行写数据
write_data_2=3'd2,//第二行写数据
write_data_3=3'd3,//第三行写数据
write_data_4=3'd4;//第四行写数据
reg[2:
0]state;//状态码
reg[4:
0]counter;//计数
assignLCD_EN=clk_1ms2;//LCD12864的使能端:
下降沿触发,锁存数据
assignLCD_PSB=1'b1;//LCD12864串/并选择:
H:
并行L:
串行
assignLCD_RST=1'b1;//LCD12864复位端:
低电平有效
assignLCD_RW=1'b0;//没有读操作,R/W信号始终为低电平
always@(posedgeclk_1ms2ornegedgerst_n)
begin
if(!
rst_n)
begin
counter=0;//计数清零
state=init;//复位回到init码
end
elsebegin
case(state)
init:
begin//LCD12864初始化写数据
LCD_RS=0;
counter=counter+4'd1;
case(counter)
1:
LCD_data=8'h30;//0x30:
基本指令
2:
LCD_data=8'h02;//0x02:
地址归位
3:
LCD_data=8'h01;//0x01:
清屏
4:
LCD_data=8'h06;//0x06:
光标右移
5:
LCD_data=8'h0c;//0x0c:
6:
begin
LCD_data=8'h80;
state=write_data_1;//转移到写第一行数据
counter=0;
end
default:
counter=0;
endcase
end
write_data_1:
begin//LCD12864写第一行数据
LCD_RS=1;
case(counter)
0:
LCD_data="";//空格
1:
LCD_data="";//空格
2:
LCD_data=8'hD3;
3:
LCD_data=8'hF1;
4:
LCD_data=8'hC1;
5:
LCD_data=8'hD6;
6:
LCD_data=8'hCA;
7:
LCD_data=8'hA6;
8:
LCD_data=8'hB7;
9:
LCD_data=8'hB6;
10:
LCD_data=8'hD1;
11:
LCD_data=8'hA7;
12:
LCD_data=8'hD4;
13:
LCD_data=8'hBA;
14:
LCD_data="";
15:
LCD_data="";
16:
begin
LCD_RS=0;
LCD_data=8'h90;
end
default:
counter=0;
endcase
if(counter==16)
begin
counter=0;
state=write_data_2;
end
elsecounter=counter+4'd1;
end
write_data_2:
begin//LCD12864写第二行数据
LCD_RS=1;
case(counter)
0:
LCD_data=8'hB4;
1:
LCD_data=8'hB4;
2:
LCD_data=8'hD0;
3:
LCD_data=8'hC2;
4:
LCD_data=8'hBB;
5:
LCD_data=8'hF9;
6:
LCD_data=8'hB5;
7:
LCD_data=8'hD8;
8:
LCD_data="-";//
9:
LCD_data="-";
10:
LCD_data="F";//"F"
11:
LCD_data="P";//"P"
12:
LCD_data="G";//"G"
13:
LCD_data="A";//"A"
14:
LCD_data="!
";//"!
"
15:
LCD_data="!
";//"!
"
16:
begin
LCD_RS=0;
LCD_data=8'h88;//写第三行数据
end
default:
counter=0;
endcase
if(counter==16)
begin
counter=0;
state=write_data_3;//转移到写第三行数据
end
elsecounter=counter+4'd1;
end
write_data_3:
begin//LCD12864写第三行数据
LCD_RS=1;
case(counter)
0:
LCD_data="F";
1:
LCD_data="r";
2:
LCD_data="e";
3:
LCD_data="=";
4:
LCD_data=8'h30+data/10000000;
5:
LCD_data=8'h30+data/1000000%10;
6:
LCD_data=",";
7:
LCD_data=8'h30+data/100000%10;
8:
LCD_data=8'h30+data/10000%10;
9:
LCD_data=8'h30+data/1000%10;
10:
LCD_data=",";
11:
LCD_data=8'h30+data/100%10;
12:
LCD_data=8'h30+data/10%10;
13:
LCD_data=8'h30+data%10;
14:
LCD_data="H";
15:
LCD_data="Z";
16:
begin
LCD_RS=0;
LCD_data=8'h98;//写第四行数据
end
default:
counter=0;
endcase
if(counter==16)
begin
counter=0;
state=write_data_4;//转移到写第四行数据
end
elsecounter=counter+4'd1;
end
write_data_4:
begin//LCD12864写第四行数据
LCD_RS=1;
case(counter)
0:
LCD_data="-";
1:
LCD_data="-";
2:
LCD_data="-";
3:
LCD_data="-";
4:
LCD_data=8'hC6;//频
5:
LCD_data=8'hB5;
6:
LCD_data=8'hC2;//率
7:
LCD_data=8'hCA;
8:
LCD_data=8'hBC;//计
9:
LCD_data=8'hC6;
10:
LCD_data="-";
11:
LCD_data="-";
12:
LCD_data=8'hD6;
13:
LCD_data=8'hA3;
14:
LCD_data=8'hD3;
15:
LCD_data=8'hC2;
16:
begin
LCD_RS=0;
LCD_data=8'h80;//写第一行数据
end
default:
counter=0;
endcase
if(counter==16)
begin
counter=0;
state=write_data_1;//转移到写第一行数据
end
elsecounter=counter+4'd1;
end
default:
state=init;//默认回到init码
endcase
end
end
endmodule
该模块定义输入输出端口如下:
■clk_1ms2:
分频得到的信号,这里为1/1.2MHZ的时钟
■data:
数据输入
■rst_n:
复位
■LCD_data:
LCD12864的数据线
■LCD_RS:
LCD12864的寄存器选择:
H:
数据寄存器L:
指令寄存器
■LCD_RW:
LCD12864的读写信号线
■LCD_EN:
LCD12864的使能
■LCD_PSB:
LCD12864串/并选择
■LCD_RST:
LCD12864复位端
4.设计数字频率计电路
VerilogHDL具有行为描述和结构描述功能。
行为描述是对设计电路的逻辑功能的描述,并不用关心设计电路使用哪些元件及这些元件之间的连接关系。
而结构描述是对设计电路的结构进行描述,即描述设计电路使用的元件及这些元件之间的连接关系。
本文用行为描述和结构描述分别实现电路系统。
生成的jishu、fm_jishu1和LCD_12864元件图形符号只是分别代表分立的电路设计结果,并没有形成系统。
顶层设计文件就是调用jishu、fm_jishu和LCD_12864三个功能元件,将它们组装起来,成为一个完整的设计。
plj.bdf是本例的顶层文件,实现的功能是将检测出的频率显示出来如图4-1所示。
图4-1plj顶层设计图
二)硬件实现
1.引脚锁定
对数字频率计进行实验验证时,需要确定用开发板的哪些输入/输出端口(PI/O)来表示设计电路的输入输出。
根据CycloneIIEP2C8Q208C8N开发板的管脚。
数字频率计与EP2C8Q208C8N中的目标芯片引脚连接的全部关系见表1-1。
表1-1频率计与目标芯片引脚连接关系表
2:
测试数据:
待测频率值/(khz)
测试频率值/(khz)
误差/(%)
0.520
0.520
0
50.000
49.999
0.002
200.010
200.010
0
400.000
400.010
0.025
600.000
600.000
0
1000.001
1000.000
0.0001
1500.000
1500.015
0.001
2000.000
2000.004
0.0002
2500.000
2500.050
0.002
结论
该频率计利用QuartusⅡ软件工作平台进行编译和综合仿真后,将程序下载到一片FPGA芯片中,经实验验证,该频率计达到了设计要求。
所设计的数字频率计由于采用VerilogHDL语言设计,用一片FPGA实现,因而体积小、功耗低,稍加修改就可以改变数字频率计测量范围,拥有较高的整体性能和可靠性,升级和维护都很方便,而且容易生产,造价比较低,具有较好的市场前景。
参考文献
1黄任.AVR单片机与CPLD/FPGA综合应用入门[M].北京:
北
京航空航天大学出版社,2004.
1王振红.VHDL数字电路设计与应用实践教程.北京:
机械工业出版社,2003年6月.
2江国强.EDA技术与与应用(第2版).北京:
电子工业出版社,2007年4月.
3王钿卓兴旺.基于VerilogHDL的数字系统应用设计.北京:
国防工业出版社,2006年1月.
4延明张亦华.数字电路EDA技术入门.北京:
北京邮电大学出版社,2006年1月.
5王钿卓兴旺盛.基于VerilogHDL的数字系统应用设计.北京:
国防工业出版社,2006年1月.
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 FPGA 数字频率计