基于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的出租车里程时间计费器

总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/948284.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unix 域协议汇总整理

Unix 域协议是一种用于同一台计算机上进程间通信&#xff08;IPC&#xff09;的技术。它提供了一种比基于网络的套接字更高效的方式来在本地进程中交换数据。Unix 域协议使用文件系统作为通信的媒介&#xff0c;并且只限于在同一台计算机上运行的进程之间进行通信。 Unix 域套接…

JVM学习:CMS和G1收集器浅析

总框架 一、Java自动内存管理基础 1、运行时数据区 运行时数据区可分为线程隔离和线程共享两个维度&#xff0c;垃圾回收主要是针对堆内存进行回收 &#xff08;1&#xff09;线程隔离 程序计数器 虚拟机多线程是通过线程轮流切换、分配处理器执行时间来实现的。为了线程切换…

1.C语言教程:历史、特点、版本与入门示例

目录 1.历史2.特点3.版本4.编译5.Hello World 示例 1.历史 本篇原文为&#xff1a;C语言教程&#xff1a;历史、特点、版本与入门示例。 更多C进阶、rust、python、逆向等等教程&#xff0c;可去此站查看&#xff1a;酷程网 C 语言的诞生源于 Unix 系统的开发需求。 1969 年…

lec7-路由与路由器

lec7-路由与路由器 1. 路由器硬件 路由器的硬件部分&#xff1a; 断电失去&#xff1a; RAM断电不失去&#xff1a;NVRAM&#xff0c; Flash&#xff0c; ROMinterface也算是一部分 路由器是特殊组件的计算机 console 口进行具体的调试 辅助口&#xff08;Auxiliary&…

spring防止重复点击,两种注解实现(AOP)

第一种&#xff1a;EasyLock 简介 为了简化可复用注解&#xff0c;自己实现的注解&#xff0c;代码简单随拿随用 使用方式 1.创建一个注解 Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) Documented public interface EasyLock {long waitTime() default …

Linux-Ubuntu之I2C通信

Linux-Ubuntu之I2C通信 一&#xff0c;I2C通信原理1.写时序2.读时序 二&#xff0c;代码实现三&#xff0c;显示 一&#xff0c;I2C通信原理 使用I2C接口驱动AP3216C传感器&#xff0c;该传感器能实现两个效果&#xff0c;一个是感应光强&#xff0c;另一个是探测物体与传感器…

音视频入门基础:MPEG2-PS专题(4)——FFmpeg源码中,判断某文件是否为PS文件的实现

一、引言 通过FFmpeg命令&#xff1a; ./ffmpeg -i XXX.ps 可以判断出某个文件是否为PS文件&#xff1a; 所以FFmpeg是怎样判断出某个文件是否为PS文件呢&#xff1f;它内部其实是通过mpegps_probe函数来判断的。从《FFmpeg源码&#xff1a;av_probe_input_format3函数和AVI…

框架模块说明 #09 日志模块_01

背景 日志模块是系统的重要组成部分&#xff0c;主要负责记录系统运行状态和定位错误问题的功能。通常&#xff0c;日志分为系统日志、操作日志和安全日志三类。虽然分布式数据平台是当前微服务架构中的重要部分&#xff0c;但本文的重点并不在此&#xff0c;而是聚焦于自定义…

【数据仓库】hadoop3.3.6 安装配置

文章目录 概述下载解压安装伪分布式模式配置hdfs配置hadoop-env.shssh免密登录模式设置初始化HDFS启动hdfs配置yarn启动yarn 概述 该文档是基于hadoop3.2.2版本升级到hadoop3.3.6版本&#xff0c;所以有些配置&#xff0c;是可以不用做的&#xff0c;下面仅记录新增操作&#…

算法题(25):只出现一次的数字(三)

审题&#xff1a; 该题中有两个元素只出现一次并且其他元素都出现两次&#xff0c;需要返回这两个只出现一次的数&#xff0c;并且不要求返回顺序 思路: 由于对空间复杂度有要求&#xff0c;我们这里不考虑哈希表。我们采用位运算的方法解题 方法&#xff1a;位运算 首先&#…

将机器学习预测模型融入AI agent的尝试(一)

将机器学习临床预测模型融入AI agent的尝试&#xff08;一&#xff09; 我主要是使用机器学习制作临床预测模型和相关的应用&#xff0c;最近考虑的事情是自己之前的的工作能不能和AI agent进行融合&#xff0c;将AI 对自然语言理解能力和预测模型的预测能力结合在一起&#x…

51单片机——按键实验

由于机械点的弹性作用&#xff0c;按键开关在闭合时不会马上稳定的接通&#xff0c;在断开时也不会一下子断开&#xff0c;因而在闭合和断开的瞬间均伴随着一连串的抖动。抖动时间的长短由按键的机械特性决定的&#xff0c;一般为 5ms 到 10ms&#xff0c;为了确保 CPU 对按键的…

电子邮件对网络安全的需求

&#xff08; 1&#xff09;机密性&#xff1a;传输过程中不被第三方阅读到邮件内容&#xff0c;只有真正的接收方才可以阅读邮件。&#xff08; 1.5 分&#xff09; &#xff08; 2&#xff09;完整性&#xff1a;支持在邮件传输过程中不被篡改&#xff0c;若发生篡改&#…

vue路由模式面试题

vue路由模式 1.路由的模式有哪些?有什么区别? history和hash模式 区别: 1.表现的形态不同: 在地址栏url中:hash模式中带有**#**号,history没有 2.请求错误时表现不同: 在hash模式中,对于404地址请求时,不会进行请求 但是在history模式中,对于404请求时,仍然会进行请求…

电子应用设计方案86:智能 AI背景墙系统设计

智能 AI 背景墙系统设计 一、引言 智能 AI 背景墙系统旨在为用户创造一个动态、个性化且具有交互性的空间装饰体验&#xff0c;通过融合先进的技术和创意设计&#xff0c;提升室内环境的美观度和功能性。 二、系统概述 1. 系统目标 - 提供多种主题和风格的背景墙显示效果&…

Python爬虫 - 豆瓣图书数据爬取、处理与存储

文章目录 前言一、使用版本二、需求分析1. 分析要爬取的内容1.1 分析要爬取的单个图书信息1.2 爬取步骤1.2.1 爬取豆瓣图书标签分类页面1.2.2 爬取分类页面1.2.3 爬取单个图书页面 1.3 内容所在的标签定位 2. 数据用途2.1 基础分析2.2 高级分析 3. 应对反爬机制的策略3.1 使用 …

西安电子科技大学初/复试笔试、面试、机试成绩占比

西安电子科技大学初/复试笔试、面试、机试成绩占比 01通信工程学院 02电子工程学院 03计算机科学与技术学院 04机电工程学院 06经济与管理学院 07数学与统计学院 08人文学院 09外国语学院 12生命科学与技术学院 13空间科学与技术学院 14先进材料与纳米科技学院 15网络与信息安…

多模态论文笔记——CogVLM和CogVLM2(副)

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍多模态模型的LoRA版本——CogVLM和CogVLM2。在SD 3中使用其作为captioner基准模型的原因和优势。 文章目录 CogVLM论文背景VLMs 的任务与挑战现有方法及…

智慧工地信息管理与智能预警平台

建设背景与政策导向 智慧工地信息管理与智能预警平台的出现&#xff0c;源于工地管理面临的诸多挑战&#xff0c;如施工地点分散、危险区域多、监控手段落后等。随着政府对建筑产业现代化的积极推动&#xff0c;各地纷纷出台政策支持智慧工地的发展&#xff0c;旨在通过信息技…

【从零开始入门unity游戏开发之——C#篇42】C#补充知识——随机数(Random)、多种方法实现string字符串拼接、语句的简写

文章目录 一、随机数1、Random.Next()生成随机整数示例&#xff1a;生成一个随机整数生成指定范围内的随机整数 2、Random.NextSingle生成随机浮点数示例&#xff1a;生成随机浮点数 3、 生成随机字母或字符示例&#xff1a;生成随机字母示例&#xff1a;生成随机小写字母 二、…