設計并制作一臺出租車計費器。
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設計思路
出租車計費器的整體結構包括:分頻模塊、計費器模塊以及選擇模塊。
另外我拓展了變速模塊、亮燈模塊、計時器模塊。
通過不同頻率的分頻模塊產生一個脈沖信號模擬汽車的啟動與停止,然后通過計數模塊,計算出一共所行駛的路程,最后通過記費模塊,將所行駛的路程計算出相對應的價錢。計費顯示起步價7元,2km之內為起步價,以后每1km在起步價7元的基礎上增加1.6元;超過10km以后,每1km增加2.4元。通過自己設定的公式計算出費用,這就是計費模塊。結合生活中的出租車計費器,分別有2km以內,10km以內以及超過10Km以后的計費標準。我設計用撥動開關來實現清零與車速的轉換,并通過數碼管來顯示路程與車費。每產生一個脈沖就代表前進了一公里,因此,脈沖頻率的快慢就是車速的快慢,脈沖的多少就是路程,這就是車速以及路程的計算;當路程的脈沖只在兩個以內,就只有7元起步價。于是便實現了車行駛2km以內,只收起步價7元。行駛超過2km后,按每公里1.6元在7.0元的基礎上增加。行駛超過10km后(或超過20元路費),每公里加收50%的車費,即車費變為每公里2.4元。
1.2.2總體設計框圖
附錄2:程序清單
1秒分頻器
module fpq1(clk,clk_1s);
input clk;
output regclk_1s; reg[24:0]counter; always@(posedge clk) begincounter=counter+'b1; if(counter==20000000)counter=0;
else if(counter<=10000000)clk_1s='b0;
else clk_1s='b1;
end
endmodule
2秒分頻器
module fpq1(clk,clk_1s);
input clk;
output reg clk_1s;
reg[24:0] counter;
always @(posedge clk)
begin counter=counter+'b1;
if(counter==20000000)counter=0;
elseif(counter<=10000000)clk_1s='b0; elseclk_1s='b1; end
endmodule
0.5秒分頻器
module fpq5(clk,clk_5s);
input clk;
output reg clk_5s;
reg[24:0] counter;
always @(posedge clk)
begin counter=counter+'b1;
if(counter==10000000)counter=0; elseif(counter<=5000000)clk_5s='b0; elseclk_5s='b1; end
endmodule
速度選擇
module suduxz(k1,k2,clk1,clk2,clk5,speed);
input clk1,clk2,clk5,k1,k2;
output reg speed;
always@(posedge clk1 or posedge clk2 or posedge clk5)
begin
case({k1,k2})
'b00:speed=0;
'b01:speed=clk2;
'b10:speed=clk1;
'b11:speed=clk5;
endcase
end
endmodule
記錄路程
module jsq99(clr,clk,q,cout,a);
input clk,clr,a;
output reg[7:0]q;
output reg cout;
always @(posedge clk or negedge clr)
begin
if(~clr) q=0;
else begin
if(a==0)
begin
if(q=='h99) q=0;
else q=q+1;
if(q[3:0]=='ha)
begin
q[3:0]=0;
q[7:4]=q[7:4]+1;
end
if(q==0) cout=1;
else cout=0;end
end
end
endmodule
計費器
module jf(clk,clrn,q,k2);
input clk,k2;
input clrn;
output reg[11:0] q;
reg[3:0] c;
always @(posedge clk or negedge clrn)
begin
if(~clrn)begin c=0;q=0;end else begin
if(k2==0)
begin
if(c<14) c=c+1;
if(c<=2) q[7:4]=7;
else if(c<=10)
begin
q[3:0]=q[3:0]+6;q[7:4]=q[7:4]+1;
if(q[3:0]>9)beginq[3:0]=q[3:0]-10;q[7:4]=q[7:4]+1;end if(q[7:4]>9)beginq[7:4]=q[7:4]-10;q[11:8]=q[11:8]+1; end end
elseif(c>10) begin
q[3:0]=q[3:0]+4;q[7:4]=q[7:4]+2;
if(q[3:0]>9)beginq[3:0]=q[3:0]-10;q[7:4]=q[7:4]+1;end if(q[7:4]>9)beginq[7:4]=q[7:4]-10;q[11:8]=q[11:8]+1;end end
end if(c>14) c=11;end
end
endmodule
60秒計時器
module cnt60(clk,clr,q,cout);
input clk,clr;
output reg cout;
output reg[7:0] q;
reg[7:0] q_temp;
always @(posedge clk,negedge clr)
begin
if(~clr)q_temp=0; elsebegin if(q_temp==59)q_temp=0; elseq_temp=q_temp+'b1;
if(q_temp==59)cout=1; elsecout=0; end
q[3:0]=q_temp%10;
q[7:4]=q_temp/10;
end
endmodule
24秒計時器
module cnt24(clk,clr,q,cout);
input clk,clr;
output reg cout;
output reg[7:0] q;
always @(posedge clk,negedge clr)
begin
if(~clr)q=0; elsebegin if(q=='h23) q=0; else q=q+'b1; if(q[3:0]=='ha) begin q[3:0]='b0; q[7:4]=q[7:4]+'b1; end
if(q=='h23) cout=1; else cout=0; end end
endmodule
選擇器
module xzq(k,qm,qf,qs,q,ql,sum);
input k;
input[7:0]qm,qf,qs,ql; input[11:0]sum; outputreg[23:0] q;
always
begin
if(k==0) begin
q[7:0]=ql;q[11:8]=0;q[23:12]=sum; end elseq[23:0]={qs,qf,qm}; end
Endmodule
注:全文設置為固定值20磅
|