基于FPGA的四相步进电机驱动

四相步进电机

速度:时钟频率决定
转向:通电顺序决定
驱动:FPGA开发板的VCC一般是3.3或5V,可能需要外加一个电机驱动模块才能带动电机

    /*	time         :  2020_6_10
        engineer     :  松哥
        version      :  1.0
        change       :   NO
	    descriptipn  :  四相步进电机的驱动,二级转速,转向可调
	                     步进电机运行控制电路,A、B、C、D分别表示步进电机的四相绕组,
	                     步进电机按四相八拍方式运行。
	                     控制端T=1,电机的四相绕组的通电顺序为A-AB-B-BC—C-CD-D—DA
	                     控制端T=0,电机的四相绕组的通电顺序为A-AD-D-DC-C-CB-B-BA
	
    */	

    module stepmotor(
    
	    input  clk,rst,
        input  dir,					
        input  sw,					
        
		output [3:0] pwmout			
    );

    reg       stepmotor_clk;				//输出脉冲频率
    reg[3:0]  ctrl;				            //DCBA四相控制

    parameter 	
	            s0 = 8'b00_000_001,     //电机步进状态 A
                S1 = 8'b00_000_010,		//AB
			    S2 = 8'b00_000_100,		
			    S3 = 8'b00_001_000,		
			    S4 = 8'b00_010_000,		
			    S5 = 8'b00_100_000,
			    S6 = 8'b01_000_000,
			    S7 = 8'b10_000_000;
			
    reg [7:0] cur_state,next_state;	

    wire 	[24:0]		speed;
    reg		[24:0]		cnt;


    assign speed = sw ? 32'd12000:32'd24000;

    always @(posedge clk or negedge rst)
    	begin
    		if(!rst)
    			stepmotor_clk <= 1'b0;
    		else if(cnt < (speed>>1))			
    			stepmotor_clk <= 1'b0;
    		else 
    			stepmotor_clk <= 1'b1;				
    	end
          	
    always @(posedge clk or negedge rst)
    	begin
    		if(!rst)
    			cnt <= 1'b0;
    		else if(cnt == (speed-1'b1))
    			cnt <= 1'b0;
    		else 
    			cnt <= cnt + 1'b1;
    	end
    
    always@(posedge stepmotor_clk or negedge rst)        //第一段
    	if(!rst)
    		cur_state <= S1;
        else 
    	    cur_state <= next_state;
    
    always@(cur_state or rst or dir)        //第二段,状态转移,dir控制方向
    	if(!rst)
    		begin
    			next_state = S1;
    		end
    	else
    		begin
    			if(dir)                         //当控制端为1,正转
    				case(cur_state)
    					S1:next_state = S2;     //
    					S2:next_state = S3;
    					S3:next_state = S4;
    					S4:next_state = S5;
    					S5:next_state = S6;     //
    					S6:next_state = S7;
    					S7:next_state = S8;
    					S8:next_state = S1;
    				endcase
    			else                             //当控制端为0,反转
    				case(cur_state)
    					S1:next_state = S8;      //
    					S2:next_state = S1;
    					S3:next_state = S2;
    					S4:next_state = S3;
    					S5:next_state = S4;      
    					S6:next_state = S5;
    					S7:next_state = S6;
    					S8:next_state = S7;
    				endcase
    		end
    
    always@(posedge stepmotor_clk or negedge rst)			//第三段,当前状态输出
    	if(!rst)
    		begin
    			ctrl <= 4'b1000;
    		end
    	else
    		begin
    			case(next_state)
    				S1: ctrl <= 4'b1000;           //A
    				S2: ctrl <= 4'b1100;		   //AB
    				S3: ctrl <= 4'b0100;		   //B
    				S4: ctrl <= 4'b0110;		   //BC
    				S5: ctrl <= 4'b0010;           //C
    				S6: ctrl <= 4'b0011;		   //CD
    				S7: ctrl <= 4'b0001;		   //D
    				S8: ctrl <= 4'b1001;		   //DA
    				default: ctrl <= 4'b1000;
    			endcase
    		end
    assign  pwmout = ctrl;		             


    endmodule

猜你喜欢

转载自blog.csdn.net/jiyishizhe/article/details/106661632