FPGA自动洗衣机的设计与验证(Verilog编写)

这篇具有很好参考价值的文章主要介绍了FPGA自动洗衣机的设计与验证(Verilog编写)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目的及要求

        1.洗衣机的工作步骤为洗衣、漂洗和脱水三个过程,工作时间分别为:洗 衣45秒,漂洗30 秒,脱水15 秒;

        2.用一个按键实现洗衣程序的手动选择:A、单洗涤;B、单漂洗;C、单脱水;D、漂洗和脱水;E、洗涤、漂洗和脱水全过程;

        3. 用3个LED灯分别表示当前工作状态,并且以1HZ频率闪烁(洗衣、漂洗和脱水),数码管倒计时显示每个步骤剩余的工作时间,这里采用数码管动态显示。全部过程结束后,应提示使用者;

        4. 用一个按键实现暂停洗衣和继续洗衣的控制,暂停后继续洗衣应回到暂停之前保留的状态;

        5.洗涤和漂洗过程中电机正运转方式为:正转5s ->暂停2s ->反转5s,若洗涤时间没到则重复以上过程,脱水则一直正转。

设计规范:功能、性能要求、端口信号说明;

类型

名称

位宽

描述

input

Clk

1

时钟信号125MHZ

input

Rst

1

复位

input

Mode

1

模式选择

input

Sta_Pause

1

启动/暂停

output

Beep

1

洗衣完成

output

Led_wash

1

洗涤状态灯

output

Led_rinse

1

漂洗状态灯

output

Led_dry

1

脱水状态灯

output

Seg_sel

4

位选信号

output

Seg_led

7

七段管段选信号

output

Roll_pos

1

电机正转

output

Roll_neg

1

电机反转

设计程序代码:

`define CLK_NUM 125_000_000    //输入的时钟频率
//
// Company: 
// Engineer: 
// 
// Create Date: 2023/11/24 09:50:24
// Design Name: 
// Module Name: washing_machine
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//


module washing_machine(
input           Clk,
input           Rst,Mode,Sta_Pause,
output  wire     Led_wash,
output  wire     Led_rinse,
output  wire     Led_dry,
output  reg      Beep,
output  wire     Roll_neg,
output  wire     Roll_pos,
output  [3:0]   seg_sel,
output  [6:0]   seg_led
);

parameter Mode0=5'b00000,ModeA=5'b00001,ModeB=5'b00010,ModeC=5'b00100,ModeD=5'b01000,ModeE=5'b10000;
parameter forward=2'b01,stop=2'b00,backward=2'b10;
parameter wash=3'b001,rinse=3'b010,dry=3'b100;
reg [4:0] next_state,present_state;
reg [2:0] work_state;
reg	[1:0] motor_state,motor_prestate;

reg [26:0]   hz_cnt;
reg	[2:0]	 cnt_motor;
reg          Clk_hz;
reg			 Mode_last;
reg			 do_not;
reg [5:0]    minute;				
reg [5:0]    sec;
reg [3:0]    status;//模式显示
reg [2:0]    cnt_beep;
wire          time_flag;
wire			Mode_d; //_d为去抖
wire			Sta_Pause_d;
wire    [3:0]   minute_ge;
wire    [3:0]   minute_shi;
wire    [3:0]   sec_ge;
wire    [3:0]   sec_shi;
wire 	[15:0]  data;

//状态转移逻辑,1/选择工作模式
always @(posedge Clk or negedge Rst) begin 
    if(!Rst)
        next_state<=ModeA; 
    else if(time_flag)
        next_state<=ModeA; 
    else begin
		Mode_last <= Mode_d;
        case(next_state)
            ModeA:  begin
                        if(Mode_last==0 && Mode_d==1) begin
                            next_state<=ModeB;
                            end
                        else next_state<=ModeA;
                    end
            ModeB:  begin
                        if(Mode_last==0 && Mode_d==1) begin
                            next_state<=ModeC;
                            end
                        else next_state<=ModeB;
                    end
            ModeC:  begin
                        if(Mode_last==0 && Mode_d==1) begin
                            next_state<=ModeD;
                            end
                        else next_state<=ModeC;
                    end
            ModeD:  begin
                        if(Mode_last==0 && Mode_d==1) begin
                            next_state<=ModeE;
                            end
                        else next_state<=ModeD;
                    end
            ModeE:  begin
                        if(Mode_last==0 && Mode_d==1) begin
                            next_state<=ModeA;
                            end
                        else next_state<=ModeE;
                    end
        endcase
        end
	end
//状态跳转,Mode0用于表示实际工作状态为空闲,2/按下开始
always@(posedge Clk or negedge Rst) begin
    if(!Rst)
        begin
		present_state<=Mode0;
		end
	else if(present_state==Mode0 && Sta_Pause_d==1) begin 
		present_state<= next_state;
		end
	else if(minute==6'd0 && sec==6'd0)
        begin
		present_state <= Mode0;
		end
end

//分、秒控制模块
always@(posedge Clk_hz or negedge Rst) begin
    if(!Rst)
        begin
        sec<=6'd0;
		minute<=6'd0;
        end
	else if(present_state==Mode0) begin 
		case(next_state)
			ModeA:	begin minute <= 6'd0; sec <= 6'd45; status <= 4'hA; end
			ModeB:	begin minute <= 6'd0; sec <= 6'd30; status <= 4'hB; end
			ModeC:	begin minute <= 6'd0; sec <= 6'd15; status <= 4'hC; end
			ModeD:	begin minute <= 6'd0; sec <= 6'd45; status <= 4'hD; end
			ModeE:	begin minute <= 6'd1; sec <= 6'd30; status <= 4'hE; end
		endcase
		end
	else if(!do_not)   begin //暂停工作
		sec<=sec;
		minute<=minute;
		status <= status;
		end
    else if(minute>=6'd1 && sec==6'd0)  begin
        sec<=6'd59;
		minute<=minute-1;
		status <= status;
		end
    else if(minute==6'd0 && sec==6'd0) //工作结束
        begin
        sec<=6'd0;
		minute<=6'd0;
		status <= 4'h0;
        end
    else	begin
        sec<=sec-1;
		minute<=minute;
		status <= status;
		end
end

assign time_flag = (minute==6'd0 && sec==6'd1) ? 1'b1:1'b0;//最后一秒准备报警

//3/选择工作状态
always @(posedge Clk or negedge Rst) begin 
    if(!Rst || present_state==Mode0)
        work_state<=3'b000;
	else if(present_state==ModeA) begin
			work_state <= wash;
			end
	else if(present_state==ModeB) begin
			work_state <= rinse;
			end
	else if(present_state==ModeC) begin
			work_state <= dry;
			end
	else if(present_state==ModeD) begin
			if(sec<=30) work_state <= dry;
			else work_state <= rinse;
			end
	else if(present_state==ModeE) begin
			if(minute==0 && sec<=15) work_state <= dry;			
			else if(minute==0 && sec<=45) work_state <= rinse;			
			else work_state <= wash;
			end
end
//电机状态,4/具体到电机转动方向
always @(posedge Clk_hz or negedge Rst) begin 
    if(!Rst || present_state==Mode0) begin 
        motor_state<=stop;
		motor_prestate <= backward;
		cnt_motor <= 0;
		end
	else if(!do_not) begin   //暂停键按下
	        motor_state <= stop;
			motor_prestate <= forward;
			cnt_motor <= 0;
			end
	else if(work_state==dry) begin 
			motor_state <= forward;
			end
	else if((sec>45 && sec<=47)||(minute==1 && sec>15 && sec<=17)) begin //状态转换前电机停止
		motor_state<=stop;
		motor_prestate <= backward;
		cnt_motor <= 0;
		end
	else begin 
		case(motor_state)
			forward:	begin //正转5s停
				if(cnt_motor==3'd4) begin
					motor_state <= stop;
					motor_prestate <= forward;	//标记停前转动方向
					cnt_motor <= 0;
					end
				else cnt_motor <= cnt_motor+1'd1;
			end 
			stop:		begin
				if(cnt_motor==3'd1 && motor_prestate == forward) begin
					motor_state <= backward;
					cnt_motor <= 0;
					end
				else if(cnt_motor==3'd1 && motor_prestate == backward) begin
					motor_state <= forward;
					cnt_motor <= 0;
					end
				else cnt_motor <= cnt_motor+1'd1;
			end 
			backward:	begin 
				if(cnt_motor==3'd4) begin
					motor_state <= stop;
					cnt_motor <= 0;
					motor_prestate <= backward;
					end
				else cnt_motor <= cnt_motor+1'd1;
			end 
		endcase
		end	
end


//暂停启动控制,6/暂停
always @(posedge Sta_Pause_d or negedge Rst) begin
    if(!Rst)
        do_not<=1'b0;
    else
        do_not<= ~do_not;
end

//分频,得到1hz的时钟
always @(posedge Clk or negedge Rst) begin
    if(!Rst) begin
        hz_cnt<=27'd0;
	  Clk_hz<=1'd0;
	end
    else if(hz_cnt==`CLK_NUM/2-1)
        begin
        hz_cnt<=27'd0;
        Clk_hz<=~Clk_hz;
        end
    else
        hz_cnt<=hz_cnt+1;
end

//蜂鸣器模块 cnt_beep在计数1-6内响
always @(posedge Clk_hz or negedge Rst) begin
    if(!Rst) begin 
		Beep<=0;
        cnt_beep<=0;
		end
	else if(time_flag) cnt_beep <= cnt_beep+1;
    else if(cnt_beep >= 3'd1 && cnt_beep <= 3'd6) begin
		cnt_beep <= cnt_beep+1;
        Beep<=1; 
		end
	else if(cnt_beep == 3'd7) begin
		cnt_beep <= 0;
        Beep<=0; 
		end
    else
        Beep<=0;
end

//led指示模块
assign Led_wash=(work_state==wash)? 1'b1 : 1'b0;
assign Led_rinse=(work_state==rinse)? 1'b1 : 1'b0;
assign Led_dry=(work_state==dry)? 1'b1 : 1'b0;
//电机转动
assign Roll_pos=(motor_state==forward)? 1'b1 : 1'b0;
assign Roll_neg=(motor_state==backward)? 1'b1 : 1'b0;


//数据输出
assign minute_ge=minute%10;
assign minute_shi=minute/10;
assign sec_ge=sec%10;
assign sec_shi=sec/10;
assign data={status,minute_ge,sec_shi,sec_ge};
//数码管的例化
seg_led seg_led_inst(
.Clk        (Clk),
.Rst      (Rst),
.data       (data),
.sel    (seg_sel),
.seg_led     (seg_led)
);
//按键去抖例化
debounce debounce_Sta(
.Clk        (Clk),
.Rst      (Rst),
.btn       (Sta_Pause),
.btn_deb    (Sta_Pause_d)
);
debounce debounce_Mode(
.Clk        (Clk),
.Rst      (Rst),
.btn       (Mode),
.btn_deb    (Mode_d)
);
endmodule



//数码管显示模块
module seg_led(
input 				Clk,Rst,
input	[15:0]		data,
output	reg [3:0]	sel,
output  reg [6:0]	seg_led
);
 
reg [15:0]	ms_cnt;
reg			ms_clk;
reg [3:0]	num_display;
reg [15:0]	num;
reg [1:0]	sel_num; //选择哪一位数码管被点亮
 
//给4位数码管赋值
always @(posedge Clk or negedge Rst) begin
	if(!Rst)
		num<=16'd0;
	else 
		begin		    
            num[15:12] <= data[15:12]; 	
            num[11:8]  <= data[11:8];
            num[ 7:4]  <= data[7:4];
            num[ 3:0]  <= data[3:0];
		end
end

always @(posedge Clk or negedge Rst) begin  //产生1ms脉冲
	if(!Rst)
		begin
			ms_cnt<=16'd0;
			ms_clk<=1'b0;
		end
	else if(ms_cnt==`CLK_NUM/2000-1)
		begin
			ms_cnt<=16'd0;
			ms_clk<=~ms_clk;
		end
	else
			ms_cnt<=ms_cnt+1;
end
//每毫秒选择管
always @(posedge ms_clk or negedge Rst) begin
	if(!Rst)
		sel_num<=0;
	else
		sel_num<=sel_num+1;
end
//选择管译码
always @(posedge Clk or negedge Rst) begin
	if(!Rst)
		sel<=4'b1111;
	else
		begin
			case(sel_num)
				3'd0:	begin
						sel<= 4'b1110;  //显示数码管最低位
						num_display<=num[3:0];
						end
				3'd1:	begin
						sel<= 4'b1101;  //显示数码管第1位
						num_display<=num[7:4];
						end
				3'd2:	begin
						sel<= 4'b1011;  //显示数码管第2位
						num_display<=num[11:8];
						end
				3'd3:	begin
						sel<= 4'b0111;  //显示数码管第3位
						num_display<=num[15:12];
						end
				default	sel<= 4'b1111;
			endcase
		end
end
//数字译码
always @(posedge Clk or negedge Rst) begin
	if(!Rst)
		seg_led<=7'b100_0000;
	else
		begin
			case(num_display)
			4'h0 :    seg_led <= 7'b100_0000;
            4'h1 :    seg_led <= 7'b111_1001;
            4'h2 :    seg_led <= 7'b010_0100;
            4'h3 :    seg_led <= 7'b011_0000;
            4'h4 :    seg_led <= 7'b001_1001;
            4'h5 :    seg_led <= 7'b001_0010;
            4'h6 :    seg_led <= 7'b000_0010;
            4'h7 :    seg_led <= 7'b111_1000;
            4'h8 :    seg_led <= 7'b000_0000;
            4'h9 :    seg_led <= 7'b001_0000;
			4'hA: 	  seg_led <= 7'b000_1000;           //A
			4'hB :    seg_led <= 7'b000_0011;
            4'hC :    seg_led <= 7'b100_0110;
            4'hD :    seg_led <= 7'b010_0001;
            4'hE :    seg_led <= 7'b000_0110;
            4'hF :    seg_led <= 7'b000_1110;
            default : seg_led <= 7'b100_0000;
        endcase
		end
end
endmodule

//按键去抖模块
module debounce(input wire btn,Clk,Rst, //按键输入信号
                output reg btn_deb //去抖后的按键信号
);

parameter debounce_time = `CLK_NUM/500 ; //去抖时间
reg [22:0] counter ; //计数器

//状态机
parameter STATE_IDLE = 2'b00;
parameter STATE_PRE_DEBOUNCE = 2'b01;
parameter STATE_DEBOUNCE = 2'b10;
reg [1:0] state = STATE_IDLE;

always @(posedge Clk or negedge Rst) begin
    if(!Rst) begin
        counter <=0;
        state <= STATE_IDLE;
        btn_deb <= 1'b0;
    end
    else begin
  case (state)
    STATE_IDLE: begin
      if (btn == 1'b1) begin
        state <= STATE_PRE_DEBOUNCE;
        counter <= 23'd0;
      end else begin
        state <= STATE_IDLE;
        btn_deb <= 1'b0;
      end
    end
    STATE_PRE_DEBOUNCE: begin
      if (btn == 1'b1 && counter < debounce_time) begin
        counter <= counter + 1;
        state <= STATE_PRE_DEBOUNCE;
      end else if (btn == 1'b1 && counter >= debounce_time) begin
        counter <= 23'd0;
        state <= STATE_DEBOUNCE;
        btn_deb <= 1'b1;
      end else begin
        state <= STATE_IDLE;
        btn_deb <= 1'b0;
      end
    end
    STATE_DEBOUNCE: begin
      if (btn == 1'b1) begin
        state <= STATE_DEBOUNCE;
        btn_deb <= 1'b1;
      end else begin
        state <= STATE_IDLE;
        btn_deb <= 1'b0;
      end
    end
    default: begin
      state <= STATE_IDLE;
      btn_deb <= 1'b0;
    end
  endcase
  end
end
endmodule


 

testbench代码:

`timescale 1ms/10us
`define CLK_CYCLE 0.02

module tb_washing;

    reg         Clk         ;
    reg         Rst       ;
    reg         Mode       ;
	reg			Sta_Pause;
    wire        Led_wash       ;
    wire        Led_rinse;
	wire        Led_dry       ;
    wire        Beep;
	wire        Roll_neg       ;
    wire        Roll_pos;

	wire [3:0]	seg_sel			;
	wire [6:0]	seg_led		;
		
    washing_machine    u1(
    .   Clk       (Clk),
    .   Rst			(Rst),
    .   Mode   (Mode),
    .   Sta_Pause     (Sta_Pause),
	
	
	.	Led_wash	(Led_wash),
	.	Led_rinse	(Led_rinse),
    .   Led_dry   (Led_dry),
    .   Beep     (Beep),
    .   Roll_neg (Roll_neg),
	.   Roll_pos (Roll_pos),

	.	seg_sel		(seg_sel),
	.	seg_led		(seg_led)
);

    initial begin
     Clk = 1'b0;
     Rst = 1'b0;
     Mode = 1'b0;
	 Sta_Pause	=	1'b0;
     #300
     Rst = 1'b1;
     #100
     repeat (2) @(posedge Clk);
Mode = 1'b1;
     #400
	 Mode = 1'b0;
	
	 #400
	 Mode = 1'b1;
	#0.1
	 Mode = 1'b0;
	 #0.1
	 Mode = 1'b1;
	 #400
	 Mode = 1'b0;
	 #400
	 Mode = 1'b1;
	 #400
	 Mode = 1'b0;
	 #400
 	 Mode = 1'b1;
	 #400
	 Mode = 1'b0;
	 #400
	 Sta_Pause = 1'b1;
	#0.1
	 Sta_Pause = 1'b0;
	 #0.1
	 Sta_Pause	=	1'b1;
	#400
	 Sta_Pause	=	1'b0;
	@(posedge Led_rinse);
	Sta_Pause	=	1'b1;
	#400
	 Sta_Pause	=	1'b0;
	#4000
	Sta_Pause	=	1'b1;
	#400
	 Sta_Pause	=	1'b0;
     #100000
     $finish;
end

always #(`CLK_CYCLE / 2) Clk = ~Clk;


endmodule


仿真结果:

开始转动前:

FPGA自动洗衣机的设计与验证(Verilog编写),fpga开发

开始转动后:

FPGA自动洗衣机的设计与验证(Verilog编写),fpga开发

板级验证:

FPGA自动洗衣机的设计与验证(Verilog编写),fpga开发FPGA自动洗衣机的设计与验证(Verilog编写),fpga开发文章来源地址https://www.toymoban.com/news/detail-832091.html

到了这里,关于FPGA自动洗衣机的设计与验证(Verilog编写)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • STM32状态机编程实例——全自动洗衣机(上)

    前面几篇文章,以按键功能,介绍了状态机的原理与按键状态机实例,实现按键单击、双击、长按等状态的检测。 本篇,继续使用状态机编程,来实现一个更有趣的功能——全自动洗衣机。 下面是一个全自动洗衣机的控制面板: 面板上有4个按键: 电源:控制洗衣机通电与

    2024年02月09日
    浏览(36)
  • 基于单片机智能洗衣机设计与实现

      功能介绍 以51单片机作为主控系统; 利用STC89C52单片机进行数据处理;  通过2路继电器分别控制洗衣机进水、出水相关逻辑运算; 采用L298去掉直流电机实现滚筒正反转; 通过单片机进行处理数据,把采集到的数据通过LCD液晶显示; 按键设置模式,定时开启等条件; 三极

    2024年02月15日
    浏览(34)
  • STM32 Proteus仿真全自动洗衣机洗涤脱水-0074

    STM32 Proteus仿真全自动洗衣机洗涤脱水-0074 Proteus 仿真小实验: STM32 Proteus仿真全自动洗衣机洗涤脱水-0074 功能: 硬件组成:STM32F103R6单片机+LCD1602显示器 +L298N驱动电机正反转+蜂鸣器+LED指示灯+多个按键(标准洗,快速洗,单独脱水,水位符合,停止) 1.有3种洗衣模式:标准、

    2024年02月16日
    浏览(34)
  • 【工控老马】洗衣机PLC程序控制系统设计详解

    摘要 该创新设计主要介绍了全自动洗衣机的工作原理、控制系统的PLC的造型和资源的配置、控制系统程序设计与调试、控制系统PLC程序。根据全自动洗衣机的工作原理,利用可编程控制器PLC实现控制,说明了PLC控制的原理方法,特点及控制洗衣机的特色。通过本系统的设计,

    2024年02月06日
    浏览(59)
  • 【特纳斯电子】基于单片机的智能洗衣机系统设计-实物设计

    资料查找方式: 特纳斯电子(电子校园网):搜索下面编号即可 T6402203M-SW 本设计是基于单片机的智能洗衣机系统设计,主要实现以下功能: 1.大物件洗:主要在单个方向的转动,有更长的时间,一般用在窗帘等大件洗涤物的清洗 2.浸泡洗: 洗涤前,会漫泡一段时间。适合贴身

    2024年03月13日
    浏览(45)
  • 51单片机实现简单的洗衣机控制系统设计

    (1)设计一个洗衣机控制系统,用直流电机的转速表征三种不同洗衣方式:弱洗、强洗、漂洗; (2)用三个独立按键设置待洗衣物的不同洗涤方式,实现最长10分钟定时:     丝质衣服: 漂洗 定时3分钟 棉质衣服:弱洗 2分钟;强洗 5分钟;漂洗 3分钟; 化纤衣服: 强洗

    2023年04月19日
    浏览(43)
  • 【UML】-- 顺序图练习题含答案(自动售货机、学生选课、提款机、购买地铁票、洗衣机工作)

    根据下面的叙述,绘制一幅关于顾客从自动售货机中购买物品的顺序图。 顾客( User )先向自动售货机的前端( Front )投币; 售货机的识别器( Register )识别钱币; 售货机前端( Front )根据 Register 的识别结果产生商品列表; 顾客选择商品; 前端控制的出货器( Dispense

    2023年04月18日
    浏览(103)
  • python实现模糊洗衣机

    使用python设计并实现一个洗衣机模糊推理系统实验。 已知人的操作经验是: 污泥越多,油脂越多,洗涤时间越长 污泥适中,油脂适中,洗涤时间适中 污泥越少,油脂越少,洗涤时间越短 洗衣机的模糊控制规则如表1所示: 表1 洗衣机的模糊控制规则表 污泥油脂 NG(无油脂)

    2024年02月07日
    浏览(42)
  • 人工智能基础 | Python实现 洗衣机模糊推理系统

    Pycharm + Anaconda3 已知一组污泥和油脂两个参数的 模糊集合 ,以及对应的洗涤时间推理的结果。 现再给出一组污泥和油脂的模糊集合,进行 模糊推理 ,推出洗涤时间的 模糊集合 。 最后进行 模糊决策 ,选择洗涤时间的档次,采用 最大隶属度 和 加权平均法 两种方法 “污泥

    2023年04月08日
    浏览(48)
  • 【人工智能】实验二: 洗衣机模糊推理系统实验与基础知识

    理解模糊逻辑推理的原理及特点,熟练应用模糊推理。 设计洗衣机洗涤时间的模糊控制。 已知人的操作经验为: “污泥越多,油脂越多,洗涤时间越长”; “污泥适中,油脂适中,洗涤时间适中”; “污泥越少,油脂越少,洗涤时间越短”。 模糊控制规则如表1所示: x y z

    2024年02月03日
    浏览(64)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包