• 2018


    背景介绍

    • 软件环境:Vivado
    • 硬件:舵机,红外模块
    • 项目周期:4周

    最终代码

    Marstdoor.v

    /* Name: Marstdoor.v
    Function: 
    系统顶层文件。通过调用之后的div,motor,Maintenance模块,得到电机工作频率,实现工作模式和维护模式的切换。
    Input: clk – 板载100MHz时钟信号;
            rst – 复位信号, ‘reset’;
            SensorSignal1 – 门内红外感应模块信号;
            SensorSignal2 – 门外红外感应模块信号;
            Switch – 工作模式与维护模式的切换命令信号;
            MaintainDirect – 维护模式下,电机转向命令信号;
    Output:SensorState1 – 门外红外感应模块信号通过LED灯显示是否感应到物体;
            SensorState2 – 门内红外感应模块信号通过LED灯显示是否感应到物体;
            Seg_Enable – 数码管位选使能信号;
            Seg_code – 数码管段选使能信号;
            OUT – 电机转动信号;
    */
     
    module marstdoor(
                input clk,
                input rst,          
                input SensorSignal1,
                input SensorSignal2,
                input Switch,
                input MaintainDirect,
                output reg SensorState1,
                output reg SensorState2,
                output[7:0]seg_code,
        	    output seg_Enable,
                output reg [3:0] OUT
                );
     
    always@(posedge clk)
           begin
           SensorState1 <= SensorSignal1;
           SensorState2 <= SensorSignal2;
           End
     
    wire clkDIV;
    div div(
               .clk_in(clk),
               .reset_low(rst),
               .clk_out(clkDIV)
               );
     
    wire [3:0]OUT1; //工作状态下的电机输出信号;
    wire [3:0]OUT2; //维护状态下的电机输出信号;
     
    motor motor(                           //工作模式
          .clk(clkDIV),
          .rst(rst),
          .StepEnable(Switch),
          .out(OUT1),
          .flag1(SensorState1),
          .flag2(SensorState2)
          );
     
    Maintenance maintenance(                   //维护模式
          .clk(clkDIV),
          .direct(MaintainDirect),
          .stepenable(Switch),
          .an(seg_Enable),
          .seg_code(seg_code),
          .out(OUT2)
          );
     
     always@(posedge clk)
     if(Switch==0)
       OUT<=OUT1;
     else if(Switch==1)
       OUT<=OUT2;
    endmodule
    

    Maintenance.v

    /*
    Name: Maintenance.v
    Function: 维护模式;通过控制板载SW信号开关,对电机的转动进行5s检测,并将计时信号实时显示在数码管上;
    Input: clk – 分频后的250Hz时钟信号;
            direct – 维护模式下,控制电机转向的的SW信号;
            stepenble – 正常工作模式和维护模式的转换信号;
    Output: an – 数码管的位选使能信号;
            seg_code – 数码管的段选使能信号,共8 bits;
            out – 维护模式下电机的转动状态输出;
    */
     
     
    module Maintenance(
      input clk,
      input direct,
      input stepenable,
      output reg an,
      output reg[7:0]seg_code,
      output reg[3:0]out
      );
      parameter T= 27'd250;           //计时1s;这是因为我们输入的时钟信号是分频之后的250Hz;
      parameter _0 = 8'hc0,_1 = 8'hf9,_2 = 8'ha4,_3 = 8'hb0,
                  _4 = 8'h99,_5 = 8'h92;
      reg[31:0]cnt;   //范围:0<cnt<250;过250则记1s;
      reg[4:0]cnt_num;	//这是数码管显示的数字;
      reg[31:0]counter;	//这是电机要用的计数变量;电机要转过一定的角度;
      reg[3:0]state;
    
    //接下来的部分是将电机模块的计数和数码管的计数联系在了一起; 
      always@(posedge clk)
        if(!stepenable)	//Switch信号此时为0; 即,处于工作状态,而非维护模块
         begin
           cnt<=0;
           cnt_num<=0;
           an<=0;      //未进入维护模式,数码管不使能
           counter<=0;
         end
        else if( stepenable )
          begin
               an<=1;
               if( direct == 1 )
               begin
              	counter<=counter+1;
           		cnt<=cnt+1;
            	if(counter<12500)	//12500/250=50;
           			state<=state-1;
          		if(cnt==T)
           		begin
           			cnt_num<=cnt_num+4'd1;
           			cnt<=0;
           		end
           		if(cnt_num>=5)
           		begin
           			counter<=12500;
           			cnt_num<=4'b0101;
           			cnt<=0;
           		end
           	end
           	else if(direct==0)
           	begin
           		counter<=counter-1;
           		if(counter>0)
           		begin
           			state<=state+1;
           		end
           		cnt<=cnt+1;
           		if(cnt==T)
            	begin
            		cnt_num<=cnt_num-4'd1;
            		cnt<=0;
            	end
            	if(cnt_num<=0)
            	begin
            		counter<=0;
            		cnt_num<=4'b0;
            		cnt<=0;
            	end
           	end
            case( cnt_num )
                4'd0:seg_code <= ~_0;
                4'd1:seg_code <= ~_1;
                4'd2:seg_code <= ~_2;
                4'd3:seg_code <= ~_3;
                4'd4:seg_code <= ~_4;
                4'd5:seg_code <= ~_5;
                default: seg_code <= 8'hff;
              endcase
     case (state)
                 3'b000 :    out <= 4'b0001 ;
                 3'b001 :    out <= 4'b0011 ;
                 3'b010 :    out <= 4'b0010 ;
                 3'b011 :    out <= 4'b0110 ;
                 3'b100 :    out <= 4'b0100 ;
                 3'b101 :    out <= 4'b1100 ;
                 3'b110 :    out <= 4'b1000 ;
                 3'b111 :    out <= 4'b1001 ;
              endcase            
            end            
    endmodule
    

    moter.v

    /*
    Name: motor.v
    Function: 系统的正常工作模式。在两个红外传感器的信号作用下,控制电机的转动状态;
    Input:  clk –- 分频后得到的250Hz时钟信号;
            rst –- 板载复位信号;
            flag1 –- 红外传感器1(门外)信号;
            flag2 –- 红外传感器2(门内)信号;
            StepEnable – 电机使能信号,控制电机进入工作状态;
    Output:out – 控制电机转速和转向的信号;
    */
     
    module motor(
                out,
        clk,
        flag1,
        flag2,
        StepEnable,
        rst);
     
    input clk;
    input flag1;
    input flag2;
    input StepEnable;
    input rst;
    output[3:0] out;
     
    reg[3:0] out;
    reg[2:0] state;
    reg[31:0] counter;
    reg[31:0] counter_num;
    reg enable;
     
    always @(posedge clk or negedge rst)
    begin
        if (!rst)   
        begin
            out <= 4'b0;
            state <= 3'b0;
            counter<=32'b0;
            counter_num<=32'b0;
            enable<=0;
        end
        else
        begin
            if (StepEnable == 1'b0)
            begin
                if(enable==0)
                begin
     		if( ( ( flag1 == 0 && flag2 == 0 ) || ( flag1 == 1 && flag2 == 0 ) || ( flag1 == 0 && flag2 == 1 ) ) && counter < 2500 )
        		begin
           			counter=counter+1;
           			state <= state - 3'b001 ;
        		end
    else
        	begin 
    if(flag1==1&&flag2==1)
            	begin
               		if(counter>2500)
                  		counter<=2500;
                   		enable<=1;
            	end
         	end
     end
    else if(enable==1)
        begin
           if(counter_num < 1250)
                	counter_num <= counter_num+1;                         
    if( flag1 == 1 && flag2 == 1 && counter > 0 && counter_num == 1250 )
    begin
            	counter=counter-1;
               	state <= state + 3'b001 ;
          end
    else if((flag1==0&&flag2==0)||(flag1==1&&flag2==0)||(flag1==0&&flag2==1))
    begin
           		if(counter<=0)
           			counter<=0;
           			enable<=0;
           			counter_num<=0;
         end
     end
        case (state)
        	3'b000 :    out <= 4'b0001 ;
        	3'b001 :    out <= 4'b0011 ;
        	3'b010 :    out <= 4'b0010 ;
        	3'b011 :    out <= 4'b0110 ;
        	3'b100 :    out <= 4'b0100 ;
        	3'b101 :    out <= 4'b1100 ;
        	3'b110 :    out <= 4'b1000 ;
        	3'b111 :    out <= 4'b1001 ;
        	endcase
    end
    end
    end
    endmodule
    

    div.v

    /*
    Name: div.v
    Function: 实现分频功能。这是因为电机的工作频率在250Hz,而板载晶振时钟为100MHz;
    Input: clk_in -- 板载晶振时钟(100MHz);
          Reset_low – 板载复位信号(’rst’);
    Output: clk_out – 分频后信号(250Hz);      
    */
     
    module div(
    clk_in, 
    clk_out, 
    reset_low);
      
    input clk_in,reset_low;
    output reg clk_out;
    reg [31:0] cnt;
     
      parameter CNT_NUM = 399999;         // M=100MHz/250Hz=400000, CNT_NUM=M-1;
      parameter CNT_HIGH = 199999;         //CNT_HIGH=M/2-1;   
     
      initial
      begin
        cnt = 0;
        clk_out = 0;
      end
     
      always @(posedge clk_in or negedge reset_low)
      begin
        cnt = cnt + 1;
        if(cnt <= CNT_HIGH)
          begin
            clk_out = 1;
          end
        else
          begin
            clk_out = 0;
            if(cnt == CNT_NUM)
              begin
                cnt = 0;
              end
          end
         
        if(!reset_low)
          begin
            clk_out = 0;
            cnt = 0;
          end
      end
    endmodule
    
  • 相关阅读:
    android 图片特效处理之模糊效果
    android 图片特效处理之怀旧效果
    android图像处理系列之六-- 给图片添加边框(下)-图片叠加
    android图像处理系列之五-- 给图片添加边框(中)
    android图像处理系列之四-- 给图片添加边框(上)
    android图像处理系列之三-- 图片色调饱和度、色相、亮度处理
    Android学习笔记进阶18 之画图并保存图片到本地
    Android学习笔记进阶19 之给图片加边框
    HDU3572_Task Schedule(网络流最大流)
    再淡spring jdbc 连接池断开重连设置
  • 原文地址:https://www.cnblogs.com/rongyupan/p/12662680.html
Copyright © 2020-2023  润新知