这程序就这样肯定是不能用的,需要你自己做一些事情:
首先,FPGA本身对非2的指数次的乘法或者除法的支持并不好,所以算法中的乘法、除法运算需要调用乘法、除法核,而核调用是没法在这里表示出来的,需要你在quaters或者ISE上生成IP核然后调用
其次,标准信号的周期不确定,所以就没法确定什么时候结果不在范围之内;
你这个考试题不知道是哪个白痴老师出的,简直是在挑战FPGA的极限,专门往FPGA不擅长的方面出题。
你先拿去用着,选为最佳答案后有问题可以hi我,我一般隔一阵就会看一眼hi
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: 搞吓米飞机
//
// Create Date: 09:30:31 06/29/2010
// Design Name:
// Module Name: frequency
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 001 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module frequency(clk,En,zhamen,Input,LED4,LED1,LED2,LED3,LED5,low,high
);
input clk;//时钟输入,同时也是所谓的标准信号。
input En;
input zhamen;//闸门输入
input Input;//测试数据输入
output LED4;//五个LED,当做输出
output LED1;
output LED2;
output LED3;
output LED5;
output low;
output high;
wire clk;
wire En;
wire zhamen;
wire Input;
reg zhamen_En;//实际门限使能
reg [10:0]Nx;//数据
reg [11:0]Ns;//标准计数
reg [7:0]LED1;
reg [7:0]LED2;
reg [7:0]LED3;
reg [7:0]LED4;
reg [7:0]LED5;
reg flag;
reg [10:0]result;
reg low;//低于或高于测试范围的提示LED输出。这里因为具体将门限制设置到多少与clk的频率相关,需要自行设置
reg high;
always@(posedge clk)
begin
if(En==1)
begin
if(zhamen==1)
begin
if(Input==1)
zhamen_En=1;
end
if(zhamen==0)
begin
if(Input==1)
begin
zhamen_En=0;
end
end
if(zhamen_En==1)
begin
Ns=Ns+1;
flag=1;
end
end
else
begin
LED5=0;
LED1=0;
LED2=0;
LED3=0;
LED4=0;
zhamen_En=0;
flag=0;
end
end
always@(posedge Input)
begin
if(zhamen_En==1)
Nx=Nx+1;
end
always@(posedge clk)
begin
if(zhamen_En==0&&flag==1)
begin
flag=0;
result=(Nx/Ns)Fs// 此处仅仅是个示例。这里需要调用除法核以及乘法核,调用之后直接输入即可
case(result%10)//这里也是要调用除法核生成余数和结果,下面同理
4'b0000: LED1=8'b11111101;
4'b0001: LED1=8'b01100001;
4'b0010: LED1=8'b11011011;
4'b0011: LED1=8'b11110011;
4'b0100: LED1=8'b01100111;
4'b0101: LED1=8'b10110111;
4'b0110: LED1=8'b10111111;
4'b0111: LED1=8'b11100001;
4'b1000: LED1=8'b11111111;
4'b1001: LED1=8'b11110111;
default: LED1=8'b11111101;
endcase
case(((result-result%10)%100)/10)
4'b0000: LED2=8'b11111100;
4'b0001: LED2=8'b01100000;
4'b0010: LED2=8'b11011010;
4'b0011: LED2=8'b11110010;
4'b0100: LED2=8'b01100110;
4'b0101: LED2=8'b10110110;
4'b0110: LED2=8'b10111110;
4'b0111: LED2=8'b11100000;
4'b1000: LED2=8'b11111110;
4'b1001: LED2=8'b11110110;
default: LED2=8'b11111100;
endcase
case((result%1000-result%100-result%10)/100)
4'b0000: LED3=8'b11111100;
4'b0001: LED3=8'b01100000;
4'b0010: LED3=8'b11011010;
4'b0011: LED3=8'b11110010;
4'b0100: LED3=8'b01100110;
4'b0101: LED3=8'b10110110;
4'b0110: LED3=8'b10111110;
4'b0111: LED3=8'b11100000;
4'b1000: LED3=8'b11111110;
4'b1001: LED3=8'b11110110;
default: LED3=8'b11111100;
endcase
case((result%10000-result%1000-result%100-result%10)/1000)
4'b0000: LED4=8'b11111100;
4'b0001: LED4=8'b01100000;
4'b0010: LED4=8'b11011010;
4'b0011: LED4=8'b11110010;
4'b0100: LED4=8'b01100110;
4'b0101: LED4=8'b10110110;
4'b0110: LED4=8'b10111110;
4'b0111: LED4=8'b11100000;
4'b1000: LED4=8'b11111110;
4'b1001: LED4=8'b11110110;
default: LED4=8'b11111100;
endcase
case((result-result%10000-result%1000-result%100-result%10)/10000)
4'b0000: LED5=8'b11111100;
4'b0001: LED5=8'b01100000;
4'b0010: LED5=8'b11011010;
4'b0011: LED5=8'b11110010;
4'b0100: LED5=8'b01100110;
4'b0101: LED5=8'b10110110;
4'b0110: LED5=8'b10111110;
4'b0111: LED5=8'b11100000;
4'b1000: LED5=8'b11111110;
4'b1001: LED5=8'b11110110;
default: LED5=8'b11111100;
endcase
end
end
endmodule
不知你测的是什么波形,为什么要除以2
若是方波,不用除以2
是交流电整流后半波变全波?是要除以2
若是STC的非1T 单片机,下载程序时 有6T和12T选项,若选6T,定时器定时时间就减小一半
实测频率就高了
STC有一个版本的下载软件有问题,6T应该是倍速,结果写成了12T是倍速
当你执行到
if(num==20) //说明一秒已到
EA=0; //这个你把总中断关了,然后就无法启用计时器
m=256TH1+TL1;
a=m/100000;
b=m/10000;
c=m/1000;
d=m/100;
e=m/10;
f=m%10;
EA=1;//在这里开启中断,让计时器继续运行
定时器1 1MS中断一次,5次是5ms,乘200就是1秒种,其初值由晶振频率决定,有计算软件
当然,也可以中断10次或20次,频率判断更准确,但响应速度慢了
1600或800方波接入定时器/计数器0的外部输入引脚上,好像是P34
程序如下:
void
init()//初始化设置
{
TMOD=0x15;//定时器0作为计数器,定时器1作为定时器用
TH0=0;//计数器清0
TL0=0;
EA=1;//开总中断
ET1=1;//允许定时器1中断
TH1=;
TL1=;
TR0=1;//启动计数器
TR1=1;//启动定时器
aa=0;
}
void
main()//主程序很简单
{
init();//初始化
while(1)//循环程序
{
dd=bb256+cc;//
5ms的计数值
ee=200dd;//换算为1秒钟的计数值
if((ee>750)&&(ee<850))
{
P35=0;
}
if((ee>1550)&&(ee<1650))
{
P35=1;
}
}
}
void
timer1()interrupt
3//注意:定时器1的中断序号为3
{
aa++;
TH1=;
TL1=;
if(aa==5)//中断5次,共5ms
{
TR0=0;//暂停计数
aa=0;
bb=TH0;//读出计数器数据
cc=TL0;
TL0=0;//计数器清0
TH0=0;
TR0=1;//重新启动计数器
}
}
不知道你这程序是哪弄来的,里面有错误且代码风格不好,锁存器只能是电平锁存,触发器才用边缘触发的。要是做项目的话,这样的代码风格具有易读性,易维护性,和可移植性。还要多多学习哈,我为你提供下我写的代码风格,可以供你参考。
我针对例 114频率计锁存器模块来讲(提醒:锁存器只能是电平锁存),所以你这书上是错误的,并且时序电路只能用非阻塞赋值。
//=====================================================
//Author :XXXXXXXX
//Date :XXXXXXXX
//Function :XXXXXXXX
//=====================================================
module latch(
//Input ports
DI,
LOAD,
//Output ports
DO
);
//=====================================================
//Input and output declaration
//=====================================================
input [15:0] DI;
input LOAD;
output [15:0] DO;
//=====================================================
//Wire and reg declaration
//=====================================================
wire [15:0] DI;
wire LOAD;
reg [15:0] DO;//方法一
wrie [15:0] DO;//方法二
//=====================================================
//Logic
//=====================================================
由于锁存器是电平锁存,因此是组合逻辑电路。而组合逻辑电路有两种实现方法,
针对这两种方法我都写出来供你参考。
注意事项:用always实现组合逻辑电路,被赋值的变量必须为reg型变量,因此在声明的时候为
reg [15:0] DO;
用asssign实现组合逻辑电路,被赋值的变量必须为wire型变量,因此在声明的时候为
wire [15:0] DO; 已在上面的声明中注明。
方法一:
always @ ()
begin
if(LOAD)
DO<=DI;
end
方法二:
assign DO = (LOAD) DI : DO;
以上就是关于急!!!设计一个用等精度测频原理的频率计的verilog语言程序全部的内容,包括:急!!!设计一个用等精度测频原理的频率计的verilog语言程序、51单片机频率计,程序中时间按道理来说应该是只测了半个周期、下面是我编的一个简单的数字频率计的c语言程序,为什么一秒后数码管显示出乱码呢等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)