名称:出租车计费系统的设计Verilog代码Xilinx ISE EVM31开发板
软件:Xilinx ISE
语言:Verilog
代码功能
该出租车计费系统基于FPGA实现完整的计费功能,包括起步价计算、里程计费和时间计费。系统支持三种计费模式:起步阶段(3公里内)、里程计费(速度大于1m/s)和时间计费(速度小于等于1m/s)。具有上客、下客、速度调节等控制功能,实时计算并显示费用。系统采用状态机设计,确保计费逻辑的正确性和稳定性。
本代码已在EVM31开发板验证,EVM31开发板如下,其他开发板可以修改管脚适配:
代码实现思路
系统采用五状态状态机设计:空闲状态、起步阶段、里程计费、时间计费和完成状态。速度检测模块根据外部速度信号计算实际行驶速度。计费逻辑根据行驶距离和时间自动切换计费模式,起步价90角,超过3公里后按里程(50米1角)和时间(10秒1角)计费。显示模块采用动态扫描技术驱动数码管显示费用信息。
代码结构
系统采用层次化模块结构:
- taxi.v - 主计费模块,实现状态机和计费逻辑
- taxi_top.v - 顶层模块,集成所有功能
- div.v - 除法运算模块,用于费用计算
- debounce.v - 按键消抖模块
- bcd_8421.v - BCD码转换模块
- hc595_ctrl.v - 74HC595控制模块
- seg_dynamic.v - 动态显示模块
- speed_gen.v - 速度生成模块
各模块协同工作,实现完整的出租车计费功能。
部分代码
// 出租车计费主模块
module taxi#(
parameter TIME_1S = 50000000 // 1秒时间
)(
input clk, // 50MHz时钟输入
input rst_n,
input speed_flag, // 模拟速度的按键 一次按键增加速度
input key_start, // 上客开始计费按钮
input key_off, // 下客按钮
output reg led, // led指示灯
output reg [19:0] cost // 费用
);
parameter IDLE = 5'b00001; // 等客阶段
parameter WORK_STEP = 5'b00010; // 起步阶段 3Km以内
parameter WORK_MILEAGE = 5'b00100; // 超过3km使用里程计费
parameter WORK_TIME = 5'b01000; // 超过3km使用时间计费
parameter DONE = 5'b10000; // 下客阶段
reg [4:0] state; // 状态寄存器
// 按键消抖处理
reg key_start_buf0, key_start_buf1;
reg key_off_buf0, key_off_buf1;
wire start_en, off_en;
assign start_en = ((key_start_buf0 == 1'b1) & (key_start_buf1 == 1'b0)) ? 1'b1 : 1'b0;
assign off_en = ((key_off_buf0 == 1'b1) & (key_off_buf1 == 1'b0)) ? 1'b1 : 1'b0;
// 计费逻辑
wire [19:0] cost_buf;
assign cost_buf = (distance >= 3000) ? business_distance[19:0] + business_time[19:0] + 90 : 20'd90;
// 状态机转换
always@(posedge clk or negedge rst_n)
if (rst_n == 1'b0)
state <= IDLE;
else
case (state)
IDLE:
if (start_en == 1'b1)
state <= WORK_STEP;
else
state <= IDLE;
WORK_STEP:
if (off_en == 1'b1) // 下客时完成
state <= DONE;
else if (distance >= 3000) // 超过起步距离
if (speed > 1) // 速度大于1m/s使用里程计费
state <= WORK_MILEAGE;
else // 速度小于等于1m/s使用时间计费
state <= WORK_TIME;
else
state <= WORK_STEP;
// 其他状态转换逻辑...
endcase
// 状态机输出信号
always@(posedge clk or negedge rst_n)
if (rst_n == 1'b0)
distance <= 20'b0;
time_cnt_1s <= 32'b0;
time_cnt <= 20'b0;
cost <= 20'b0;
led <= 1'b0;
else
case (state)
IDLE:
distance <= 20'b0;
cost <= 20'b0;
led <= 1'b0;
WORK_STEP:
if (time_cnt_1s >= TIME_1S - 1'b1) // 计时
time_cnt_1s <= 32'b0;
distance <= distance + speed * 2; // 距离累加
cost <= 20'd90; // 起步价90角
led <= 1'b1;
// 其他状态输出逻辑...
endcase
endmodule
134