FPGA出租车计费系统设计

这篇具有很好参考价值的文章主要介绍了FPGA出租车计费系统设计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、需求分析

        设计一个简易的出租车计费系统,实现计价功能,计费标准为按里程收费,起步价为6.00元,当里程小于3公里时,按起步价收费,超过3公里后按1.2元/公里收费。

        实现车辆行驶的模拟:能模拟汽车的启动,暂停,停止等状态。

        计费显示部分设计:用LED数码管实时显示车费和汽车行驶里程,用一个按键切换车费和里程的显示,里程单位km,记程范围为0-99km。

二、输入输出端口

输入:系统时钟、系统复位、行驶模拟按键(启动、暂停、停止)、显示切换按键

输出:①数码管段选位选(没有驱动芯片)

           ②ds数据、oe使能、shcp移位时钟、stcp寄存时钟(74hc595串并转换数码管驱动芯片)

设计一个出租车计费系统起步价为5元(2km以内),2km后,0.8元/0.5km;要,FPGA学习,fpga开发

三、模块介绍

1.计费逻辑状态机:

        状态机的核心是一个case语块,是一种编程思想。case的条件是不同的状态(state),每个状态下分别进行各种操作,状态的切换由输入信号条件控制。在写法上可以只定义一个状态(state),或者定义两个状态(now_state、next_state)现态和次态。再写一个状态转移,让次态不断传递给现态,完成状态的切换。

        在本项目中,使用状态机思想,描述汽车的启动、暂停、停止几种状态。

        停止状态:此状态下对车费和里程清零,并判断启动键是否按下,进入启动状态

        启动状态:让里程自增(模拟汽车行驶)让车费为6元,当里程大于等于3公里,车费开始每公里1.2元增加。

        暂停状态:不进行操作,只判断启动和停止键是否按下进行跳转。

2.数码管动态显示:

        数码管一般是由7个led灯组成,称为7段数码管,加上dp小数点称为8段。  

设计一个出租车计费系统起步价为5元(2km以内),2km后,0.8元/0.5km;要,FPGA学习,fpga开发

        如图,要显示数字“1”,bc亮,其他不亮,段码则为1001_1111,转为16进制从低位到高位数,为F9。开发板上有6位数码管,即6个这样的数码管连接在一起,通过位选来控制让哪一个数码管有效,再通过段选控制显示的内容。

        所以,动态显示=位选信号从1-6扫描为周期,例如要显示数字“2023”,在选通1号数码管亮的时候,段选为“3”;接着选通2号数码管亮,段选输出“2”;接着让3号数码管亮,段选“0”;4号数码管亮,段选“2”,这样通过高速4次扫描,由于人眼暂留效应,看到的就是“2023”同时亮起的效果。

3.bcd_8421模块:

        明白了数据的获取(计费逻辑)与显示(动态数码管),但实际上要想把一个数字的不同数位分别显示出来,还需要一个拆分功能把一个数拆成小数位、个位、十位、百位等,然后把不同位分别送入不同数码管动态显示。

        起初我是自己用除法写了拆分逻辑,进行电路综合后发现,在FPGA芯片中,除法非常占用资源,导致我的资源块超出(下图报错信息),无法进行布局布线设计。FPGA有硬件乘法器,但没有除法器。如果非要用除法,建议使用ip核除法软核,不过ip核也是使用“+,-,移位”实现的。所以不如自己写一个拆分模块。

assign	fare_g[7:4] = (fare/10) % 10;    
assign	fare_g[11:8] = (fare/100) % 10;
assign	fare_g[15:12] = (fare/1000) % 10;

设计一个出租车计费系统起步价为5元(2km以内),2km后,0.8元/0.5km;要,FPGA学习,fpga开发

        拆分思想是,先补零,移位判断是否大于4,大于就加3再判断。对于十进制数的位数进行判断,例如“234”,3位,补3x4=12个0,进行如下操作后,“2”“3”“4”就被拆开分别放入3组4位二进制里了。(下图取自野火FPGA教程)

设计一个出租车计费系统起步价为5元(2km以内),2km后,0.8元/0.5km;要,FPGA学习,fpga开发

        对费用数据、里程数据进行拆分后,分别放入段选寄存器中,按位把数据组一个一个送入595芯片,595芯片将串行传入的数据,进行移位存入寄存器,当一组8位数据存好,再复制到输出寄存器并行输出,编写控制移位时钟和寄存器时钟的时序,送入595芯片,即可实现串并转换。

        如果没有595芯片,就需要编写动态扫描周期进程,按照位选段选时序要求,依次让数码管不同位显示不同数据。

四、代码

1.计费逻辑与显示数据生成模块

module  data_gen	//数据生成模块
#(
    parameter   CNT_MAX = 26'd49_999_999,
)
(
    input 	wire		sys_clk		,	 // 系统时钟
	input	wire		sys_rst_n	,	 // 系统复位
	
	input   wire 		start		,    // 启动
    input   wire 		stop		,    // 停止
    input   wire 		pause		,    // 暂停
    input   wire 		key_switch	,    // 切换显示,
    
    output  reg     [19:0]  data,	//数据输出
    output  reg    [5:0]  point,	//小数点
    output  wire            sign,	//正负号
    output  reg           seg_en	//显示使能
);

parameter	STOP  = 4'b0000 ,	//停止
			START = 4'b0001 ,	//启动
			PAUSE = 4'b0010 ;	//暂停,三个状态值

reg     [25:0]  cnt_100ms;
reg             cnt_flag;

reg [10:0]  fare;          // 车费
reg [6:0]  total_distance; // 总行驶里程
reg [3:0]  state;          // 车辆状态

//100ms的计费自增周期产生
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_100ms <= 26'd0;
    else if(cnt_100ms == CNT_MAX)
        cnt_100ms <= 26'd0;
    else
        cnt_100ms <= cnt_100ms + 1'b1;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_flag <= 1'b0;
    else if(cnt_100ms == CNT_MAX - 1'b1)
        cnt_flag <= 1'b1;
    else 
        cnt_flag <= 1'b0;
 
//计费逻辑状态机进程 
always@(posedge sys_clk or negedge sys_rst_n)
	if(!sys_rst_n)
		begin
        fare <= 11'b0;				//初始化车费、路程等清零
        total_distance <= 7'b0;
        state <= 4'b0;
		end 
	else 
		begin		  //状态机各个状态转换
        case (state)
            STOP:  // 停止状态
                if(start == 1'b0)
					begin
                    state <= START;  // 切换到启动状态
					end
				else
					begin
					total_distance <= 7'b0;
					fare <= 11'b0;
					end
            START:  // 启动状态
                if(pause == 1'b0) 
					begin
                    state <= PAUSE;  // 切换到暂停状态
					end 
				else if(cnt_flag == 1'b1)
					begin
                    total_distance <= total_distance + 1'b1;  // 模拟行驶
                    if(total_distance <= 7'd2) 
						begin
                        fare <= 11'd60;  // 起步价6.00元
						end 			 // 这里用60代表6元,12代表1.2元
					else
					begin
                        fare <= fare + 11'd12;  // 超过3公里,每公里1.2元
                    end
					end 
				else if(stop == 1'b0) begin
                    state <= STOP;  // 切换到停止状态
                end
            PAUSE:  // 暂停状态
                if(start == 1'b0) 
					begin
                    state <= START;  // 切换到启动状态
					end 
				else if(stop == 1'b0) 
					begin
                    state <= STOP;  // 切换到停止状态
					end
        endcase
		end

//显示切换进程
always@(posedge sys_clk or negedge sys_rst_n)
	if(!sys_rst_n)
		begin
			data <= 20'd0;
			point <= 6'b000_000;
		end
	else if(key_switch == 1'b0)		//显示费用模式
		begin
			data <= fare;	
			point <= 6'b000_010;
		end
	else						//显示里程模式
		begin
		data <= total_distance;
		point <= 6'b000_000;
		end
		
assign  sign  = 1'b0;
  
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        seg_en <= 1'b0;
    else 
        seg_en <= 1'b1;
        
endmodule

2.595芯片驱动控制模块

module  hc595_ctrl
(
    input   wire        sys_clk  ,	//系统时钟
    input   wire        sys_rst_n,	//系统复位
    input   wire   [7:0]   seg   ,	//数码管段选
    input   wire   [5:0]   sel   ,	//数码管位选
    
    output  reg      shcp         ,	//移位时钟
    output  reg      stcp         ,	//寄存器时钟
    output  reg      ds           ,	//数据
    output  wire     oe           	//使能
);

wire    [13:0]  data    ;
reg     [1:0]   cnt     ;
reg     [3:0]   cnt_bit ;

assign  data = {seg[0],seg[1],seg[2],seg[3],
                seg[4],seg[5],seg[6],seg[7],sel};	//把段位数据放入data

//产生周期扫描信号
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt <= 2'd0;
    else if(cnt == 2'd3)
        cnt <= 2'd0;
    else 
        cnt <= cnt + 2'd1;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_bit <= 4'd0;
    else if((cnt_bit == 4'd13) && (cnt == 2'd3))
        cnt_bit <= 4'd0;
    else if(cnt == 2'd3)
        cnt_bit <= cnt_bit + 1'b1;
    else
        cnt_bit <= cnt_bit;

//按周期扫描信号,依次把数据传入595芯片ds
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        ds <= 1'b0;
    else if(cnt == 2'd0)
        ds <= data[cnt_bit];
    else
        ds <= ds;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        shcp <= 1'b0;
    else if(cnt == 2'd2)
        shcp <= 1'b1;
    else if(cnt == 1'b0)
        shcp <= 1'b0;
    else
        shcp <= shcp;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        stcp <= 1'b0;
    else if((cnt == 1'b0) && (cnt_bit == 4'd0))
        stcp <= 1'b1;
    else if((cnt ==2'd2) && (cnt_bit ==4'd0))
        stcp <= 1'b0;
    else
        stcp <= stcp;
        
assign  oe = 1'b0;

endmodule

3.bcd_8421数据拆分模块

module  bcd_8421
(
    input   wire         sys_clk     ,
    input   wire         sys_rst_n   ,
    input   wire [11:0]  data        ,	//要拆分的数据

    output  reg [3:0]   unit        ,	//拆分后的个位
    output  reg [3:0]   ten         ,	//十位
    output  reg [3:0]   hun         ,	//百位
    output  reg [3:0]   tho         	//千位
    
);

reg [3:0]   cnt_shift;
reg [27:0]  data_shift;
reg         shift_flag;

//循环移位次数
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_shift <= 4'd0;
    else if((cnt_shift == 4'd13)&& (shift_flag == 1'b1))
        cnt_shift <= 4'd0;
    else if(shift_flag == 1'b1)
        cnt_shift <= cnt_shift + 1'b1;
    else
        cnt_shift <= cnt_shift;
 
//4位一组进行判断>4否? 大于就加3
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_shift <= 27'd0;
    else if(cnt_shift == 4'd0)
        data_shift <= {16'b0,data};
    else if((cnt_shift <= 12) && (shift_flag == 1'b0))
        begin
            data_shift[15:12] <= (data_shift[15:12] > 4) ? (data_shift[15:12] +2'd3) : (data_shift[15:12]);
            data_shift[19:16] <= (data_shift[19:16] > 4) ? (data_shift[19:16] +2'd3) : (data_shift[19:16]);
            data_shift[23:20] <= (data_shift[23:20] > 4) ? (data_shift[23:20] +2'd3) : (data_shift[23:20]);
            data_shift[27:24] <= (data_shift[27:24] > 4) ? (data_shift[27:24] +2'd3) : (data_shift[27:24]);
        end
    else if((cnt_shift <= 12) && (shift_flag == 1'b1))  
        data_shift <= data_shift << 1;
    else
        data_shift <= data_shift;
        
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        shift_flag <= 1'b0;
    else
        shift_flag <= ~shift_flag;

//移位判断一个周期后,进行数据输出
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        begin
            unit  <= 4'd0;
            ten   <= 4'd0;
            hun   <= 4'd0;
            tho   <= 4'd0;
        end
    else if(cnt_shift == 5'd13)
        begin
            unit  <= data_shift[15:12];
            ten   <= data_shift[19:16];
            hun   <= data_shift[23:20];
            tho   <= data_shift[27:24];
        end
endmodule

4.数码管段选位选数据产生模块

`timescale  1ns/1ns
module  seg_dynamic
(
    input   wire            sys_clk  ,
    input   wire            sys_rst_n,
    input   wire    [19:0]  data     ,
    input   wire    [5:0]   point    ,
    input   wire            sign     ,
    input   wire            seg_en   ,

    output  reg    [7:0]   seg      ,
    output  reg    [5:0]   sel      
);

parameter     CNT_MAX = 16'd49_999;

wire [3:0]   unit        ;
wire [3:0]   ten         ;
wire [3:0]   hun         ;
wire [3:0]   tho         ;
wire [3:0]   t_tho       ;
wire [3:0]   h_hun       ;
reg [23:0]  data_reg    ;
reg [15:0]  cnt_1ms     ;
reg         flag_1ms    ;
reg [2:0]   cnt_sel     ;
reg [5:0]   sel_reg     ;
reg [3:0]   data_disp   ;
reg         dot_disp    ;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_reg <= 24'd0;    
    else if((h_hun) || (point[5]))	            //最高位非零,则全显示
        data_reg <= {h_hun,t_tho,tho,hun,ten,unit};
								        	    //次高位非零,少显示一位最高位
    else if(((t_tho) || (point[4])) && (sign == 1'b1))
        data_reg <= {4'd10,t_tho,tho,hun,ten,unit};
    else if(((t_tho) || (point[4])) && (sign == 1'b0))
        data_reg <= {4'd11,t_tho,tho,hun,ten,unit};
        
    else if(((tho) || (point[3])) && (sign == 1'b1))
        data_reg <= {4'd11,4'd10,tho,hun,ten,unit};
    else if(((tho) || (point[3])) && (sign == 1'b0))
        data_reg <= {4'd11,4'd11,tho,hun,ten,unit};
        
    else if(((hun) || (point[2])) && (sign == 1'b1))
        data_reg <= {4'd11,4'd11,4'd10,hun,ten,unit};
    else if(((hun) || (point[2])) && (sign == 1'b0))
        data_reg <= {4'd11,4'd11,4'd11,hun,ten,unit};
        
    else if(((ten) || (point[1])) && (sign == 1'b1))
        data_reg <= {4'd11,4'd11,4'd11,4'd10,ten,unit};
    else if(((ten) || (point[1])) && (sign == 1'b0))
        data_reg <= {4'd11,4'd11,4'd11,4'd11,ten,unit};
									                    //只显示最低位一位
    else if(((unit) || (point[0])) && (sign == 1'b1))
        data_reg <= {4'd11,4'd11,4'd11,4'd11,4'd10,unit};
    else 
        data_reg <= {4'd11,4'd11,4'd11,4'd11,4'd11,unit};

//1ms循环计数
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_1ms <= 16'd0;
    else if(cnt_1ms == CNT_MAX)
        cnt_1ms <= 16'd0;
    else
        cnt_1ms <= cnt_1ms +1'b1;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        flag_1ms <= 1'b0;
    else if(cnt_1ms == CNT_MAX -1'b1)
        flag_1ms <= 1'b1;
    else
        flag_1ms <= 1'b0;

//从0到5循环数,选择当前显示的数码管
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_sel <= 3'd0;
    else if((cnt_sel == 3'd5) && (flag_1ms == 1'b1))
        cnt_sel <= 3'd0;
    else if(flag_1ms == 1'b1)
        cnt_sel <= cnt_sel + 3'd1;
    else
        cnt_sel <= cnt_sel;

//根据上面进程,让位选信号移位       
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        sel_reg <= 6'b000_000;
    else if((cnt_sel == 3'd0) && (flag_1ms == 1'b1))
        sel_reg <= 6'b000_001;
    else if(flag_1ms == 1'b1)
        sel_reg <= sel_reg << 1;
    else
        sel_reg <= sel_reg;
   
//六个数码管轮流显示   
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)   
        data_disp <= 4'd0;
    else if((seg_en == 1'b1) &&(flag_1ms == 1'b1))
        case(cnt_sel)
            3'd0:   data_disp <= data_reg[3:0];
            3'd1:   data_disp <= data_reg[7:4];
            3'd2:   data_disp <= data_reg[11:8];
            3'd3:   data_disp <= data_reg[15:12];
            3'd4:   data_disp <= data_reg[19:16];
            3'd5:   data_disp <= data_reg[23:20];
            default:data_disp <= 4'd0;
        endcase
    else
        data_disp <= data_disp;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)  
        dot_disp <= 1'b1;
    else if(flag_1ms == 1'b1)
        dot_disp <= ~point[cnt_sel];
    else
        dot_disp <= dot_disp;

//数码管显示数字与段码映射
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0) 
        seg <= 8'b1111_1111;
    else
        case(data_disp)
            4'd0:   seg <= {dot_disp,7'b100_0000};
            4'd1:   seg <= {dot_disp,7'b111_1001};
            4'd2:   seg <= {dot_disp,7'b010_0100};
            4'd3:   seg <= {dot_disp,7'b011_0000};
            4'd4:   seg <= {dot_disp,7'b001_1001};
            4'd5:   seg <= {dot_disp,7'b001_0010};
            4'd6:   seg <= {dot_disp,7'b000_0010};
            4'd7:   seg <= {dot_disp,7'b111_1000};
            4'd8:   seg <= {dot_disp,7'b000_0000};
            4'd9:   seg <= {dot_disp,7'b001_0000};
            4'd10:  seg <= 8'b1011_1111;
            4'd11:  seg <= 8'b1111_1111;
            default: seg <= 8'b0000_0000;
        endcase

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0) 
        sel <= 6'b000_000;
    else 
        sel <= sel_reg;

bcd_8421    bcd_8421_inst
(
    .sys_clk     (sys_clk  ),
    .sys_rst_n   (sys_rst_n),
    .data        (data     ),

    .unit        (unit     ),
    .ten         (ten      ),
    .hun         (hun      ),
    .tho         (tho      ),
    .t_tho       (t_tho    ),
    .h_hun       (h_hun    )
);

endmodule

5.不使用595芯片版本,产生数码管扫描信号

//数据与数码管段码映射关系
always@(posedge sys_clk or negedge sys_rst_n)
	if(!sys_rst_n)
		begin
			seg_data <= 8'd0;
		end
	else 
		begin
		case (seg_cache)
			4'd0: seg_data <= {point,SEG_0};
			4'd1: seg_data <= {point,SEG_1};
			4'd2: seg_data <= {point,SEG_2};
			4'd3: seg_data <= {point,SEG_3};
			4'd4: seg_data <= {point,SEG_4};
			4'd5: seg_data <= {point,SEG_5};
			4'd6: seg_data <= {point,SEG_6};
			4'd7: seg_data <= {point,SEG_7};
			4'd8: seg_data <= {point,SEG_8};
			4'd9: seg_data <= {point,SEG_9};
			default: seg_data <= 8'b1111_1111;
		endcase
		end

//产生数码管位选扫描更新1ms刷新
always@(posedge clk_1ms or negedge sys_rst_n)
	if(!sys_rst_n)
		cnt_dig <= 1'b0;
	else if(cnt_dig == 2'd3)
		cnt_dig <= 1'b0;
	else
		cnt_dig <= cnt_dig + 1'b1;

//数码管段选位选数据扫描1ms刷新
always@(posedge clk_1ms or negedge sys_rst_n)
	if(!sys_rst_n)
		begin
			seg_cache <= 8'b1111_1111;
			seg_dig <= 4'b0000;
		end
	else if(key_switch == 1'b0)		//显示费用模式
		begin
			case (cnt_dig)
				2'd0: begin
						seg_dig <= 4'b1110;	//点亮第1位数码管
						seg_cache <= fare_g[3:0];	//费用的第1位
						point <= 1'b0;	//小数点不亮
					  end
				2'd1: begin
						seg_dig <= 4'b1101; //点亮第2位数码管
						seg_cache <= fare_g[7:4];	//费用的第2位
						point <= 1'b1;	//小数点亮
					  end
				2'd2: begin
						seg_dig <= 4'b1011; //点亮第3位数码管
						seg_cache <= fare_g[11:8];	//费用的第3位
						point <= 1'b0;	//小数点不亮
					  end
				2'd3: begin
						seg_dig <= 4'b0111; //点亮第4位数码管
						seg_cache <= fare_g[15:12];	//费用的第4位
						point <= 1'b0;	//小数点不亮
					  end
				default:;
			endcase
			end		
		else						//显示里程模式
			begin
			case (cnt_dig)
				2'd0: begin
						seg_dig <= 4'b1110;		//同上
						seg_cache <= distance_g[3:0];
					  end
				2'd1: begin
						seg_dig <= 4'b1101;
						seg_cache <= distance_g[7:4];
					  end
				2'd2: begin
						seg_dig <= 4'b1011;
						seg_cache <= 4'd0;
					  end
				2'd3: begin
						seg_dig <= 4'b0111;
						seg_cache <= 4'd0;
					  end
				default:;
			endcase
			end

五、仿真与实物效果演示

1.费用与里程关系

        60代表6元,12代表1.2元。由图可见:在里程从1km到3km递增时,费用固定60也即起步价6元;当里程4km,5km递增时,费用递增1.2元。符合设计要求。

设计一个出租车计费系统起步价为5元(2km以内),2km后,0.8元/0.5km;要,FPGA学习,fpga开发

2.数码管动态显示

Seg_data为数码管段选,seg_dig为数码管位选。由图可见:在费用fare为168,16.8元

位选1110,第1位数码管点亮,段码为00000000,显示数字8;

位选1101,第2位数码管点亮,段码为10000010,显示数字6;

位选1011,第3位数码管点亮,段码为01111001,显示数字1;

位选0111,第4位数码管点亮,段码为01000000,显示数字0。

其中第二位的小数点dp点亮,即代表第一位为小数,实际显示“016.8”,符合设计。

设计一个出租车计费系统起步价为5元(2km以内),2km后,0.8元/0.5km;要,FPGA学习,fpga开发

同上分析,在显示里程的时候,total_distance为35km,四位数码管依次显示“0035”。

设计一个出租车计费系统起步价为5元(2km以内),2km后,0.8元/0.5km;要,FPGA学习,fpga开发

3.上板演示

出租车计费系统演示

六、总结

        通过本次项目实战,巩固了数码管动态显示知识,提高了代码编写思路,在编写逻辑算法时,没有年初刚开始学习FPGA时的那种无从下手。也遇到很多bug,仿真时没有关掉modelsim,仿真报错,原因要关掉才能重新仿真。数据更新与数码管显示的频率要有合理的区分度,不然数据已经变化了,数码管还没动态刷新一个周期。在例化模块的时候,该用wire线型还是reg寄存器型,需要考虑清楚对这个信号进行了时序逻辑操作还是组合逻辑。文章来源地址https://www.toymoban.com/news/detail-766196.html

到了这里,关于FPGA出租车计费系统设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于单片机出租车计价器设计

     功能介绍 以51单片机作为主控系统; 1602液晶屏显示最初的起步价,里程收费,等待时间收费; 按键调整起步价,里程收费,等待时间收费; 电机旋转,通过霍尔传感器检测转速,来模拟出租车行驶; 电路图 仿真图 元器件清单 B1 5V直流电机+托盘(粘好磁铁) BT1 2032纽扣电

    2024年02月11日
    浏览(37)
  • 0097-基于单片机的出租车计价器仿真设计

    1、采用51/52单片机作为主控芯片; 2、采用1602液晶显示:里程、计价、实时时间、实时单价、本次行程计时; 3、采用DS1302作为时钟芯片; 4、支持切换显示界面、设置日期时间、设置白天单价、设置夜晚单价; 5、支持分别设置3千米内的单价、3千米外的单价、等待时的单价

    2024年02月20日
    浏览(38)
  • 【C51】基于51单片机的出租车计价器设计

    随着我国经济的快速发展,出行选择乘坐出租车的人越来越多。与此同时电子信息技术的发展更新,更加准确、便捷、稳定的出租车计价收费系统随之出现。基于单片机的出租车计价系统的设计,不仅可以更加准确、稳定的反映计价情况,也能促进出租车行业健康稳定的发展

    2024年02月03日
    浏览(42)
  • 出租车计价c语言

    本关任务:根据某城市普通出租车收费标准编写程序对车费进行计算。具体标准如下: 起步里程为3km,起步费为10元;10km以内超起步里程部分,每千米2元,超过10km以上的部分加收50%的回空补贴费,即每千米3元。营运过程中,因堵车及乘客要求临时停车的,按每5分钟2元计收

    2024年02月07日
    浏览(32)
  • Java语言怎么编写一个程序计算出租车的运输费用:出租车起步15公里以内20块钱,需要支付调头费用

    下面是一个Java语言编写的计算出租车运输费用的程序:   ```java import java.util.Scanner;   public class TaxiFareCalculator {     public static void main(String[] args) {         Scanner input = new Scanner(System.in);           System.out.print(\\\"请输入出租车行驶的里程(公里):\\\");         double distance

    2024年02月12日
    浏览(39)
  • 出租车GPS轨迹数据分析

    •使用numpy、pandas等完成“00.csv”文件读取; •剔除无效数据:GPS 采集出租车轨迹数据的过程中,可能因设备问题 导致数据没有采集到,故而在原始轨迹数据集中记录为空值。因此,需 要将每个采样点中有效字段为空值的数据进行剔除,即剔除 DeviceID、 Longitude、Latitude、

    2024年02月04日
    浏览(36)
  • 企业spark案例 —— 出租车轨迹分析(Python)

    头歌的大数据作业,答案没找着,遂自己整了一份 第1关:SparkSql 数据清洗 任务描述 本关任务:将出租车轨迹数据规整化,清洗掉多余的字符串。 相关知识 为了完成本关任务,你需要掌握:1. 如何使用 SparkSQL 读取 CSV 文件,2. 如何使用正则表达式清洗掉多余字符串。 编程要

    2024年02月03日
    浏览(39)
  • LeetCode 2008. 出租车的最大盈利:动态规划 + 哈希表

    力扣题目链接:https://leetcode.cn/problems/maximum-earnings-from-taxi/ 你驾驶出租车行驶在一条有 n  个地点的路上。这 n  个地点从近到远编号为  1  到  n  ,你想要从 1  开到 n  ,通过接乘客订单盈利。你只能沿着编号递增的方向前进,不能改变方向。 乘客信息用一个下标从 0  开

    2024年02月04日
    浏览(36)
  • 仿滴滴打车百度地图定位查找附近出租车或门店信息

    随着技术的发展,开发的复杂度也越来越高,传统开发方式将一个系统做成了整块应用,经常出现的情况就是一个小小的改动或者一个小功能的增加可能会引起整体逻辑的修改,造成牵一发而动全身。通过组件化开发,可以有效实现单独开发,单独维护,而且他们之间可以随

    2024年02月09日
    浏览(47)
  • 【Cocos 3d】从零开始自制3d出租车小游戏

    本文很长,建议收藏食用。 课程来源: 游戏开发教程 | 零基础也可以用18堂课自制一款3D小游戏 | Cocos Creator 3D 中文教程(合集)p1~p6 简介: 资源下载:https://github.com/cocos-creator/tutorial-taxi-game 适合学习人群:本教程假定你对编程有一定的了解,ts,js 学习过其中之一。 如果不

    2024年02月02日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包