基于FPGA的出租车计费器的设计

1 概述

EDA(Electronic Design
Automation)即电子设计自动化,是电子设计技术的核心,它的系统级高层次电子设计方法,对整个系统进行方案设计和功能划分,无须通过门级原理图描述电路,而是针对设计目标进行功能描述,。

FPGA
是现场可编程门阵列的简称。它结合了微电子技术、电路技术和EDA技术,使设计者可以集中精力进行所需逻辑功能的设计,缩短设计周期,提高设计质量。FPGA的开发系统包括软件和硬件两个部分,开发系统软件指专用的编程语言和相应的汇编程序或编译程序。开发系统硬件部分包括计算机和编程器。编程器是对FPGA进行写入和擦除的专用装置,能够供写入或擦除操作所需要的电源电压和控制信号,并通过串行接口从计算机接收编程数据,最终写进FPGA之中。

基于FPGA的计费器系统利用Verilog
HDL语言,采用模块化程序设计,自顶向下、由粗到细、逐步求精的方法,将基于FPGA的计费器系统的整体逐步分解各个模块。它不需要专门的硬件,只通过软件编程即可实现计费器系统的逻辑功能、电路结构和连接形式。Verilog
HDL语言类似C语言,可读性强、更易理解,这种语言几乎覆盖了以往各种硬件描述语言的功能,在编程的过程中一般采用自顶向下的电路设计过程。

本设计利用Verilog
HDL语言,在QuartusⅡ13.0软件中将出租车计费器基本结构分成6个模块对其进行程序汇编。将各块程序生成的.v文件组合在一起,生成数字钟源代码的.bdf
图形文件,最后下载到CycloneⅡ系列芯片EP20C8Q208C8N中,验证试验结果。

1.1 设计要求

1.1.1 设计任务

设计并制作一台出租车计费器。

1.1.2 性能指标要求

① 用EDA实训仪的I/O设备和PLD芯片实现出租车计费器的设计。


出租车起步开始计程和计费,计程系统按实际公里数计程,计费系统首先显示起步价(如7.0),车行驶2km以内,只收起步价7元。

③ 出租车行驶超过2km后,按每公里1.6元在7.0元的基础上增加。


出租车行驶超过10km后(或超过20元路费),每公里加收50%的车费,即车费变为每公里2.4元。

⑤ 出租车达到目的地后,(用一个按钮)计程和计费数据清零,为下一次计费开始。

1.2 总体设计基本原理及框图

1.2.1 基本原理

该出租车计费器的基本原理方框图如图1所示,由时钟模块、控制模块、计程模块、音乐模块、LCD显示模块、计费模块6部分组成。该计费系统通过分频模块将20MHz的时钟信号通过分频器变成1Hz的时钟信号和50Hz的显示输出信号。该出租车计费的标准是起步价是6元,2公里之内费用不变,当超过2公里时,每行驶1公里,费用加收50%元;由peo信号来控制有人或者没人,高电平有人,低电平显示空车,出租车计费显示模块显示相应的费用和行驶的里程。当res为低电平时,计费系统复位。该计费系统的显示费用是0~999.9元

1.2.2 总体框图

![C:\Users\Home\Documents\Tencent
Files\1120572057\Image\C2C\Y[}1L5]CNPLAM@@]JI254WK.png](media/924498901234891f75b5b1eb34710397.png)

图1 总体框图

2 系统软件设计分析

整个系统由6个模块组成:

2.1时钟模块

时钟模块,提供实时时间,并可以通过按键调节分钟和小时并由其qs、qm、qh分别输出秒、分、时,clk20m输入20Mhz,clrn清零,fj和hj为调分和调时。用于区分白天与夜间计费,白天时间6:00~00:00、夜间时间00:00~6:00,由两个60进制计数器和一个24进制计数器组成,生成一个元件符号。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pl4hVYoX-1619189226876)(media/ce142d58869d07f6e5e0c9d80abace7a.png)]

图2-1 时钟模块元件符号图

60进制计数器程序:

module cont60(clk,clrn,q,cout,j);

input j,clrn,clk;

output reg [7:0] q;

output reg cout;

always @( posedge clk^j or posedge clrn )

begin

if(clrn) q=0;

else

begin

q = q+1; if(q[3:0] >= 10)

begin q[3:0] = 0;q[7:4] = q[7:4]+1;

if(q[7:4] >= 6) q[7:4] = 0;

end

if( q == 'h00 ) cout = 1;else cout = 0;

end

end

endmodule

24进制计数器程序:

module cont24(clk,clrn,q,cout,j);

input j,clk,clrn;

output reg [7:0] q;

output reg cout;

always@( posedge clk^j or posedge clrn )

begin

if(clrn)begin q=0;cout = 0;end

else

begin

q = q+1; if(q[3:0] >= 10)

begin q[3:0] = 0; q[7:4] = q[7:4]+1;

end

if( q >= 'h24 )

begin q = 0; cout = 1; end

else cout = 0; end end endmodule

图2-2 时钟仿真图

2.2控制模块

控制模块是用于控制车速的模块clk输入20Mhz,res清零作用,key_up是加速、key_down是减速,对应速度有0km/h、20km/h、40km/h——260km/h、280km/h、300km/h共15个速度调节来产生不同的频率由clk_speed输出,20km/h即11.1m每秒,所以20km/h要产生一秒为11100个上升沿,20Mhz/(2*11100),而gear输出不同的档位,通过对20MHz分频来产生不同的频率对应不同的速度,1秒内10000个上升沿表示1秒行驶了1m,改变频率即改变了1秒内上升沿的个数,就改变了速度。

图2-3 按键控制模块元件符号图

控制模块程序:

module key(clk,

key_up,

gear,

res,

key_down,

clk_speed,

people);

input res,people;

input key_up,clk,key_down;

output reg clk_speed;

reg [29:0] clk_sp_reg;

output reg[3:0]gear;

reg [29:0]up_c,down_c,n;

initial begin

gear='b1000;up_c=0;down_c=0;n=0;

clk_sp_reg=0;

end

always@( posedge clk or posedge res)//加速减速控制

begin

if(res) begin down_c=0;up_c=0;end

else if(!people)begin up_c=0; down_c =0; end else

begin

if(key_up)

begin

up_c=up_c+1’b1;

end

else

begin

up_c=0;

end

if(key_down)

begin

down_c=down_c+1’b1;

end

else

begin

down_c=0;

end

end

end

always @(posedge clk or posedge res)//速度对应的分频数,

begin

if(res) begin gear=0; end

else if(!people)begin gear=0; clk_sp_reg=0; end else

begin

if(key_up ^ key_down )

begin

if(key_up==1)

begin

if(up_c==5 && gear<='b1110)//200000)

gear=gear+1;

if(gear>='b1111)

gear='b1111;

end

if(key_down==1)

begin

if(down_c==5)//200000)

if(gear=='b0)

gear='b0;else gear=gear-1;

end

end

case (gear)

0 : ; //速度为0

1 : clk_sp_reg=909;

2 : clk_sp_reg=454;

3 : clk_sp_reg=303;

4 : clk_sp_reg=227;

5 : clk_sp_reg=181;

6 : clk_sp_reg=151;

7 : clk_sp_reg=129;

8 : clk_sp_reg=113;

9 : clk_sp_reg=101;

10 : clk_sp_reg=90;

11 : clk_sp_reg=82;

12 : clk_sp_reg=75;

13 : clk_sp_reg=69;

14 : clk_sp_reg=64;

15 : clk_sp_reg=60;

endcase

end

end

always @( posedge clk or posedge res) //把20MHz分频,产生相对应速度的频率

begin

if(res)begin n<=0;clk_speed<=0;end

else if(!people)begin n<=0;clk_speed<=0; end else

begin

if (n>=clk_sp_reg && gear!=0)

begin n<=0;clk_speed<=~clk_speed; end

else

begin n<=n+1; clk_speed<=clk_speed;end

end

end

endmodule

图2-4 控制模块仿真图

2.3计程模块

计程模块由五个100进制的计数器组成,clk输入控制模块分频出来的频率,然后在计程模块进行计数,只显示qshiwan到qshiyi的计程其中qshiwan[7:4]是百米计程,这样能使计费精确到分以下,所以计程用1000个上升沿记为1米,

图2-5 计程模块元件符号图

计程模块程序:

module counter0_99(clk,clr,q,cout,people);

input clk,clr,people;

output reg [7:0] q;

output reg cout;

reg one='b1;

initial q='h99;

always@( posedge clk or posedge clr or negedge people )

begin

if(clr ) q=0;

else

begin if(!people) q=0;

else

begin

q = q+1;

if(q[3:0] >= 10)

begin

q[3:0] = 0;

q[7:4] = q[7:4]+one;

if(q[7:4] >= 10)

q[7:4] = 0;

end

if( q == 0 )

cout = 1;

else

cout = 0;

end end end endmodule

图2-6 计程模块仿真图

2.4音乐模块

音乐模块的clk是时钟输入,people是有人和没人的状态标志,beep外接蜂鸣器,并设定了两个音乐《送别》和《起风了》,作为乘客上车下车时播放的音乐,播放音乐的原理是通过改变频率来改变音高,改变延时时间来确定一小节拍的时间是240ms,通过分频产生。

//音高与频率的对应关系

//| | 1 | 2 | 3 | 4 | 5 | 6 | 7 |

//|低音 |261.6Hz |293.7Hz |329.6Hz |349.2Hz | 392Hz | 440Hz |493.9Hz |

//|中音 |523.3Hz |587.3Hz |659.3Hz |698.5Hz | 784Hz | 880Hz |987.8Hz |

//|高音 |1045.5Hz|1174.7Hz|1318.5Hz|1396.9Hz| 1568Hz | 1760Hz
|1975.5Hz|

//乐谱参数:D=F/2K (D:参数,F:时钟频率,K:音高频率)

图2-7 音乐模块元件符号图

音乐模块程序:

module music( clk,people, beep);

input clk,people;

output reg beep;

reg flag ,flag1;

reg[7:0] state,state1; //乐谱状态机

reg[16:0]count,count_end;

reg[23:0]count1,count2; //乐谱参数:D=F/2K (D:参数,F:时钟频率,K:音高频率)

parameter S_0=8’d20000000,

L_1 = 17’d38226, M_1 = 17’d19109, H_1 = 17’d09564, //音1

L_2 = 17’d34048, M_2 = 17’d17027, H_2 = 17’d08512, //音2

L_3 = 17’d30339, M_3 = 17’d15167, H_3 = 17’d07584, //音3

L_4 = 17’d28636, M_4 = 17’d14316, H_4 = 17’d07158, //音4

L_5 = 17’d25510, M_5 = 17’d13368, H_5 = 17’d06377, //音5

L_6 = 17’d22727, M_6 = 17’d11363, H_6 = 17’d05681, //音6

L_7 = 17’d20247, M_7 = 17’d10123, H_7 = 17’d05062; //音7

parameter TIME = 2400000; //控制每一个音的长短(480ms)

parameter TIME1 = 4800000; //控制每一个音的长短(240ms)

always @(posedge clk)

begin

if(people==0)

begin

flag=1; state1 =0;count2=0;

if(flag1==1)

begin

count = count + 1’b1; //计数器加1

if(count == count_end && count_end!=S_0)

begin count = 17’h0; //计数器清零

beep = !beep;end //输出取反

if(count1 < TIME) count1 = count1 + 1’b1;

//一个节拍240mS data=F/2/ms T=2*N*Tc

else begin count1 = 24’d0;

if(state == 8’d127)

begin flag = 0;state=8’d0; end

else state = state + 1’b1;

case(state)

8’d0,8’d1,8’d2,8’d3: count_end = M_5;//低音"3",4个节拍

8’d4,8’d5: count_end = M_3;//低音"5",持续2个节拍

8’d6,8’d7: count_end = M_5;//低音"6",持续2个节拍

8’d8,8’d9,8’d10,8’d11,

8’d12,8’d13,8’d14,8’d15: count_end = H_1;//高音"1",8拍

8’d16,8’d17,8’d18,8’d19: count_end = M_6;//中音"6",4拍

8’d20,8’d21,8’d22,8’d23: count_end = H_1;//高音"1",4拍

8’d24,8’d25,8’d26,8’d27,

8’d28,8’d29,8’d30,8’d31,

8’d32,8’d33,8’d34,8’d35: count_end = M_5;//中音"5",8拍

8’d36,8’d37: flag1=0;//count_end = M_1;//低音"5",2拍

endcase

end

end

end

else

if(people==1)

begin

flag1=1; state =0;count1=0;

if(flag==1)

begin

count = count + 1’b1; //计数器加1

if(count == count_end)

begin count = 17’h0; //计数器清零

beep = !beep;end //输出取反

if(count2 < TIME1) count2 = count2 + 1’b1;

//一个节拍240mS data=F/2/ms T=2*N*Tc

else begin count2 = 24’d0;

if(state1 == 8’d229)

begin flag = 0;state1=8’d0; end

else state1 = state1 + 1’b1;

case(state1)

8’d0,8’d1 : count_end = M_1;

8’d2,8’d3 : count_end = M_2;

8’d4,8’d5 : count_end = M_3;

8’d6,8’d7 : count_end = M_1;//

8’d8,8’d9 : count_end = M_6;

8’d10 : count_end = M_5;

8’d11 : count_end = M_6;

8’d12 : count_end = M_6;

8’d13,8’d14 : flag=0;//count_end = S_0;

endcase

end

end

end

end

endmodul

2.5 LCD显示模块

显示模块是使用LCD1602液晶屏,其中clk是时钟,people是有人和没人的状态为rstn是清零,in_data是档位输入,q0到q4是公里数输入,qs、qm、qh是时钟输入,cost_lcd_in是费用输入,显示界面可以显示时间、行驶路程、速度、费用,由于程序数据转换太多,这里只给出一部分程序,后面的程序在附录。

LCD1602主要技术参数:显示容量:16×2个字符、芯片工作电压:4.5—5.5V、工作电流:2.0mA(5.0V)、模块最佳工作电压:5.0V、字符尺寸:2.95×4.35(W×H)mm。

图2-8 LCD1602模型图

编号 符号 引脚说明 编号 符号 引脚说明
1 VSS 电源地 9 D2 数据
2 VDD 电源正极 10 D3 数据
3 VL 液晶显示偏压 11 D4 数据
4 RS 数据/命令选择 12 D5 数据
5 R/W 读/写选择 13 D6 数据
6 E 使能信号 14 D7 数据
7 D0 数据 15 BLA 背光源正极
8 D1 数据 16 BLK 背光源负极

表1 引脚接口说明表

序号 指令 RS R/W D7 D6 D5 D4 D3 D2 D1 D0
1 清显示 0 0 0 0 0 0 0 0 0 1
2 光标返回 0 0 0 0 0 0 0 0 1 *
3 置输入模式 0 0 0 0 0 0 0 1 I/D S
4 显示开/关控制 0 0 0 0 0 0 1 D C B
5 光标或字符移位 0 0 0 0 0 1 S/C R/L * *
6 置功能 0 0 0 0 1 DL N F * *
7 置字符发生存贮器地址 0 0 0 1 字符发生存贮器地址
8 置数据存贮器地址 0 0 1 显示数据存贮器地址
9 读忙标志或地址 0 1 BF 计数器地址
10 写数到CGRAM或DDRAM) 1 0 要写的数据内容
11 从CGRAM或DDRAM读数 1 1 读出的数据内容

表2 控制指令表

1602液晶模块的读写操作,屏幕和光标的操作都是通过指令编程来实现的。(说明1为高电平,0为低电平)

指令1:清显示,指令码01H,光标复位到地址00H位置

指令2:光标复位,光标返回到地址00H

指令3:光标和显示位置设置I/D,光标移动方向,高电平右移,低电平左移,S:屏幕上所有文字是否左移或右移,高电平表示有效,低电平表示无效。

指令4:显示开关控制。D:控制整体的显示开与关,高电平表示开显示,低电平表示关显示。C:控制光标的开与关,高电平表示有光标,低电平表示无光标
B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。

指令5:光标或显示移位 S/C :高电平时显示移动的文字,低电平时移动光标

指令6:功能设置命令 DL:高电平时为4位总线,低电平时为8位总线
N:低电平时为单行显示,高电平时为双行显示,F:低电平时显示5X7的点阵字符,高电平时显示5X10的显示字符。

指令7:字符发生器RAM地址设置。

指令8:DDRAM地址设置。

指令9:读忙信号和光标地址
BF:忙标志位,高电平表示忙,此时模块不能接收命令或数据,如果为低电平表示不忙。

图2-9 LCD显示模块元件符号图

LCD显示模块程序:

module lcd1602(sys_clk ,

sys_rstn ,

lcd_rs ,

lcd_rw ,

lcd_en ,

lcd_data ,

in_data,

q0,q1,q2,q3,q4,qs,qm,qh,people,

cost_lcd_in

); //输入输出信号定义

input [31:0] cost_lcd_in;

input [7:0] q0,q1,q2,q3,q4,qs,qm,qh;

input sys_clk ;//系统时钟输入

input people, sys_rstn ;//系统复位信号,低电平有效

input [3:0] in_data;

output lcd_rs ;//lcd的寄存器选择输出信号

output lcd_rw ;//lcd的读、写操作选择输出信号

output lcd_en ;//lcd使能信号

output [7:0] lcd_data ;//lcd的数据总线(不进行读操作,故为输出)

reg lcd_rs ;

reg clk_div ;

reg [7:0] q1h,q1l,q2h,q2l,q3h,q3l,q4l;

reg [7:0] sp_reg1,sp_reg2,sp_reg3;

reg [7:0] qsl,qsh,qml,qmh,qhl,qhh;

reg [7:0] in_data_reg;

reg [7:0] cost_reg0,cost_reg1,cost_reg2,cost_reg3;

reg [17:0] delay_cnt ;

reg [7:0] lcd_data ;

reg [4:0] char_cnt ;

reg [7:0] data_disp ;

reg [9:0] state ;

parameter

idle = 10’b000000000, //初始状态,下一个状态为CLEAR

clear = 10’b000000001, //清屏

set_function = 10’b000000010,

switch_mode = 10’b000000100,

set_mode = 10’b000001000,

shift = 10’b000010000,

//光标、画面位移设置:光标向左平移一个字符位

set_ddram1 = 10’b000100000,

//设置DDRAM的地址:第一行起始为0x00(注意输出时DB7一定要为1)

set_ddram2 = 10’b001000000, //设置DDRAM的地址:第二行为0x40 write_ram1 =
10’b010000000, //数据写入DDRAM相应的地址

write_ram2 = 10’b100000000; //数据写入DDRAM相应的地址

assign lcd_rw = 1’b0; //没有读操作,R/W信号始终为低电平

assign lcd_en = clk_div; //E信号出现高电平以及下降沿的时刻与LCD时钟相同
always@(posedge sys_clk or posedge sys_rstn) /分频

begin if(sys_rstn) begin delay_cnt<=18’d0; clk_div<=1’b0;

end else if(delay_cnt==18’d200000)

begin

delay_cnt<=18’d0; clk_div<=~clk_div; end else

begin delay_cnt<=delay_cnt+1’b1; clk_div<=clk_div;

end end

always@(posedge clk_div or posedge sys_rstn) //State Machine

begin if(sys_rstn)

begin state <= idle; lcd_data <= 8’b0; char_cnt <= 5’d0;

lcd_rs<=1’b0;//地址\数据

end else begin

case(state)

idle: begin //初始状态

state <= clear; lcd_data <= 8’b0; end

clear: begin //清屏

state <= set_function;

lcd_rs<=1’b0;

lcd_data <= 8’b00000001;

end

set_function: //功能设置(38H):8位数据接口/2行显示/5*8点阵字符

begin state <= switch_mode; lcd_rs<=1’b0;

lcd_data <= 8’b00111000; end

switch_mode: //显示开关控制(0CH):开显示,光标和闪烁关闭

begin state <= set_mode; lcd_rs<=1’b0;

lcd_data <= 8’b00001110; end

set_mode:begin //输入方式设置(06H):数据读写操作后,地址自动加一/画面不动

state <= shift; lcd_rs<=1’b0;

lcd_data <= 8’b00000110; end

shift: begin //光标、画面位移设置(10H):光标向左平移一个字符位

//(光标显示是关闭的,所以实际上设置是看不出效果的)

state <= set_ddram1; lcd_rs<=1’b0;

lcd_data <= 8’b0001_0000; end

set_ddram1: //设置DDRAM的地址:第一行起始为00H(注意输出时DB7一定要为1)

begin state <= write_ram1;

lcd_rs<=1’b0; lcd_data <= 8’b1000_0000;//Line1

end

set_ddram2: //设置DDRAM的地址:第二行为40H(DB7一定要为1)

begin state <= write_ram2;

lcd_rs<=1’b0; lcd_data <= 8’b1100_0000;//Line2

end

write_ram1:

begin

if(char_cnt <=5’d15)

begin char_cnt <= char_cnt + 1’b1;

lcd_rs<=1’b1; lcd_data <= data_disp;

state <= write_ram1; end

else begin state <= set_ddram2; end

end

write_ram2:

begin

if(char_cnt <=5’d30)

begin char_cnt <= char_cnt + 1’b1;

lcd_rs<=1’b1; lcd_data <= data_disp;

state <= write_ram2; end

else begin char_cnt <=5’d0; state <= shift; end

end

default: state <= idle;

endcase

end

end

2.6计费模块

计费模块其中clk是20MHz输入,clrn清零,people是有人没人的状态位,q0到q4为里程输入,qh为小时输入,用于判断白天计程和夜间计费,其中又分0~2km不计程,2~10km加20%费用,且白天和夜间的四个计费阶段都有相对应的指示灯闪烁(L12到L15),白天:7元2km内7元,2km-10km每公里收费1.6元,10km以上每公里收费2.4元;夜间:起步价8元2km内8元,2km-10km每公里收费2元,10km以上每公里收费3元。cost_q输出费用。10km以上加收费用,1000个上升沿即为1米,则1km——1.6元,1000000个上升沿对应160分,1分即6250个上升沿,由于程序数据转换太多,这里只给出一部分程序,后面的程序在附录。

图2-10 计费模块元件符号图

计费模块程序:

module counter0_99_16(

clk,clr,cost_q,people,

q0,q1,q2,q3,q4,qh,

l12,l13,l14,l15

);

input clk,clr,people;

output reg l12,l13,l14,l15;

input [7:0] q0,q1,q2,q3,q4,qh;

output reg [31:0] cost_q;

reg [13:0] n;

reg one='b1;

initial n=0;

initial cost_q='b0000_0000_0000_0000_0000_1000_0000_0000;

always@( posedge clk or posedge clr or negedge people )

begin

if(clr ) begin l12=0;l13=0;l14=0;l15=0;cost_q=0;end

else

begin if(!people) begin l12=0;l13=0;l14=0;l15=0;

if(qh>'b00000110)cost_q='b0000_0000_0000_0000_0000_0111_0000_0000;

else if(qh<='b00000110)cost_q='b0000_0000_0000_0000_0000_1000_0000_0000; end

else

begin

if(qh>8’b00000110)

begin

if({q4,q3,q2,q0}<=32’b0000_0000_0001_0000_0000_0000_0000_0000

&& {q4,q3,q2,q0}>32’b0000_0000_0000_0010_0000_0000_0000_0000 ) begin

//1000000电平除以160分,得出一分6250个上升沿

if(n < 'd6250) //1.6元

begin n=n+'d1; end

if(n >= 'd6250)

begin

n<=0;

begin

l12=~l12;l13=0;l14=0;l15=0;

cost_q = cost_q+1;

if(cost_q[3:0] >= 10)

begin cost_q[3:0] = 0;

cost_q[7:4] = cost_q[7:4]+one;end

if(cost_q[7:4] >= 10)

begin cost_q[7:4] = 0;

cost_q[11:8] = cost_q[11:8]+one;end

if(cost_q[11:8] >= 10)

begin cost_q[11:8] = 0;

cost_q[15:12] = cost_q[15:12]+one;end

if(cost_q[15:12] >= 10)

begin cost_q[15:12] = 0;

cost_q[19:16] = cost_q[19:16]+one;end

if(cost_q[19:16] >= 10)

begin cost_q[19:16] = 0;

cost_q[23:20] = cost_q[23:20]+one;end

if(cost_q[23:20] >= 10)

begin cost_q[23:20] = 0;

cost_q[27:24] = cost_q[27:24]+one;end

if(cost_q[27:24] >= 10)

begin cost_q[27:24] = 0;

cost_q[31:28] = cost_q[31:28]+one;end

end

end

end else

end

end

end

end

endmodule

图2-11 计费模块仿真图

3 系统测试(调试)

3.1 测试仪器与设备

① EDA实验仪一台。

② 计算机一台(装有Quartus Ⅱ软件)

3.2 性能指标测试

把程序下载进实验箱,按键控制有人和没人的状态,蜂鸣器能正常播放音乐,然后运行计费器,通过计算的出的费用和路程相符合,白天和夜间的起步价、2km到10km计费标准和10km以上的计费标准都正确,且能显示正确的速度,时间,路程,四个收费阶段都有相对应的指示灯闪烁提示,速度的各档速也有相对应的灯点亮。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-34JtQeYN-1619189226885)(media/024cb6b92b850231a7fd4fa75f86ccfb.png)]

图3-1 引脚锁定

3.3 结果分析

达到了所要完成的基本功能,并在此功能上扩展出来,一些额外功能,在显示方面使用了LCD1602的液晶显示屏显示时间、速度、里程和费用,并有一个一天的计时器,且能够分为白天和夜间计费,并在人上车下车的时候能够用蜂鸣器播放音乐。

4 波形发生器设计

波形发生器设计,能够产生锯齿波、三角波、方波和正弦波,采用LPM_ROM,储存四个波形的数字,然后直接输出波形的数据即可,并在此基础上采用两个按键控制四个频率的转换。

锯齿波ROM数据,从0自加到255。

三角波ROM数据:从0到127自加,每次加2,从128到255自减每次减2。

正弦波ROM数据:用正弦波发生函数。

正弦波数据C语言程序:

#include <stdio.h>

#include “math.h”

main()

{

int i,k;

for(i=0;i<256;i++)

{

k=128+128*sin(360.0*i/256.0*3.1415926/180);

printf("%d : %d\n",i,k);

}

return 0;

}

方波ROM数据:从0到127自加,为255,从128到255为0。

计数模块:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-R83iS7hq-1619189226886)(media/227d232942c6eef01da61cb2e680f6be.png)]

图4-1 计数器元件符号图

LPM_ROM模块:


图4-3 选择波形元件符号图

选择波形的程序:

module data_selector4_1 (A,B,C,D,s0,s1,z);

input s0;

input s1;

input [7:0] A;

input [7:0] B;

input [7:0] C;

input [7:0] D;

output reg [7:0] z;

always@( s0 or s1 or A or B or C or D)

begin

case ( {s1,s0} )

'b00 : z=A;

'b01 : z=B;

'b10 : z=C;

'b11 : z=D;

default : z='bz;

endcase

end

endmodule

分频选择部分:

图4-4 选择频率元件符号图

分频选择程序:

module clk_ch (key1,key2,clk,clk_c);

input clk;

input key1;

input key2;

output reg clk_c;

reg [7:0]h;

reg [7:0]y;

always@( posedge clk )

begin

case ({key2,key1})

'b00:y=0;

'b01:y=2;

'b10:y=4;

'b11:y=6;

endcase

if(h == y)

begin h<=0;clk_c<=~clk_c; end

else begin h<=h+1;clk_c<=clk_c;end

end endmodule



图4-8 频率转换结果图

5 实训总结

在做本次课程设计的过程中,我感触最深的当属查阅大量的设计资料了。为了让自己的设计更加完善,查阅这方面的设计资料是十分必要的,同时也是必不可少的。另外,这次课程设计让我感到了团队合作的重要性。在团队中,我们互帮互助,对整个课程设计来说,这是至关重要的,缺少每一个人都会对我们的设计产生影响。还有要感谢指导老师在我们遇到困难时,给予我们的建议与鼓励。一周的课程设计结束了,但是从中学到的知识会让我受益终身。发现、提出、分析、解决问题和实践能力的提高都会受益于我在以后的学习、工作和生活中。
为期一个星期的课程实训,在覃老师的亲切指导和同学的帮助下,此次设计才得以完成,在此向所有给予我此次课程设计指导和帮助的老师和同学表示最诚挚的感谢!

6 参考文献

[1] 江国强,覃琴.EDA技术与应用(第5版):电子工业出版社,2017

[2]赵倩,叶波,林丽萍,周多,王晓华.Verilog数字系统设计与FPGA应用[M].北京:清华大学出版社,2012

[3]吴迪,杨梅,严飞.EDA与数字系统实验教程[M].大连:大连海事大学出版社,2011

附录

总体原理图

总仿真图

基于FPGA的出租车计费器的设计相关推荐

  1. 设计题目:基于CPLD/FPGA的出租车计费器

    一.设计任务及要求: 本设计要求设计一个基于CPLD/FBGA的出租车计费器,其具体要求如下: 1  能够实现计费功能 费用是按行驶的里程进行 计算的,设出租车的起价是6.0元,当里程小于3km时,按 ...

  2. 单片机c语言出租车计时程序,基于单片机的出租车计费(c语言).doc

    基于单片机的出租车计费(c语言) 基于单片机的出租车计费(c语言) 基于proteus仿真 一.设计要求: 1.用实现出租车计费器的设计. 出租车起步开始计程和计费,计程系统按实际公里数计程,计费系统 ...

  3. 出租车收费题目及答案c语言,《基于单片机的出租车计费(c语言)》.doc

    基于单片机的出租车计费(c语言)基于proteus仿真 一.设计要求: 1.用实现出租车计费器的设计. 出租车起步开始计程和计费,计程系统按实际公里数计程,计费系统首先显示起步价(如.0),车行驶2k ...

  4. 基于FPGA的数码管显示出租车计费器

    基于FPGA简易出租车计价器设计技术规范 专业:集成电路设计与集成系统 班级:电路1401班 姓名:童峥 学号:05146034 一. 功能描述: 本设计基于FPGA设计并使用Verilog HDL硬 ...

  5. 基于 FPGA 的数字抢答器设计

    下面是基于 FPGA 的数字抢答器设计,在quartusII下,modelsim下仿真,编程语言VHDL.   1.抢答器的工作原理 主持人宣布可以抢答后,在 20s 的定时时间内若有人按键抢答,则这 ...

  6. 基于 FPGA 的智力抢答器设计

    本文设计文档及源码将在公众号 果冻空间 免费公布,关注公众号回复A-001获取,博文展示过少,有需要公众号获取,目前公众号仅仅作为资源管理的平台,提供资料链接 基于 FPGA 的智力抢答器设计 题目简 ...

  7. 基于FPGA的智力抢答器设计

    配套FPGA开发板(含该设计的工程代码):https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-4676525296.4.6e8950ed57YPh ...

  8. 基于FPGA的竞赛抢答器

    基于FPGA的竞赛抢答器,使用verilog语言设计实现. 实验要实现的基本功能是 主持人按下开始,三个人抢答,主持人可以给选手加分或者减分,分数用数码管来显示.以下是主要功能和指标: (1)设计一个 ...

  9. 基于FPGA的音乐播放器系统设计_kaic

    摘 要 音乐播放器随处可见,广播.CD.MP3.车载播放器.智能家居等系统,都用播放器娱乐着我们的生活.FPGA以硬件描述语言完成的电路设计,具有运算速度快,编程简单又稳定性,长期维护,成本等优点,本 ...

  10. 基于FPGA的音频处理芯片的设计

    基于FPGA的音频处理芯片的设计 时间:2009-01-07 10:00:18 来源:维库电子市场 作者:刘虹 黄涛 徐成 1 引言 随着数字技术日益广泛的应用,以现场可编程门阵列FPGA(Field ...

最新文章

  1. xgboost源码 要看的
  2. 突发灵感,看到某网站的搞笑图片挺多,做了一个小java,扫描抠了一些
  3. Android Binder 分析——数据传递者(Parcel)
  4. Flex手机开发-退出应用程序
  5. 数字化经营支付3.0有哪些盈利机会
  6. 数据结构和算法分析英语生词整理
  7. Linux系统C/C++通用错误码实现模板
  8. 腾讯王兰:覆盖12大场景,45个应用,5G变革的关键是“串联”
  9. 人人能上手:OpenAI发射初学者友好的强化学习教程 | 代码简约易懂
  10. 2.1 InnoDB存储引擎(概述、版本、体系结构)
  11. 如何解决jsp中文乱码的问题
  12. jszip 解压压缩包_Node.js使用jszip实现打包zip压缩包
  13. Tableau可视化---Tableau简介
  14. 图片怎么压缩成指定大小?怎么能把图片压缩到200k?
  15. 短期出差北京个人所见所闻所感
  16. 下列不是SQL的服务器组件,北语网院15秋《数据库应用(SQL server)》作业3答案...
  17. mysql怎么做纵表,本文实例讲述了MySQL横纵表相互转化操作实现方法。分享给大家供大家参考,具体如下:先创建一个成绩表(纵表)create table user_scor...
  18. cad渐开线齿轮轮廓绘制_CAD画齿轮的方法
  19. 【学习记录】图片行列切割与子图行列拼接之中央裁剪法
  20. c++动态数组的优点,创建和删除

热门文章

  1. 华为手机克隆无法迁移联系人_华为手机克隆软件使用问题及解决办法
  2. 中科院SCI分区和JCR分区
  3. 【等保】二级等保常见问题解答汇总
  4. Java POI 合并单元格操作以及代码示例
  5. java poi 合并单元格 边框显示不全
  6. python医学科研中能做什么-科研画图都用什么软件?
  7. 安装wget 、 wget命令
  8. c51汇编语言如何定义全局变量_汇编语言程序访问C语言全局变量
  9. 利用opencv对图像进行二值化处理
  10. Java项目源码下载S2SH基于java的保险业务管理系统