基于FPGA的直流电机PWM调速系统设计与实现

  • 格式:doc
  • 大小:3.38 MB
  • 文档页数:19

FPGA课程设计题目:基于FPGA的直流电机PWM调速系统设计与实现班级:微电子学1202班:杜英学号:1206080201日期:2016年3月24日基于FPGA的直流电机PWM调速系统设计与实现1设计任务与要求1.1设计任务完成基于FPGA的直流电机PWM调速系统设计与实现,实现对直流电机的闭环调速,速度值采用LCD或数码管显示。

1.2设计要求1.2.1了解PWM控制方法及应用;掌握PWM直流电机调速控制原理;掌握直流电机调速及驱动控制原理;完成基于FPGA的直流电机PWM 调速系统设计。

采用PWM(脉冲宽度调制)技术,速度值采用LCD 或数码管显示。

1.2.2通过课程设计的实践,进一步了解和掌握硬件描述语言(VHDL 或Verilog)和TOP-DOWN的设计流程,提高对实际项目的分析和设计能力,体会FPGA项目开发的过程,熟悉实验报告的编写规。

2设计原理分析2.1直流电机结构如下图1.1所示图2.1 直流电机的构造将直流电源通过电刷接通线组线圈,使线组线圈导体(电枢导体)有电流通过,在电磁的作用下,线组线圈将会产生磁场,同时产生的磁场与主磁极的磁场产生电磁力,这个电磁力作用于转子,使转子以一定的速度开始旋转,电机就开始工作。

在电机的外部电路加入开关型的霍尔元件,同时在电子转子的转盘上加入一个使霍尔元件产生输出的带有磁场的磁钢片。

当直流电机旋转时转盘与磁钢片一起旋转,当磁钢片转到霍尔元件上方时,可以使霍尔元件的输出端高电平变为低电平。

当磁钢片离开霍尔元件上方后,霍尔元件输出端又恢复高电平。

如此,点击每旋转一周,会使霍尔元件的输出端产生一个低脉冲,可以通过检测单位时间霍尔元件输出端低脉冲的个数推算出直流电机的转速。

本次设计中,调节PWM占空比进而控制直流电机转速,在本次设计中,为了保护霍尔元件,故设定程序每6秒刷新一次数据,所以在数码管显示的数据乘以10就是在该占空比时的直流电机每分钟转速。

在这次的实验中数码管采用的8位共阴极数码管,通过锁存器输入数据使得数码管的8个段码数字显示,再通过选择输出数据对所需数码管进行选择。

2.2电路原理图图2.2 电路原理图3 设计方案上述原理图中包含PWM模块、测速模块、计数模块、电机模块、滤波模块。

电机的外部电路加入开关型的霍尔元件,同时在电子转子的转盘上加入一个使霍尔元件产生输出的带有磁场的磁钢片。

当直流电机旋转时转盘与磁钢片一起旋转,当磁钢片转到霍尔元件上方时,可以使霍尔元件的输出端高电平变为低电平。

当磁钢片离开霍尔元件上方后,霍尔元件输出端又恢复高电平。

如此,点击每旋转一周,会使霍尔元件的输出端产生一个低脉冲,可以通过检测单位时间霍尔元件输出端低脉冲的个数推算出直流电机的转速。

本次设计为六秒记一次数,乘十就是每分钟转速值。

再通过驱动模块显示数码管数据。

4设计步骤(1)首先确定整体设计方案,确定设计需要使用的软件;(2)设计电路模块,编写各模块程序代码并进行仿真编译;(3)完成整体电路图设计后,使用QuartusⅡ软件对整体电路进行仿真调试;(4)连接硬件,使用示波器观察产生的波形,对不足之处进行改进调试。

5调试结果说明连接好试验箱,把硬件与实验箱接通,将程序下载到实验箱中。

进行实验,示波器观察PWM脉冲波形(占空比),看实验结果与预期效果是否相同,若相同,则实验无误。

其波形如下:占空比为50%时占空比为90%时将程序下载到实验箱中后,其实际操作过程如下:K12为使能键,使K12=‘1’;输入时钟信号为1MHZ;(1)K4=1时,示波器和LED的显示如下:示波器显示的是霍尔元件单位时间计数的个数为31.011显示器是每六秒电机转的圈数为186转结论:31.011*6=186.066于186近似,所以结论符合要求。

(2)K4=1,k3=1时,示波器和LED的显示如下:结论:68.6338*6=411.8028于412近似,所以结论符合要求。

(3)K4=1,k3=1,K2=1时,示波器和LED的显示如下:结论:85.516*6=513.096于513近似,所以结论符合要求。

(4)K4=1,k3=1,K2=1,K1=1时,示波器和LED的显示如下:结论:90.0339*6=540.2034于541近似,所以结论符合要求。

通过以上的比较,发现示波器中的结果与数码管上数据大概一致,即实验结果基本达到要求。

6心得体会本次课程设计,用FPGA控制直流电机,完成直流电机PWM调速系统设计,实现对直流电机的闭环调速,速度值采用LCD或数码管显示。

是一次很好的学习和实践的机会。

通过课程设计,我明白了电机工作的原理,以及用FPGA控制电机的原理。

最重要的是,对如何设计一个系统有了更进一步的了解,积累了很多经验。

从下载测试的结果来看,设计的要求基本上都实现了。

但是仍存在不少问题。

每个模块生成基本电路后,把各个模块的进行连接,仿真结果是正确的。

但是当连接到试验箱后,电机正常转动,LED却无法显示。

检查电路和程序还有电路图,并发现什么问题。

无意中发现LED偶尔会出现数字,但也只是闪一下。

最后才发现是因为电机转动太快了,LED无法及时显示或者是一直在闪,人眼无法识别。

在程序中加入了滤波模块,才解决了问题。

在设计的过程中,开始照着EDA课本上的原理设计,后来才发现所设计的电路有很多地方都满足不了设计要求,使设计一度遭遇了很大困难。

通过与同学讨论请教,逐步改进了设计,终于使设计的电路和设计要求相吻合。

在这中间,通过不断提出问题,解决问题,我对这次设计的原理有了更深的了解,也给我分析问题,解决问题提供了很多好的方法,好的思路。

同时,我也发现了自己存在的很多不足。

发现自己在设计一个系统的时候不能够统筹兼顾,不能够从总体上把握设计的思路,也不能看清问题的核心与关键所在。

这些都需要在下面不断学习实践,理论毕竟只是理论,要多参加实践,这样才能提高自己的能力,积累经验。

附录一PWM模块程序Library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity PWM isport(clock:in std_logic;duty_cycle:in std_logic_vector(3 downto 0);pwm_en:in std_logic;pwm_out:out std_logic);end entity;architecture art of PWM issignal pwm_out_io:std_logic;signal count:std_logic_vector(3 downto 0); beginpwm_out<=pwm_out_io;process(clock)beginif rising_edge(clock) thenif pwm_en='1' thencount<=count+1;end if;end if;end process;process(clock)beginif rising_edge(clock) thenif pwm_en='1' and count<duty_cycle thenpwm_out_io<='1';elsepwm_out_io<='0';end if;end if;end process;end;测速模块程序library ieee ;use ieee.std_logic_1164.all ;use ieee.std_logic_arith.all ;use ieee.std_logic_unsigned.all ;entity cesu isport( clk : in std_logic; --时钟输入1Mhzena : out std_logic; --允许计数clr : out std_logic; --计数器清零信号产生load : out std_logic); --锁存、显示输出允许高有效end cesu;architecture behav of cesu issignal clkk :std_logic; --1HZ时钟信号signal count :integer range 0 to 7;--6秒计数signal clr1 :std_logic; --清零信号signal ena1 :std_logic; --允许计数信号signal load1 :std_logic; --允许计数信号--signal cq1,cq2,cq3,cq4 : INTEGER RANGE 0 TO 15;--计数数据beginprocess(clk)variable c:std_logic;variablet:integer range 0 to 500000;beginif clk'event and clk='1' thent:=cnt+1;ift=500000 thent:=0; c:=not c;end if;end if;clkk<=c;end process;process(clkk) --6秒计数beginif clkk'event and clkk='1' thencount<=count+1;if count<6 thenena1<='1';load1<='0';clr1<='0';elsif count=6 thenena1<='0';load1<='1';clr1<='0';elsif count=7 thenena1<='0';load1<='1';clr1<='1';end if;end if;ena<=ena1;load<=load1;clr<=clr1;end process;end behav;计数模块程序library ieee;use ieee.std_logic_1164.all;entityt10 isport (clk:in std_logic; --计数时钟信号clr:in std_logic; --清零信号ena:in std_logic; --计数使能信号cq :out integer range 0 to 15; --4位计数结果输出carry_out:out std_logic); --计数进位end t10;architecture behav oft10 issignal cq1:integer range 0 to 15;beginprocess(clk,ena)beginif clr= '1' then cq1<= 0; ----计数器异步清零elsif clk'event and clk= '1' thenif ena= '1' thenif cq1=10 then cq1<=1;else cq1<=cq1+1;end if; ----等于9,则计数器清零end if;end if;end process;process (cq1)beginif cq1=10 then carry_out<= '1'; ----进位输出else carry_out<= '0';end if;end process;cq<=cq1;end behav;驱动模块程序library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity qudong_8 isport(clk:in std_logic; --动态显示刷新速度时钟QQ1,QQ2,QQ3:in std_logic_vector(3 downto 0); --32位BCD码输入,最0~3低位,28~31最高位qudong1:out std_logic_vector(7 downto 0); --驱动信号输出,0~7分别为abcdefgpcontrl:buffer std_logic_vector(2 downto 0)); --数码管位选输出,000最低位数码管有效,111最高位数码管有效end qudong_8;architecture behavior of qudong_8 issignal disp:std_logic_vector(3 downto 0);signal temp:std_logic_vector(2 downto 0);beginprocess(clk)beginif clk'event and clk='1' thentemp<=temp+1;end if;contrl<=temp;end process;process(contrl) --位选信号产生进程begincase contrl is--when"000"=>disp<=QQ7;--when"001"=>disp<=QQ6;--when"010"=>disp<=QQ5;--when"011"=>disp<=QQ4;when"100"=>disp<=QQ3;when"101"=>disp<=QQ2;when"110"=>disp<=QQ1;--when"111"=>disp<="0000";when others=>disp<="0000";end case;end process;process(disp) --译码进程begincase disp iswhen"0000"=>qudong1<="00111111";when"0001"=>qudong1<="00000110";when"0010"=>qudong1<="01011011";when"0011"=>qudong1<="01001111";when"0100"=>qudong1<="01100110";when"0101"=>qudong1<="01101101";when"0110"=>qudong1<="01111101";when"0111"=>qudong1<="00000111";when"1000"=>qudong1<="01111111";when"1001"=>qudong1<="01101111";when others=>qudong1<="00000110";end case;end process;end behavior;消抖模块程序library ieee;use ieee.std_logic_1164.all;entity xiaodou isport(clk,input: in std_logic;output: out std_logic);end xiaodou;architecture behav of xiaodou issignal cp:std_logic;signal count:integer range 0 to 3;beginprocess(clk)beginif(clk'event and clk='1') then --检测上升沿if(input='1')then --如果有输入信号if(count=3)then count<=count; --当计数达到3时,保持计数值不变else count<=count+1; --当其小于3时,进行加1处理end if;if(count=2)then cp<='1'; --如果计数达到2,cp置1else cp<='0'; -- 其余情况全部为0end if;else count<=0; --如果计数出现非法状况,进行清零复位end if;end if;output<=cp; --信号输出end process;end behav;。