FPGA项目(6)--基于FPGA的出租车计费器

产品功能

        本次设计的出租车计价器所实现的功能如下:      

1、能够实现计费的功能

        费用是按行驶的里程进行计算,设出租车的起价为6元,当里程小于3km时,按起价计算费用;当里程大于3km时每km按1元计费。

2、能够实现显示的功能

        1)左边四个数码管显示里程:用四位数字显示,显示方式为“XXXX”,单位为km。里程范围为0~999.9km,里程分辨率为0.1km。

        2)右边四个数码管显示费用:用四位数字显示,显示方式为“XXXX”,单价为元。计价范围为0~999.9元,费用分辨率为0.1元。

系统框图

设计步骤 

          开发板提供的时钟信号CLK频率为1000Hz,应该设计一分频器得到1Hz的时钟信号作为里程计数脉冲,每一个脉冲表示0.1km。数码管显示采用动态扫描的方式。

设计思路

        首先设计一个分频模块,将输入的1000HZ时钟分频为1HZ,用于驱动里程计数。然后定义一个内部变量flag,只要S1按下,flag=1,S2按下,flag=0。然后系统根据flag的值进行计数。如果flag为1,那么里程和费用就正常计数;如果flag为0,那么里程和费用就不计数,显示总的里程和费用不动。如果检测到S3被按下,那么费用和里程直接清0。显示部分直接调用现成的显示模块,将要显示的数据传过去即可。关于数码管动态显示的内容,具体参见我的另一篇博客:

https://blog.csdn.net/guangali/article/details/130754726?spm=1001.2014.3001.5501

代码

module taxi(
input			clk,
input			reset,
input			S1,
input			S2,
input			S3,
output	[2:0]	sel,		//数码管位选
output	[7:0]	sel_seg		//数码管段选
);

parameter	HZ_NUM=10'd1000;		//得到1HZ信号的分频系数
//parameter	HZ_NUM=10'd2;		//仿真使用
reg	[9:0]	cnt;
reg 		clk_hz;						//分频后得到的1HZ信号
reg [13:0]	miles;						//用于保存公里数
reg	[13:0]	cost;						//用于保存路费
reg			flag;						//标志位  1-->系统运作   0-->系统暂停
reg			i;
wire [31:0]	data_show;					//要送到数码管显示的数据

wire   [3:0]              data0    ;        // 个位数
wire   [3:0]              data1    ;        // 十位数
wire   [3:0]              data2    ;        // 百位数
wire   [3:0]              data3    ;        // 千位数
wire   [3:0]              data4    ;        // 万位数
wire   [3:0]              data5    ;        // 十万位数
wire   [3:0]              data6    ;        // 百万位数
wire   [3:0]              data7    ;        // 千万位数

always	@(posedge clk or negedge reset) begin
	if(!reset)
		cnt<=10'd0;
	else if(cnt==HZ_NUM/2-1)
		begin
		clk_hz<=~clk_hz;
		cnt<=10'd0;
		end
	else
		cnt<=cnt+10'd1;
		
end

always @(posedge clk or negedge reset) begin	//根据按键控制标志位
	if(!reset)
		flag<=1'b0;
	else if(S1==1'b0)
		flag<=1'b1;
	else if(S2==1'b0)
		flag<=1'b0;
	else
		flag<=flag;
end
//里程数的控制
always @(posedge clk_hz or negedge reset) begin
	if(!reset)
		begin
		miles<=14'd1234;				//复位时显示学号
		i<=1'b1;
		end
	else if(S3==1'b0)					//按下S3  清0
		miles<=14'd0;
	else if(flag==1'b1)
		begin	
		if(i==1'b1)						//这里用变量i 来控制miles从学号跳变到0
			begin
			miles<=14'd0;
			i<=1'b0;
			end
		else
			miles<=miles+14'd1;
		end
	else
		miles<=miles;
end

//路费控制模块
always @(posedge clk or negedge reset)begin
	if(!reset)
		cost<=14'd5678;							//上电显示学号
	else if(S3==1'b0)					//按下S3  清0
		cost<=14'd0;
	else if(flag==1'b1)
		begin
		if((miles/10)<14'd3)					//除以10 是因为 miles的单位为0.1km
			cost<=14'd60;						//cost的 单位 是0.1元
		else
			cost<=14'd60+(miles-30);
		end
	else
		cost<=cost;
end

assign data7=miles/1000;
assign data6=(miles/100)%10;
assign data5=(miles/10)%10;
assign data4=miles%10;

assign data3=cost/1000;
assign data2=(cost/100)%10;
assign data1=(cost/10)%10;
assign data0=cost%10;


assign data_show={data7,data6,data5,data4,data3,data2,data1,data0};
//例化数码管模块
segshow segshow_u(
.sys_clk	(clk),
.sys_rest	(reset),
.data		(data_show),
.sel		(sel),
.seg_led	(sel_seg)
);
endmodule

        本次设计的关键在于上电显示学号。我采用的方案是将8位数字的学号按4位数为一组,分别给mile 和 cost显示。那么这样就会带来一个问题,上电后,再按下S1时,mile 和 cost都不是从0开始计数的,所以就要想办法让mile从学号跳变到0。所以我用了一个变量i,i的巧妙使用可以实现这种效果。

  • 1
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式小李

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值