公司做网站设计的,深圳交易服务中心官网,wordpress gae,品牌网站建设市场欢迎各位朋友关注“郝旭帅电子设计团队”#xff0c;本篇为各位朋友介绍基于FPGA的出租车计费系统设计—第一版
功能说明#xff1a; 收费标准#xff08;里程#xff09;#xff1a;起步价5元#xff0c;包括三公里#xff1b;三公里之后#xff0c;每公里2元#x…欢迎各位朋友关注“郝旭帅电子设计团队”本篇为各位朋友介绍基于FPGA的出租车计费系统设计—第一版
功能说明 收费标准里程起步价5元包括三公里三公里之后每公里2元不到一公里不收费。 收费标准低速等待费当计费开始车辆速度低于某一速度时开始收取低速等待费三分钟收取2元不足三分钟不收费 整体收费里程计费低速等待费 设置有计费开始/停止按钮。 设置有档位控制按钮0档停止不动1档3分钟一公里2档1分钟一公里。当计费开始0档和1档位需要累加低速等待计费。 利用六个数码管显示信息。 显示模式一第一个数码管显示是否计费A计费停止 C计费开始第二个数码管显示档位0、1、2第三个至六个显示应收钱数。 显示模式二总计运行时间 显示模式三前三个里程后三个里程收费 显示模式四前三个低速等待时长分钟后三个低速等待费。 设置有显示模式切换按钮。 计费停止后重新按下计费开始上述所有统计从0开始。 为了下板后能够比较快速显示出效果所有的时间加速30倍.
使用平台本次设计应用Altera的平台设计芯片EP4CE10F17C8N。
仿真平台Modelsim。
作者QQ746833924
说明本篇设计中不涉及到IP和原语代码在其他平台依然可以适用当其他板卡电路不同时会导致不同的现象出现如有需要修改代码请联系作者如需作者使用的板卡请联系作者
设计思想如下 key_ctrl模块负责将外部输入的按键进行消抖产生按键按下时的脉冲。
taxi_meter_ctrl模块负责根据外部输入的三个脉冲和出租车计费的规则产生对应的输出数据。
seven_tube_drive模块负责将taxi_meter_ctrl产生的数据显示到数码管上。
key_ctrl模块设计思想为按键信号是由外部机械式按键产生每次按下或者抬起时会产生一定的抖动。如果直接对其进行边沿检测就会导致多次触发。故而需要设计按键消抖进而对消抖之后的波形进行边沿检测。消抖原理为外部按键信号发生改变后如果能够持续20ms没有新的改变就认为此次改变不是抖动而是真正的按下然后进行采样即可。
// 记录任意边沿之后没有遇到新的边沿的时间长度是否达到20Ms //--------------------------------------------------------------------------------------- always(posedgeclk)beginif(rst_n 1b0)cnt_20ms 20d0;elseif(pulse_key_negedge 1b1||pulse_key_posedge 1b1)cnt_20ms 20d1;elseif(cnt_20ms 20d0cnt_20ms T_20ms)cnt_20ms cnt_20ms 1b1;elsecnt_20ms 20d0;end// --------------------------------------------------------------------------------------- // 任意边沿之后没有遇到新的边沿的时间长度达到20Ms认为按键稳定此时采样 //-------------------------------------------------------------------------------------- always(posedgeclk)beginif(rst_n 1b0)key_wave 1b1;elseif(cnt_20ms T_20ms)key_wave key_rr;elsekey_wave key_wave;end//--------------------------------------------------------------------------------------// 对消抖之后的按键信号进行边沿检测 //---------------------------------------------------------------------------------------------initialkey_wave_r 1b1;always(posedgeclk)key_wave_r key_wave;assignflag_neg (key_wave_r 1b1key_wave 1b0)?1b1:1b0;assignflag_pos (key_wave_r 1b0key_wave 1b1)?1b1:1b0;//--------------------------------------------------------------------------------------------
taxi_meter_ctrl模块的设计原理如下
根据flag_start_stop的信号确定运行状态。 always (posedge clk) beginif (rst_n 1b0)state_run 1b0;elseif (flag_start_stop 1b1)state_run ~state_run;elsestate_run state_run;end根据flag_gear的信号确定出租车的档位。 always (posedge clk) beginif (rst_n 1b0)gear 2d0;elseif (flag_gear 1b1) if (gear 2d2)gear gear 1b1;elsegear 2d0;elsegear gear;end
确定公里数以及根据规则确定钱数。
停止运行了后公里数不要清除也需要翻看公里数需要在下一次启动时清除
flag_mileage_add是公里数递增的脉冲。 always (posedge clk) beginif (rst_n 1b0)mileage 10d0;elseif (state_run 1b0 flag_start_stop 1b1)mileage 10d0;elseif (state_run 1b1)if (flag_mileage_add 1b1)if (mileage 10d999)mileage mileage 1b1;elsemileage mileage;elsemileage mileage;elsemileage mileage;endalways (posedge clk) beginif (rst_n 1b0)money_mileage 10d0;elseif (mileage 10d4)money_mileage 10d5;elsemoney_mileage (mileage - 10d3) * 2 5;end产生flag_mileage_add的逻辑为记录三分钟如果是0档则计数器不动如果是1档则计数器加1由于加速30倍所以加30如果是2档则计数器加3由于加速30倍所以加90由于每次并不是加1所以最大值并一定正好能达到所以超过最大值时减去最大值。 always (posedge clk) beginif (rst_n 1b0) begincounter 64d0;flag_mileage_add 1b0;endelseif (state_run 1b1)if (gear 2d1)if (counter 34d9_000_000_000 - 1b1) begincounter counter 30;flag_mileage_add 1b0;endelse begincounter counter - (34d9_000_000_000 - 1b1);flag_mileage_add 1b1;endelseif (gear 2d2)if (counter 34d9_000_000_000 - 1b1) begincounter counter 90;flag_mileage_add 1b0;endelse begincounter counter - (34d9_000_000_000 - 1b1);flag_mileage_add 1b1;endelse begincounter counter;flag_mileage_add 1b0;endelse begincounter 64d0;flag_mileage_add 1b0;endend记录整体的运行时间加速30倍 always (posedge clk) beginif (rst_n 1b0)cnt_1s_all_timer 26d0;elseif (state_run 1b1)if (cnt_1s_all_timer T_1s - 1b1)cnt_1s_all_timer cnt_1s_all_timer 30;elsecnt_1s_all_timer cnt_1s_all_timer - (T_1s - 1b1);elsecnt_1s_all_timer 26d0;endalways (posedge clk) beginif (rst_n 1b0)sec_counter_all_timer 32d0;elseif (state_run 1b0 flag_start_stop 1b1)sec_counter_all_timer 32d0;elseif (cnt_1s_all_timer T_1s - 1b1)sec_counter_all_timer sec_counter_all_timer 1b1;elsesec_counter_all_timer sec_counter_all_timer;end
确定低速等待时间加速30倍计数器为1分钟的计数器
然后根据1分钟的计数器确定等待了多长时间 always (posedge clk) beginif (rst_n 1b0) min_wait_timer 32d0;elseif (state_run 1b1) if (gear 2d0 || gear 2d1)if (min_wait_timer T_60s - 1b1)min_wait_timer min_wait_timer 30;elsemin_wait_timer min_wait_timer - (T_60s - 1b1);elsemin_wait_timer min_wait_timer;elsemin_wait_timer 32d0;endalways (posedge clk) beginif (rst_n 1b0)wait_min 32d0;elseif (state_run 1b0 flag_start_stop 1b1) wait_min 32d0;elseif (state_run 1b1 (gear 2d0 || gear 2d1) min_wait_timer T_60s - 1b1)wait_min wait_min 1b1;elsewait_min wait_min;end
根据低速等待时间确定低速等待费。 always (posedge clk) beginif (rst_n 1b0)money_wait 32d0;elsemoney_wait (wait_min/3) * 2;end
最终的费用等于里程费用加上低速等待费。 always (posedge clk) beginif (rst_n 1b0)money_all 11d0;elsemoney_all money_mileage money_wait;end
根据切换显示的脉冲确定需要显示的模式 always (posedge clk) beginif (rst_n 1b0)state_show 2d0;elseif (flag_show 1b1)state_show state_show 1b1;elsestate_show state_show;end
一个模式显示车辆运行状态档位和收费。 initial data0[23:20] 4ha;always (posedge clk) beginif (rst_n 1b0)data0[23:20] 4ha;elseif (state_run 1b1)data0[23:20] 4hc;elsedata0[23:20] 4ha;endalways (posedge clk) beginif (rst_n 1b0)data0[19:16] 4h0;elsedata0[19:16] {2d0,gear};endalways (posedge clk) beginif (rst_n 1b0)data0[15:0] 16d0;elsedata0[3:0] money_all % 10;data0[7:4] money_all/10 % 10;data0[11:8] money_all/100 % 10;data0[15:12] money_all/1000 % 10;end
第二个模式显示整体的运行时间换算成为时分秒。 always (posedge clk) beginif (rst_n 1b0)data1 24d0;elsedata1[23:20] sec_counter_all_timer / 3600 / 10 % 10;data1[19:16] sec_counter_all_timer / 3600 % 10;data1[15:12] sec_counter_all_timer % 3600 / 60 / 10 % 10;data1[11:8] sec_counter_all_timer % 3600 / 60 % 10;data1[7:4] sec_counter_all_timer % 60 / 10 % 10;data1[3:0] sec_counter_all_timer % 60 % 10;end第三个模式显示历程历程计费。 always (posedge clk) beginif (rst_n 1b0)data2 24d0;elsedata2[23:20] mileage / 100;data2[19:16] mileage / 10 % 10;data2[15:12] mileage % 10;data2[11:8] money_mileage / 100;data2[7:4] money_mileage / 10 % 10;data2[3:0] money_mileage % 10;end第四个模式显示低速等待计费和低速等待时间。 always (posedge clk) beginif (rst_n 1b0)data3 24d0;elsedata3[23:20] wait_min / 100;data3[19:16] wait_min / 10 % 10;data3[15:12] wait_min % 10;data3[11:8] money_wait / 100;data3[7:4] money_wait / 10 % 10;data3[3:0] money_wait % 10;end
根据外部的显示脉冲确定需要显示的模式 always (posedge clk) beginif (rst_n 1b0)state_show 2d0;elseif (flag_show 1b1)state_show state_show 1b1;elsestate_show state_show;endalways (posedge clk) beginif (rst_n 1b0)data 23d0;else case (state_show)2d0 : data data0;2d1 : data data1;2d2 : data data2;2d3 : data data3;default : data data0;endcaseend
以上为taxi_meter_crtl的设计思想
七段数码管为普通六位一体的共阳极数码采用动态驱动的方式在此不再赘述。
下板后我们就可以看到出租车计费系统的运行情况。 讲解和演示视频链接如下
https://www.bilibili.com/video/BV184421D7MT/?vd_sourceb5405faeab8632f02533bcbfc5e52e55
本设计所有内容设计代码、设计工程链接为
链接https://pan.baidu.com/s/1vLDLaQckYVFUMS8hQolcaQ 提取码01v6
本篇内容中有部分资源来源于网络如有侵权请联系作者。
如果您觉得本公众号还不错的话可以推给身边的朋友们感谢并祝好