本实验的任务是设计控制四相绕组的步进电机电机正转、反转、停止的控制电路。要求如下:
电机运转规律为:正转30s→停10s→反转30s→停10s→正转30s……
步进电机是将电脉冲信号转变为角位移或线位移的开环控制元步进电机件。当电流流过定子绕组时,定子绕组产生一矢量磁场。该磁场会带动转子旋转一角度,使得转子的一对磁场方向与定子的磁场方向一致。当定子的矢量磁场旋转一个角度。转子也随着该磁场转一个角度。每输入一个电脉冲,电动机转动一个角度前进一步。它输出的角位移与输入的脉冲数成正比、转速与脉冲频率成正比。改变绕组通电的顺序,电机就会反转。按照实验要求,我们可以将电机四相的时序图画出,用1代表高电平,用0代表低电平。则四相步进电机的工作状态可以分成四个:状态1:1001 ;状态2:1100;状态3:0110;状态4:0011 。正转:状态1~4,反转状态4~1。根据要求中的正转30s→停10s→反转30s→停10s→正转30s,我们可以将周期设为40s(其中高电平30s,低电平10s),占空比为3/4。
设计文件 stepmotor1.v
module stepmotor1 ( input wire clk,rst, output wire [5:0] led ); wire clk1h; //1秒时钟 reg [5:0] dir; //电机转动方向控制。正转000111,反转111000,停止000000 reg [5:0] timecont; //计时 parameter S1 = 2'b00, //电机工作状态 正转 S2 = 2'b01, //停止 S3 = 2'b10, //反转 S4 = 2'b11; //停止 parameter TIME_S1 = 6'd30, //正转计时30秒 TIME_S2 = 6'd10, //停止计时10秒 TIME_S3 = 6'd30; //反转计时30秒 reg [1:0] cur_state,next_state; divide #( //产生1秒时钟信号 .WIDTH(24), .N(12000000) ) u1 ( .clk(clk), .rst_n(rst), .clkout(clk1h) ); always@(posedge clk1h or negedge rst) //第一段 if(!rst) cur_state <= S1; else cur_state <= next_state; always@(cur_state or rst or timecont) //第二段,状态转移 if(!rst) begin next_state = S1; end else begin case(cur_state) //判断当前状态 S1:begin if(timecont == 1) //计时结束跳转到S2,否则保持S1 next_state = S2; else next_state = S1; end S2:begin if(timecont == 1) //计时结束跳转到S3,否则保持S2 next_state = S3; else next_state = S2; end S3:begin if(timecont == 1) //计时结束跳转到S4,否则保持S3 next_state = S4; else next_state = S3; end S4:begin if(timecont == 1) //计时结束跳转到S1,否则保持S4 next_state = S1; else next_state = S4; end default:next_state = next_state; endcase end always@(posedge clk1h or negedge rst) //第三段,当前状态输出 if(!rst) begin timecont <= TIME_S1; dir <= 6'b000111; end else begin case(next_state) S1:begin dir <= 6'b000111; //正转状态输出 if(timecont == 1) //计时控制 timecont <= TIME_S1; //计时结束赋新的值 else timecont <= timecont - 1;//计时减1 end S2:begin dir <= 6'b000000; if(timecont == 1) timecont <= TIME_S2; else timecont <= timecont - 1; end S3:begin dir <= 6'b111000; if(timecont == 1) timecont <= TIME_S3; else timecont <= timecont - 1; end S4:begin dir <= 6'b111000; if(timecont == 1) timecont <= TIME_S2; else timecont <= timecont - 1; end default:begin dir <= 6'b000111; timecont <= TIME_S1; end endcase end assign led = dir; //状态输出动作对应的led endmodule
开发板上的四个led会按照10011100011000111001的顺序正向循环30s后暂停10s,然后继续从暂停处开始按照10010011011011001001的顺序反向循环30s后暂停10s,再继续从暂停处开始正向循环,以此往复。在任一时刻,按下rst所连接的按键开关,将rst置0,则循环会回到初始1001状态开始正向循环。