首页 > 其他 > 详细

2018 - 数电项目设计 - 智能门

时间:2020-04-08 22:29:52      阅读:78      评论:0      收藏:0      [点我收藏+]

背景介绍

  • 软件环境: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

2018 - 数电项目设计 - 智能门

原文:https://www.cnblogs.com/rongyupan/p/12662680.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!