实验目的
- (1)熟悉和掌握FPGA开发流程和Lattice Diamond软件使用方法;
- (2)通过实验理解和掌握步进电机的原理和设计方法;
- (3)学习用Verilog HDL描述一个步进电机电路。
实验任务
本实验的任务是设计控制四相绕组的步进电机电机正转、反转、停止的控制电路。要求如下:
电机运转规律为:正转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。
Verilog HDL建模描述
设计文件 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
实验步骤
- 打开Lattice Diamond,建立工程。
- 新建Verilog HDL设计文件,并键入设计代码。
- 根据逻辑综合并分配管脚,在本实验中引脚分配如下:clk —C1,rst_n — L14,led0~led3—N13, M12, P12, M11
- 构建并输出编程文件,烧写至FPGA的Flash之中。
- 观察输出结果。
开发板上的四个led会按照10011100011000111001的顺序正向循环30s后暂停10s,然后继续从暂停处开始按照10010011011011001001的顺序反向循环30s后暂停10s,再继续从暂停处开始正向循环,以此往复。在任一时刻,按下rst所连接的按键开关,将rst置0,则循环会回到初始1001状态开始正向循环。