基於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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章