您的位置:首页 > 其它

设计题目:基于CPLD/FPGA的出租车计费器

2012-12-08 21:51 555 查看
一、设计任务及要求:
本设计要求设计一个基于CPLD/FBGA的出租车计费器,其具体要求如下:
1 能够实现计费功能
费用是按行驶的里程进行 计算的,设出租车的起价是6.0元,当里程小于3km时,按起价计算费用,当里程大于3km时,每km1.0元计费,所以总费用按下式计算。
总费用=起价费用+(里程-3km)*里程单价
2 能够实现显示的功能
1) 显示汽车行驶的里程,用4位数字显示,显示的方式为“XXX.X”.单位为km。计程范围为0~999.9km。
2) 显示总费用:用4位数字想害死,显示的方式为“XXX.X”.单位为元。计程范围为0~999.9元。
二、设计原理与方案:
(一)、顶层设计方案:
原理框图:

数码管显示器
分频器2
扫描脉冲

译码、动态扫描
分频器1
里程脉冲

S1 S2 S3 CLK
工作原理:
出租车的计费过程为:按下S1(按下时S1=0,松开时S1=1),启动计时器,里程从0开始计数,费用从6.0开始计数。再根据行驶的里程按以上的标准计费。出租车到达目的,按下S2停止计费。显示总里程和总费用。按下S3清零。时钟信号为50MHZ,应设计一个分频器得到1HZ的时钟信号作为里程计数的的脉冲、每一个脉冲表示100米。数码管采用动态扫描的方式,应该设计一个合适的分频器得到显示用的扫描脉冲。

(二)、计量电路的设计方案:

设计思路:
按下S1(按下时S1=0,松开时S1=1),启动计时器,里程从0开始计数,费用从6.0开始计数。再根据行驶的里程按以上的标准计费。出租车到达目的,按下S2停止计费。显示总里程和总费用。按下S3清零。用时钟脉冲来控制整个过程。输入S1,S2,S3,输出
Lichen0;licheng1;licheng2;licheng3,jifei0;jifei1;jifei2;jifei3

工作原理:
每来一个时钟脉冲,里程计数就要增加0.1 km ;在里程的3km之内, 费用是6元保持不变 里程在3km之后,每来一个时钟脉冲,费用就要增加0.1元。并且为了后面的显示方便 要用不同的数字分别记录各个位上的数字.采用10进制计数器。将脉冲信号分别转换为10进制信号。然后进行传输。
(三)、分频器1和分频器2设计方案:

设计思路:
要实现50000000分频 就要采用模50000000/2计数器实现,所以就是当时钟脉冲跳动25000000时采用计数器将信号取反得到50000000分频的分频器 。分频器2的设计类似。

工作原理:
对于偶数N分频,通常是由模N/2计数器实现一个占空比为1:1的N分频器,分频输出信号模N/2自动取反。

三、电路设计、仿真与实现:
(一)、顶层设计实现
原理图:

仿真波形:

(二)、计量电路的设计实现
源文件:
显示程序源文件
module show(clk,
licheng0,licheng1,licheng2,licheng3,
jifei0,jifei1,jifei2,jifei3,
out,df,n);
input clk;
input [3:0]licheng0;
input [3:0]licheng1;
input [3:0]licheng2;
input [3:0]licheng3;
input [3:0]jifei0;
input [3:0]jifei1;
input [3:0]jifei2;
input [3:0]jifei3;

output [6:0]out;
output df;
output [2:0] n;

reg [6:0]out;
reg [3:0] m;
reg [2:0]n;
reg df;

always@(posedge clk)
begin
if(clk)
begin
n=n+3'b001;
end
case (n)
3'b000:begin m=licheng0; df=1'b0;end
3'b001:begin m=licheng1; df=1'b1;end
3'b010:begin m=licheng2; df=1'b0;end
3'b011:begin m=licheng3; df=1'b0;end
3'b100:begin m=jifei0; df=1'b0;end
3'b101:begin m=jifei1; df=1'b1;end
3'b110:begin m=jifei2; df=1'b0;end
3'b111:begin m=jifei3; df=1'b0;end
default : m=4'd0;
endcase
end
always@(m)
begin
case(m)
4'd0:out[6:0]<=7'b0111_111;
4'd1:out[6:0]<=7'b0000_110;
4'd2:out[6:0]<=7'b1011_011;
4'd3:out[6:0]<=7'b1001_111;
4'd4:out[6:0]<=7'b1100_110;
4'd5:out[6:0]<=7'b1101_101;
4'd6:out[6:0]<=7'b1111_101;
4'd7:out[6:0]<=7'b0000_111;
4'd8:out[6:0]<=7'b1111_111;
4'd9:out[6:0]<=7'b1101_111;
default : out[6:0]<= 7'b0000_000;
endcase
end
endmodule
计量程序源文件:
module jishu(
s1,s2,s3,
clk,
licheng0,licheng1,licheng2,licheng3,
jifei0,jifei1,jifei2,jifei3
);

input s1,s2,s3,clk;

output [3:0] licheng0,
licheng1,
licheng2,
licheng3,
jifei0,
jifei1,
jifei2,
jifei3;
//初始化路程 费用
reg [3:0] licheng0=0;
reg [3:0] licheng1=0;
reg [3:0] licheng2=0;
reg [3:0] licheng3=0;
reg [3:0] jifei0=0;
reg [3:0] jifei1=6;
reg [3:0] jifei2=0;
reg [3:0] jifei3=0;
reg [31:0]nx=0;
reg nw;

always@( posedge clk )
begin
if(!s3)begin
licheng0<=4'd0;
licheng1<=4'd0;
licheng2<=4'd0;
licheng3<=4'd0;
jifei0<=4'd0;
jifei1<=4'd6;
jifei2<=4'd0;
jifei3<=4'd0;
end
if(!s1)begin
nw<=1'b1;
end
if(nw)
begin
nx=nx+32'd1;
licheng0<=licheng0+4'd1;
jifei0<=jifei0+4'd1;
if(licheng0>=4'd9)begin
licheng0<=4'd0;
licheng1<=licheng1+4'd1;
end
if(licheng1>=4'd9)begin
licheng1<=4'd0;
licheng2<=licheng2+4'd1;
end
if(licheng2>=4'd9)begin
licheng2<=4'd0;
licheng3<=licheng3+4'd1;
end
if(licheng3>=4'd9)begin
licheng0<=4'd0;
licheng1<=4'd0;
licheng2<=4'd0;
licheng3<=4'd0;
end
end
if(!s2)begin
nw<=1'b0;
end
if(nx<31)begin
jifei0<=4'd0;
jifei1<=4'd6;
jifei2<=4'd0;
jifei3<=4'd0;
end
else
begin
if(jifei0>=4'd9)begin
jifei0<=4'd0;
jifei1<=jifei1+4'd1;
end
if(jifei1>=4'd9)begin
jifei1<=4'd0;
jifei2<=jifei2+4'd1;
end
if(jifei2>=4'd9)begin
jifei2<=4'd0;
jifei3<=jifei3+4'd1;
end
if(jifei3>=4'd9)begin
jifei0<=4'd0;
jifei1<=4'd6;
jifei2<=4'd0;
jifei3<=4'd0;
end
end
end
endmodule

仿真波形:

(三)、分频器1和分频器2设计实现
源文件:
分频器1
module fenpin(clk, clkout );
input clk;
output clkout;
reg clkout;
reg [31:0] cout;

always @(posedge clk )
begin
cout <= (cout == 32'd25000_000) ? 32'd0 : (cout + 32'd1);
clkout <= (cout == 32'd25000_000) ? 1'd1 : 1'd0;
end

endmodule
分频器2
module fenpin2(clk, clkout );
input clk;
output clkout;
reg clkout;
reg [31:0] cout;

always @(posedge clk )
begin
cout <= (cout == 32'd50000) ? 32'd0 : (cout + 32'd1);
clkout <= (cout == 32'd50000) ? 1'd1 : 1'd0;
end

endmodule
(四)、实际DownLoad及测试结果。
下载完毕后数码管显示为000.0 000.0;当按下S1后 开始计算里程和费用,里程从0.1开始加,费用刚开始为6.0,当里程大于3.0时,按6+里程 计算费用。
当按下S2后停止计费,按下S3后清零。
四、分析与讨论:
由于是第一次亲手设计如此较大规模的EDA设计 ,难免回出现一些问题。刚开始在分频时,由于是采用的50Mhz的脉冲 要得到1HZ脉冲就要进行50000000分频 而就是说要在25000000翻转一次脉冲 ,刚开始用的是50000000次后翻转一次脉冲 得到的脉冲偏小。在总体设计方面,考虑到了不同的数码管显示的内容不同 而提前在计数时就考虑到了用多个输出作为下一级的输入。为下一级工作做好了准备。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: