当前位置: 首页 > article >正文

基于FPGA的出租车里程时间计费器

基于FPGA的出租车里程时间计费器

  • 功能描述
  • 一、系统框图
  • 二、verilog代码
    • 里程增加模块
    • 时间增加模块
    • 计算价格模块
    • 上板视频演示
  • 总结


功能描述

(1);里程计费功能:3公里以内起步价8元,超过3公里后每公里2元,其中不满一公里按照一公里计算。
(2);等待计费功能:当乘客中途下车需要司机等待时,按照等待时间进行收费,每3分钟0.7元,其中不满3分钟不收费。
(3);数码管显示功能;3种显示状态,默认显示公里数,显示格式10.2,每次步进0.1km,步进时间长度为5S。第二种显示等待时间,显示格式50:33,步进时间长度1S。第三种显示当前费用,包括等待费用以及里程计价费用。
(4);信号灯指示功能:当里程计费模式下,LED2亮起,其他LED熄灭。当等待时间计费模式下,LED4亮起,其他LED熄灭。载人状态下LED1亮起,否则不亮。
(5);按键切换功能:3个按键起作用,第一个按键负责切换计费模式,默认是里程计费模式,切换后为等待时间计费模式。第二个按键负责表示出租车载人状态,默认空载,按下表示载人模式。第三个按键负责切换数码管显示的数据,每按一次切换一次,3种数据循环显示。

一、系统框图

在这里插入图片描述

二、verilog代码

里程增加模块

module count_km(
	input key_dri,
	input sys_reset_n,
	input en_dowm_car,
	input EN,
	output reg [3:0] data_km_ge,
    output reg [3:0] data_km_shi,
    output reg [3:0] data_km_bai,
	
	
//	output reg [15:0] data_km,
	output [3:0] point
);

parameter max_km=16'd9999; 

reg       flag_km_shi_up;
reg       flag_km_bai_up;

assign point=4'b0010;



always @(posedge key_dri or negedge sys_reset_n)
	begin
		if(!sys_reset_n)
			begin
				data_km_ge<=4'h0;
				flag_km_shi_up<=1'b0;
			end
		else if(!EN)begin
			data_km_ge<=data_km_ge;
			flag_km_shi_up<=flag_km_shi_up;
			end
		else if(key_dri && en_dowm_car)
			begin
				if(data_km_ge<4'h9)
					begin
						data_km_ge<=data_km_ge+1'b1;
						flag_km_shi_up<=1'b0;
					end
				else
					begin
						data_km_ge<=4'h0;
						flag_km_shi_up<=1'b1;
					end
			end
	end

always @(posedge key_dri or negedge sys_reset_n)
	begin
		if(!sys_reset_n)
			begin
				data_km_shi<=4'h0;
				flag_km_bai_up<=1'b0;
			end
		else if(!EN)begin
			data_km_shi<=data_km_shi;
			flag_km_bai_up<=flag_km_bai_up;
			end
		else if(key_dri && en_dowm_car && flag_km_shi_up)
			begin
				if(data_km_shi<4'h9)
					begin
						data_km_shi<=data_km_shi+1'b1;
						flag_km_bai_up<=1'b0;
					end
				else
					begin
						data_km_shi<=4'h0;
						flag_km_bai_up<=1'b1;
					end
			end
		else if(key_dri && en_dowm_car && flag_km_shi_up==1'b0)
			begin
			flag_km_bai_up<=1'b0;
			end
	end

always @(posedge key_dri or negedge sys_reset_n)
	begin
		if(!sys_reset_n)
			begin
				data_km_bai<=4'h0;
			end
		else if(!EN)begin
			data_km_bai<=data_km_bai;
			end
		else if(key_dri && en_dowm_car && flag_km_bai_up)
			begin
				if(data_km_bai<4'h9)
					begin
						data_km_bai<=data_km_bai+1'b1;
					end
				else
					begin
						data_km_bai<=4'h0;
					end
			end
	end

endmodule

时间增加模块

//计时模块
module count_1s
(
	input clk,   //系统时钟
	input sys_reset_n, //复位信号
	input EN, //使能  保持
	input en_dowm_car,
	
//	output reg [7:0] data_s,  //秒计时器
//	output reg [7:0] data_m,	//分钟计时器
    output reg [3:0] data_s_shi,
    output reg [3:0] data_s_ge,
    output reg [3:0] data_m_shi,
    output reg [3:0] data_m_ge,
    output reg [3:0] time_price_ge,
    output reg [3:0] time_price_shi,
    output reg [3:0] time_price_bai,
    output reg   clk_1s,  //1s脉冲

	output [3:0] point   //点
);

parameter time_60=8'd60;
parameter MAX_NUM=28'd249;

reg [27:0] cnt; //1s计数器

reg   flag_1m;  //1m计时

reg       flag_m_shi_up;
reg       flag_s_up;
reg       flag_m_up;
reg       time_shi_up;
reg       time_bai_up;


assign point=4'b0100;
//1s计时
always @(posedge clk or negedge sys_reset_n)
	begin
		if(!sys_reset_n)
			begin
				cnt<=1'b0;
				clk_1s<=1'b0;
		end
		else if(!EN)
			begin
				cnt<=cnt;   //保持
				clk_1s<=clk_1s;
			end
		else if(cnt<MAX_NUM)
			begin
				cnt<=cnt+1'b1;
			end
		else
			begin
				cnt<=0;
				clk_1s<=~clk_1s;  //翻转
			end
	end

always @(negedge clk_1s or negedge sys_reset_n)	
	begin
	   if(!sys_reset_n)
			begin
				time_price_ge<=4'h0;
			end
	   else if(en_dowm_car)begin
	         if(flag_s_up && time_price_ge<4'h9)begin
	            time_price_ge<=time_price_ge+1;
	         end
	         else if(flag_s_up && time_price_ge==4'h9)begin
	            time_price_ge<=0;
	         end
	   end
	end
always @(negedge clk_1s or negedge sys_reset_n)	
	begin
	   if(!sys_reset_n)
			begin
				time_price_shi<=4'h0;
			end
	   else if(en_dowm_car)begin
	         if(time_price_ge==4'h9 && time_price_shi<4'h9 && flag_s_up )begin
	            time_price_shi<=time_price_shi+1;
	         end
	         else if(time_price_ge==4'h9 && time_price_shi==4'h9&& flag_s_up)begin
	            time_price_shi<=0;
	         end
	   end
	end

always @(negedge clk_1s or negedge sys_reset_n)	
	begin
	   if(!sys_reset_n)
			begin
				time_price_bai<=4'h0;
			end
	   else if(en_dowm_car)begin
	         if(time_price_shi==4'h9 && time_price_bai<4'h9&& flag_s_up &&time_price_ge==4'h9)begin
	            time_price_bai<=time_price_bai+1;
	         end
	         else if(time_price_shi==4'h9 && time_price_bai==4'h9&& flag_s_up&&time_price_ge==4'h9)begin
	            time_price_bai<=0;
	         end
	   end
	end
	
//	秒个位加1
always @(negedge clk_1s or negedge sys_reset_n)	
	begin
		if(!sys_reset_n)
			begin
				data_s_ge<=4'h0;
				flag_s_up<=0;
			end
		else if(!EN)
			begin
				data_s_ge<=data_s_ge;   //保持
				flag_s_up<=flag_s_up;
			end
		else if(en_dowm_car)begin
		    if(data_s_ge < 4'h9 )
			begin
				data_s_ge<=data_s_ge+1'b1;		
				flag_s_up<=1'b0;					
			end
	    else if(data_s_ge == 4'h9)
			begin
				data_s_ge<=4'h0;		
				flag_s_up<=1'b1;					
			end
	    end
	    else begin
	            data_s_ge<=data_s_ge;   //保持
				flag_s_up<=flag_s_up;
	    end
	end
//	秒十位加1
always @(negedge clk_1s or negedge sys_reset_n)	
	begin
		if(!sys_reset_n)
			begin
				data_s_shi<=4'h0;
				flag_m_up<=0;
			end
		else if(!EN)
			begin
				data_s_shi<=data_s_shi;   //保持
				flag_m_up<=flag_m_up;
			end
		else if(data_s_shi < 4'h5 && data_s_ge==4'h9)
			begin
				data_s_shi<=data_s_shi+1'b1;		
				flag_m_up<=1'b0;					
			end
	    else if(data_s_shi == 4'h5 && data_s_ge==4'h9)
			begin
				data_s_shi<=4'h0;		
				flag_m_up<=1'b1;					
			end
		else begin
		        data_s_shi<=data_s_shi;		
				flag_m_up<=1'b0;	
		end
	end

//分钟个位加一
always @(posedge clk_1s or negedge sys_reset_n)	
	begin
		if(!sys_reset_n)
			begin
				data_m_ge<=4'h0;
				flag_m_shi_up<=1'b0;
			end
		else if(!EN)
			begin
				data_m_ge<=data_m_ge;   //保持
				flag_m_shi_up<=flag_m_shi_up;
			end
		else if(en_dowm_car) 
			begin
				if(data_m_ge<4'h9 && data_s_shi==4'h5 && data_s_ge==4'h9)
					begin
						data_m_ge<=data_m_ge+1'b1;
						flag_m_shi_up<=1'b0;
					end
				else if(data_m_ge==4'h9 && data_s_shi==4'h5 && data_s_ge==4'h9)
					begin
						data_m_ge<=4'h0;
						flag_m_shi_up<=1'b1;
					end
				else begin
		               data_m_ge<=data_m_ge;   //保持
				       flag_m_shi_up<=1'b0;
		          end
			end
		else begin
		        data_m_ge<=data_m_ge;   //保持
				flag_m_shi_up<=1'b0;
		end
	end

//分钟十位加一
always @(posedge flag_m_shi_up or negedge sys_reset_n)	
	begin
		if(!sys_reset_n)
			begin
				data_m_shi<=4'h0;
			end
		else if(!EN)
			begin
				data_m_shi<=data_m_shi;   //保持
			end
		else if(en_dowm_car) 
			begin
				if(data_m_shi<4'h5 )
					begin
						data_m_shi<=data_m_shi+1'b1;
					end
				else if(data_m_shi==4'h5)
					begin
						data_m_shi<=4'h0;
					end
			end
		else begin
		        data_m_ge<=data_m_ge;   //保持
		end
	end

endmodule

计算价格模块

module count_money(
	input [7:0] data_m,
	input [15:0] data_km,
	input sys_reset_n,
	input clk,
	input             add_km,
	input         en_dowm_car,
	input          clk_1s,
	input         [3:0] data_km_ge,
	input         [3:0] data_km_shi,
    input         [3:0] data_km_bai,
    input          [3:0] time_price_ge,
    input          [3:0] time_price_shi,
    input          [3:0] time_price_bai,
    output      reg [3:0] price_ge,
    output      reg [3:0] price_shi,
    output      reg [3:0] price_bai,
//	output reg [15:0] data_price,
	output [3:0] point
);

assign point=4'b0010;

reg [15:0] price_km;
reg [15:0] price_time;

reg price_shi_up;
reg price_bai_up;
initial
	begin
		price_km<=16'd30;
		price_time<=16'd0;
	end

	
	
//里程计价
always @(posedge add_km or negedge sys_reset_n)
	begin
		if(!sys_reset_n)
			begin
				price_ge<=4'h0;
				 price_shi_up<=1'b0;
			end
		else if(en_dowm_car )begin
		    if(data_km_bai==4'h0)begin
		          if(price_ge<4'h9 && data_km_shi>=4'h3 )begin//大于3.0公里开始增加
		          price_ge<=price_ge+1;
		          price_shi_up<=1'b0;
		          end
		           else if(price_ge>=4'h9 && data_km_shi>=4'h3 )begin//大于3.0公里开始增加 到9累加
		          price_ge<=4'h0;
		          price_shi_up<=1'b1;
		          end
		           else if(price_ge<4'h9 && data_km_shi<4'h3)begin
		          price_ge<=price_ge;
		          price_shi_up<=1'b0;
		          end
		          end
		    else if(data_km_bai!=4'h0)begin
		           if(price_ge<4'h9 )begin//大于3.0公里开始增加
		          price_ge<=price_ge+1;
		          price_shi_up<=1'b0;
		            end
		          else if(price_ge>=4'h9)begin//大于3.0公里开始增加 到9累加
		          price_ge<=4'h0;
		          price_shi_up<=1'b1;
		          end
		        end
		      end
	    
	end

always @(posedge add_km or negedge sys_reset_n)
	begin
		if(!sys_reset_n)
			begin
				price_shi<=4'h8;
				 price_bai_up<=1'b0;
			end
		
		    else if(price_shi<4'h9 && price_shi_up)begin
		          price_shi<=price_shi+1;
		          price_bai_up<=1'b0;
		    end
		    else if(price_shi>=4'h9 && price_shi_up)begin
		          price_shi<=4'h0;
		          price_bai_up<=1'b1;
		    end
		    else if(price_shi_up==1'b0)begin
		          price_bai_up<=1'b0;
		    end
		
	     
	end

always @(posedge add_km or negedge sys_reset_n)
	begin
		if(!sys_reset_n)
			begin
				price_bai<=4'h0;
			end
		    else if(price_bai<4'h9 && price_bai_up)begin
		          price_bai<=price_bai+1;
		    end
		    else if(price_bai>=4'h9 && price_bai_up)begin
		          price_bai<=4'h0;
		    end
	end

endmodule

在这里插入图片描述

模块分析:
通过分频得到5S周期的脉冲信号,当EN信号为高电平时,也就是有乘客上车后,司机按下按键,出租车变为载客状态,这时里程开始根据脉冲信号的上升沿进行增加。
在这里插入图片描述
通过按键切换到等待时间计费模式后,EN变为高电平,模块开始工作。将时钟分频模块得到的1S脉冲信号作为触发源进行判断,分和秒各8位,可以看到在脉冲上升沿时间不断累加,符合预期功能。

上板视频演示

基于FPGA的出租车里程时间计费器

总结

模块太多,只展示了比较重要的,其他一些模块就是产生分频信号的,无关紧要。需要的一键三连


http://www.kler.cn/a/472866.html

相关文章:

  • python注意事项:range遍历越索引现象、列表边遍历边修改出现的问题
  • Selenium 的四种等待方式及使用场景
  • C语言基本知识复习浓缩版:标识符、函数、进制、数据类型
  • LeetCode 第34题:二分查找+扩展搜索
  • LangChain速成课程_构建基于OpenAI_LLM的应用
  • MCU 和 PSK
  • 欧标开源OCPP充电桩平台 V2.6.8 - 慧知开源充电平台
  • Spark的原理以及使用
  • PyMysql 02|(包含项目实战)数据库工具类封装
  • 结构型模式4.装饰器模式
  • 枫清科技高雪峰: Data-Centric新范式开启,知识引擎+大模型双轮驱动企业智能化
  • Python里JSON orjson ujson在json.loads有什么区别?
  • 性能测试03|JMeter:断言、关联、web脚本录制
  • c++ 17 constexpr
  • conda+jupyter+pycharm:如何在Windows conda环境下运行jupyter并使用浏览器或者pycharm运行.ipynb
  • 开源一款简单易用的键盘音效工具
  • el-table 多级表头
  • 域名反查IP多种方式
  • 【Linux基础指令】第一期
  • 高频 SQL 50 题(基础版)_197. 上升的温度
  • cursor试用出现:Too many free trial accounts used on this machine 的解决方法
  • html 前端进行浮动布局设置
  • Go跨平台UI开发之wails的使用(1)
  • Lua语言的软件工程
  • 实现串口控制
  • 计算机网络 (31)运输层协议概念