1、基于fpga的无刷直流电机控制软件篇之霍尔信号基于fpga的无刷直流电机控制软件篇之霍尔信号)霍尔信号根据在电机安装位置的不同,有2种不同的时序图,分别是60度和120度。这个要根据电机的厂家提供的资料。我这次选型的电机是60度。时序图如下:s1-s6分别对应6个状态,每一个状态的电气角度是60度。霍尔信号在这里不仅要用来换向。还要用测速,提高电机控制系统的测速反馈。先来说换向。s1-s6代表6个状态,每个状态对应6个开关管的开启和关闭。上图为6个状态对应霍尔信号逻辑电平和对应6个开关管的开关逻辑状态。软件部分这里很好处理,简单的状态机就可以实现了。但是,不要忘记我们的集成模块是dvr8312
2、,它的控制接口为pwm_a pwm_b,pwm_c rst_a,rst_b,rst_c,并不是对应6个开关管。这是dvr8312手册上给出的用常规6个开关管信号的逻辑图。我们就按手册的来。程序如下:timescale 1ns / 1psmodule PWM_ctrl(clk,rst_n, pwm_ah,pwm_bh,pwm_ch, rst_an,rst_bn,rst_cn, hall_a,hall_b,hall_c );input clk;input rst_n;input hall_a; /三相霍尔信号input hall_b;input hall_c;output pwm_ah; /a相输
3、出output pwm_bh; /b相输出output pwm_ch; /c相输出output rst_an; /rst_a输出output rst_bn; /rst_b输出output rst_cn; /rst_c输出/-/霍尔换相 分为6状态 每状态只有2相通电/ s1s2s3s4s5s6/hall_a 111000/hall_b 001110/hall_c 100011/pwm_ah 110000/pwm_al 000110/pwm_bh 001100/pwm_bl 100001/pwm_ch 000011/pwm_cl 011000/-reg 2:0 hall1;reg 2:0 hal
4、l2;reg pwm_ahr;reg pwm_bhr;reg pwm_chr;reg pwm_alr;reg pwm_blr;reg pwm_clr;/reg9:0 ctrl_reg;regpwm_reg;reg 9:0 cnt;parameter ctrl_reg = 200;always(posedgeclk or negedge rst_n)if(!rst_n)begin pwm_reg =1b0; cnt = 10b0; endelse begin if(cnt =ctrl_reg) pwm_reg = 1b1; else pwm_reg = 1b0; endalways (posed
5、ge clk or negedge rst_n)if(!rst_n) cnt = 10b0;else cnt = cnt + 1b1;always (posedge clk or negedge rst_n)if(!rst_n)begin hall1 = 3b0; hall2 = 3b0; endelse begin hall1 = hall_a,hall_b,hall_c; hall2 = hall1; end/-always (posedge clk or negedge rst_n)if(!rst_n)begin pwm_ahr = 1b0; pwm_bhr = 1b0; pwm_chr
6、 = 1b0; pwm_alr = 1b0; pwm_blr = 1b0; pwm_clr = 1b0; endelse begin case(hall2) 3b101:begin pwm_ahr = pwm_reg; pwm_bhr = 1b0; pwm_chr = 1b0; pwm_alr = 1b0; pwm_blr = pwm_reg; pwm_clr = 1b0; end 3b100:begin pwm_ahr = pwm_reg; pwm_bhr = 1b0; pwm_chr = 1b0; pwm_alr = 1b0; pwm_blr = 1b0; pwm_clr = pwm_re
7、g; end 3b110:begin pwm_ahr = 1b0; pwm_bhr = pwm_reg; pwm_chr = 1b0; pwm_alr = 1b0; pwm_blr = 1b0; pwm_clr = pwm_reg; end 3b010:begin pwm_ahr = 1b0; pwm_bhr = pwm_reg; pwm_chr = 1b0; pwm_alr = pwm_reg; pwm_blr = 1b0; pwm_clr = 1b0; end 3b011:begin pwm_ahr = 1b0; pwm_bhr = 1b0; pwm_chr = pwm_reg; pwm_
8、alr = pwm_reg; pwm_blr = 1b0; pwm_clr = 1b0; end 3b001:begin pwm_ahr = 1b0; pwm_bhr = 1b0; pwm_chr = pwm_reg; pwm_alr = 1b0; pwm_blr = pwm_reg; pwm_clr = 1b0; end default:; endcase endassign rst_an = pwm_ahr | pwm_alr;assign rst_bn = pwm_bhr | pwm_blr;assign rst_cn = pwm_chr | pwm_clr;assign pwm_ah
9、= pwm_ahr;assign pwm_bh = pwm_bhr;assign pwm_ch = pwm_chr;/-endmodule如果要换向的话,只需要改变状态切换顺序就可以。这里就不详细说了。简要说明,软件思路,计数器计数,pwm_reg为经过控制算法处理后的控制量,和计数器进行比较,如果小于输出高电平,大于输出低电平。仿真图如下:占空比为50%时。可以明显看到每个换向状态只有2个管开,而且分别对应一上一下。具体计数器的位数选择我会在以后的系统连接中作说明。没有整个系统的联系这个位数是无法确定的。位数也同样决定了时钟频率。作为电机控制的2个环路之一速度环。 这里采用霍尔信号进行测速。
10、再来看霍尔的时序图一次高电平对应180度的电气角度。如果对高电平进行计数,计数值就对应180度的电气角度。计数时间就是时钟周期与计数值的积,这就得到电气速度。相对应机械角度要查看电机的磁极对数,电气速度/磁极对数就是相应的机械速度。利用霍尔信号测速的方法有分两种。一种就是如我之前说的对高电平计数,还有一种就是固定一个时间内对霍尔信号的高电平计数。同样也可得到速度。这部分我参考了很多资料。最后选用一种对2相霍尔信号取与非,得到一个一个霍尔开关状态下的高电平,用计数器对这个高电平计数的方法。这部分具体效果如果只能等实际测定后才能下结论。程序如下:odule speed_get(clk,rst_n,
11、hall_a,hall_b,speed );input clk;input rst_n;input hall_a;input hall_b;/input hall_c;output 15:0 speed;reg hall_ar1,hall_ar2;reg hall_br1,hall_br2;/reg hall_cr1,hall_cr2;always (posedge clk or negedge rst_n)if(!rst_n)begin hall_ar1 = 1b0; hall_ar2 = 1b0; hall_br1 = 1b0; hall_br2 = 1b0; endelse begin
12、hall_ar1 = hall_a; hall_ar2 = hall_ar1; hall_br1 = hall_b; hall_br2 = hall_br1;endwire hall_speed = hall_ar2 &( hall_br2);reg hall_speed1;always (posedge clk or negedge rst_n)if(!rst_n)begin hall_speed1 = 1b0; endelse begin hall_speed1 = hall_speed; end wire hall_neg = hall_speed1 & hall_speed;wire
13、hall_pos = hall_speed1 & hall_speed;reg 15:0cnt_speed;reg 15:0speed_reg;reg 1:0 state;always (posedge clk or negedge rst_n)if(!rst_n) begin cnt_speed = 16b0; state = 2b00; endelse begin case(state) 2b00:begin if(hall_pos) state = 2b1; else state = 1b0; end 2b01:begin cnt_speed = cnt_speed + 1b1; if(hall_neg) state = 2b11; else state = 2b01; end 2b11:begin speed_reg = cnt_speed; cnt_speed = 16b0; state = 2b00; end default:state = 2b00; endcase endassign speed = speed_reg; endmodule对于这个高电平,我做了边沿检测处理,用这2个检测脉冲来启动和清零计数器。仿真图:
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1