FPGA FPGA İle PWM RC Servo Motor By Ahmet Memeşil Posted on 19 Temmuz 2017 5 min read 0 0 3,725 Paylaş ! Facebook Paylaş ! Twitter Paylaş ! Google+ Paylaş ! Reddit Paylaş ! Pinterest Paylaş ! Linkedin Paylaş ! Tumblr 19Merhabalar; Bu projemizde FPGA üzerinden servo motor sürmek için PWM sinyali oluşturacağız. FPGA board üzerindeki GPIO pininden alınan PWM sinyalini SALEAE ( https://www.saleae.com/ )nın logic analyzer ı ile bilgisayar ekranında gerçek zamanlı olarak inceleyip oluşturulan ile tasarlanan sinyal arasındaki ilişkiyi inceleme fırsatımız olacak. Saleae Logic Analyzer 24 Mhz 8 Kanal Servo motor kontrolü için periyodu 20 ms olan Duty Cycle’ının ise 1 ile 2 ms arasında değişen 1.5 ms merkez pozisyonu olan PWM sinyali oluşturacağız. Board üzerinde 50 Mhz lik kristal olduğu için pwm’in periyodunu belirlemek için bir counter tanımlayacağız ve bu caounterın üst sınırı 20ms/20ns = 1000000 olarak tanımlanacak. Duty miktarını 1 ile 2 ms arasında değiştirmek istediğimiz için 1 ms için 50000, 2 ms için 100000 değerinde sabit belirleyeceğiz. Bu değerler PWM duty miktarının maksimum ve minimum değerleri olacak. Servo motorun bir tam turunun motor limitleri de dikkate alınarak istenilen sürede tamamlanması sağlanabilir. Programda 2 s lik bir tam devir süresi seçildiği için duty miktarı farkı dikkate alınarak 50000*20 ms/2 s = 500 değerindeki sabit ile motorun dönüş hızını belirleyeceğiz. Bunun için iki farklı butonla motoru sağa ve sola döndüreceğiz. VHDL KODU: library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity pwm is Port ( clk : in STD_LOGIC; reset : in STD_LOGIC; button_sag : in STD_LOGIC; button_sol : in STD_LOGIC; pwm : out STD_LOGIC); end pwm; architecture Behavioral of pwm is constant duty_hiz:integer:=500; constant period:integer:=1000000; constant dcycle_max:integer:=100000; —- maksimum duty genişliği constant dcycle_min:integer:=50000; —–minimum duty genişliği signal pwm_reg,pwm_next:std_logic; signal duty_cycle,duty_cycle_next:integer:=0; signal say,say_next:integer:=0; signal flag:std_logic; begin process(clk,reset) begin if reset = ‘1’ then pwm_reg<=’0′; say<=0; duty_cycle<=0; elsif clk=’1′ and clk’event then pwm_reg<=pwm_next; say<=say_next; duty_cycle<=duty_cycle_next; end if; end process; say_next<= 0 when say = period else say+1; flag<= ‘1’ when say= 0 else ‘0’; process(button_sağ,button_sol,flag,duty_cycle) begin duty_cycle_next<=duty_cycle; if flag=’1′ then if button_sag =’1′ and duty_cycle >dcycle_min then duty_cycle_next<=duty_cycle-duty_hiz; elsif button_sol =’1′ and duty_cycle < dcycle_max then duty_cycle_next<=duty_cycle+duty_hiz; end if; end if; end process; pwm<=pwm_reg; pwm_next<= ‘1’ when say < duty_cycle else ‘0’; end Behavioral; Program derlenip uygun pin planı yapıldıktan sonra pwm çıkışını inceleyelim. Tasarladığımız 20 ms lik periyodun logic analyzer da ki ölçümü Logic Analyzer ile yapılan ölçümlerde de görüldüğü gibi 20 ms lik PWM sinyalimizi oluşturduk. Atanan uygun butonlarla PWM genişliği tasarlanan limitler çerçevesinde değiştirilebilmiştir. Kaynakça: http://www.fpganedir.com/index.php