---------------------------------------------------------------------------------- -- Company: AK development GmbH -- Engineer: A.Kurka -- -- Create Date: 11.12.2023 -- modif : Version A20:11.07.2024 -- satzempfang 32bit -- Module Name: TopAS21A20 - Behavioral -- Project Name: AS21 Version A20 -- Target Devices: xc7k325t-3fbg676 -- Tool versions: ISE 14.7 ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; LIBRARY XilinxCoreLib; --use ieee.std_logic_signed.ALL; use IEEE.STD_LOGIC_ARITH.ALL; --USE ieee.math_real.all; --use IEEE.numeric_std.all; --library UNISIM; --use UNISIM.VComponents.all; ----------------------------------- -- synthesis translate_off LIBRARY XilinxCoreLib; -- synthesis translate_on entity TopAS21 is generic(adrbit : INTEGER:= 25; clkper :INTEGER:= 20); port( SYSCLK_P : in STD_LOGIC;-- Sysrtem clk 200 MHz SYSCLK_N : in STD_LOGIC; --CLKIN_P : in STD_LOGIC;-- REF clk 100 MHz, für SDRAM --CLKIN_N : in STD_LOGIC; nrst_in : in STD_LOGIC; -- reset input asynchron -- Interface zu 8051 Controller ncs_in : in STD_LOGIC; -- uP Controlsignale, ncs nrd_in : in STD_LOGIC;-- nrd nwr_in : in STD_LOGIC;-- nwr adr : in STD_LOGIC_VECTOR (7 downto 0):="00000000";-- AD[7..0] dbus : inout STD_LOGIC_VECTOR (7 downto 0):="ZZZZZZZZ"; -- Databus, DB[7..0] resCPU0 : out STD_LOGIC:='0';--P1.7, =1 request daten senden, =0, ruhe zustand resCPU1 : in STD_LOGIC;--P1.6 =1 Daten bereits geschickt, =0 Daten noch nicht geschickt --DONE : inout STD_LOGIC:='0';--DONE+ =FPGA geladen ---Interface zu CPU 16,Master DP RAM Signals---------------------------------- m_dbus : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0):=(OTHERS => 'Z');--MasterBus,mD[7..]0] m_adr_in : IN STD_LOGIC_VECTOR(3 DOWNTO 0);--FIFO Reg Adressen, mA[7..0] m_nrd_in : IN STD_LOGIC; -- Master rd, m_nrd m_nwr_in : IN STD_LOGIC; -- Master wr, m_nwr m_ncs_in : IN STD_LOGIC; -- Master cs, m_ncs m_IBF : OUT STD_LOGIC:='0'; -- Master Input Buffer full, m_IBF m_NOBF : OUT STD_LOGIC:='1'; -- Master Output Buffer full, m_NOBF ------------------------------------------ frq_in : in STD_LOGIC; --Interpolation Leitfrequenz,frq_in- strimp :IN std_logic:='0'; --- start befehl prgrun :IN std_logic:='0';-- 0:Rampe Aktiv, 1: Outut = ITP Pulse ------- Endlage Inputs ------------------------------------------ ZuEnd :IN STD_LOGIC_VECTOR(11 DOWNTO 0):= X"000";--A6EL,A6ER,....A1EL,A1ER ------- Enkoder Inputs ------------------------------------------- Encod :IN STD_LOGIC_VECTOR(17 DOWNTO 0):= "00" & X"0000"; --EncoderA6..A1(I,B,A) -------------------- stopin :IN STD_LOGIC:='0';-- stop itp und Rampe, STOP+ EndOut :OUT STD_LOGIC:='1';-- Endlage erreicht, END - intreq :OUT STD_LOGIC:='0';-- interpolation läuft =1 ramprun :OUT STD_LOGIC:='0';-- rampe läuft = 1 ------- SDI: Drehzahl Sollwere / Analog Inputs---------------------------- CLKDA :OUT std_logic:='0';-- clk für SPI D/A Drehzahl Ausgänge CLRDA :OUT std_logic:='1';-- clr für SPI D/A Drehzahl Ausgänge LDAC :OUT STD_LOGIC:='1';-- SDI LDAC für D/A CLK_AD :OUT std_logic:='0';-- clk für SPI A/D Eingänge --- DA12 :OUT std_logic:='0';-- data für D/A Ausgang A1,A2 SYN12 :OUT STD_LOGIC:='1';-- CS für SDI D/A Wandler Sollwer Achse 1,2 DA34 :OUT std_logic:='0';-- data für D/A Ausgang A3,A4 SYN34 :OUT STD_LOGIC:='1';-- CS für SDI D/A Wandler Sollwer Achse 3,4 DA56 :OUT std_logic:='0';-- data für D/A Ausgang A5,A6 SYN56 :OUT STD_LOGIC:='1';-- CS für SDI D/A Wandler Sollwer Achse 5,6 ---- CSAD :OUT std_logic:='1';-- CS für SPI A/D Eingänge DINAD :OUT STD_LOGIC:='0';-- Select DATA für A/D§ --- KIN :IN STD_LOGIC:='0';-- Input DATA von A/D KX,KY,KZ,K4 RIN :IN STD_LOGIC:='0';-- Reserve Input Digital: 0 ..5V -------PSRAM Interface---------------------------DDR2-SDRAM interface Signale- PCLK :OUT STD_LOGIC:='0';--PSRAM CLK adrDR :OUT std_logic_vector((adrbit -1) DOWNTO 0):=(OTHERS =>'0');--A[24..0] SDRAM noeDR :OUT STD_LOGIC:='1';--**PSRAM Output Enable(RD) CKN DDR2-SDRAM ncsDR :OUT STD_LOGIC:='1';--**PSRAM CS Enable CKP DDR2-SDRAM nweDR :OUT STD_LOGIC:='1';--**PSRAM Write Enable CKE DDR2-SDRAM nadvDR :OUT STD_LOGIC:='1';--**PSRAM nADV creDR :OUT STD_LOGIC:='0';--**PSRAM CRE DataDR :INOUT std_logic_vector(15 DOWNTO 0):= "ZZZZZZZZZZZZZZZZ"; -- D[15..0]SDRAM ------------------------------------------------------------------------ ebene :IN STD_LOGIC_VECTOR(3 DOWNTO 0):= "0000"; --P10--13(AchsenEbene0..2)vonCPU16.1 testout :OUT STD_LOGIC_VECTOR(15 DOWNTO 0):= X"0000" --Test ausgänge ); end TopAS21;-- end topas21 entity --====================================================== architecture Behavioral of TopAS21 is ------------------------------------------------ COMPONENT ITPModul IS port (nrst : in std_logic; clk : in std_logic; XS :in std_logic_vector(31 downto 0);-- Startpunkt Koordinate X YS :in std_logic_vector(31 downto 0);-- Startpunkt Koordinate Y ZS :in std_logic_vector(31 downto 0);-- Startpunkt Koordinate Z XT :in std_logic_vector(31 downto 0);-- Koordinate X relativ (XE-XS) YT :in std_logic_vector(31 downto 0);-- Koordinate Y relativ (YE-YS) ZT :in std_logic_vector(31 downto 0);-- Koordinate Z relativ (ZE-ZS) pfrq :in std_logic_vector(23 downto 0);--Bahn-Periode in anzahl CLK L1 :in std_logic_vector(15 downto 0);-- länge Arm1 in mm L2 :in std_logic_vector(15 downto 0);-- länge Arm2 in mm L3 :in std_logic_vector(15 downto 0);-- länge Arm3 in mm --------------------- Xlin :in std_logic_vector(15 downto 0);-- Koord LinStz Ylin :in std_logic_vector(15 downto 0); ebene :in std_logic_vector(3 downto 0); Xactiv :in std_logic; Yactiv :in std_logic; celin :in std_logic; ----------------------------------- stopp :in std_logic;-- stop interpolation, nach Endlage RampRun :in std_logic;-- rampe aktiv =1 strimp :in std_logic;-- start interpolation ce :in std_logic;-- start interpolation von kreis oder XYZ Satz : InversTransf ----------------------------- calcok :out std_logic:= '0';-- signalisiert alle berechnungen sind fertig XAout :out std_logic_vector(31 downto 0):=X"00000000";--virtuelle aktuelle koordinate YAout :out std_logic_vector(31 downto 0):=X"00000000"; ZAout :out std_logic_vector(31 downto 0):=X"00000000"; ITPmod :out std_logic_vector(2 DOWNTO 0):="000";--ITP für Status Meldung an CPU oAXdif :out std_logic_vector(95 downto 0):= (OTHERS => '0');--Sollwertdif von inv.Transfer/linStz oImpLk :out std_logic:='1';--impulse von xyz itp enditp :out std_logic:='0';-- ende von Kontur:=0 (enditp-) itprun :out std_logic:='0';---- =1:interpolator läuft,aktuelle Sollwerte in AXIS(5..0) testdata :out std_logic_vector(15 downto 0):= X"0000" ); end COMPONENT;--itp modul ----------------------------------------------------------------- COMPONENT RAMP is generic(adrbit : INTEGER:=25; clkper :INTEGER:=20); port ( clk : in std_logic:='0'; --gesamt clk, 200Mhz, output vom DCM nrst : in std_logic:='0';-- reset enditp : in std_logic:='0';--enditp-:Interpolator läuft kontur itprun : in std_logic:='0';--itprun+ :Interpolator läuft prgrun :in std_logic:='0';--aktivelow=rampe aktiv,sonst outpulse=itppulse ------------Steilheit----------------------------- Steilheit :in std_logic_vector(15 downto 0):=(OTHERS => '0'); pfrq :in std_logic_vector(23 downto 0);--Bahn-Periode in anzahl CLK --------------------------------------------- calcok :IN STD_LOGIC;-- Berechnungen fertig start für daten einlesen XYimp :in STD_LOGIC;-- signalisiert das Impulse kommen strimp :in STD_LOGIC;-- Start für neue satz stopp :IN STD_LOGIC;-- stop Rampe AXdif :in std_logic_vector(95 downto 0):= (OTHERS => '0');--inkr input, 6 x 24 bit outdif :OUT std_logic_vector(95 DOWNTO 0):=(OTHERS => '0');--dif solloutput,6 x 16 bit -------- radrDR :OUT std_logic_vector((adrbit -1) DOWNTO 0):=(OTHERS => '0'); rncsDR :OUT std_logic:='1'; -- SRAM CS Enable rnweDR :OUT std_logic:='1'; -- SRAM Write Enable rnoeDR :OUT std_logic:='1'; -- SRAM Output Enable rnadvDR :OUT STD_LOGIC:='1';--**PSRAM nADV rcreDR :OUT STD_LOGIC:='0';--**PSRAM CRE rdataDR :INOUT std_logic_vector(15 DOWNTO 0):="ZZZZZZZZZZZZZZZZ";--SRAM Inp/Outp ----------- ordAX :OUT std_logic:='1';-- allle 6 Achsen eingelesen ormpzu :OUT std_logic_vector(1 DOWNTO 0):="00" ); END COMPONENT; ---------------------------------------------------------------- COMPONENT debounce is port ( SIG_IN : in std_logic; CLK : in std_logic; SIG_OUT : out std_logic); end COMPONENT; ------------------------------- COMPONENT synch is port ( SYN_IN : in std_logic; CLK : in std_logic; SYN_OUT : out std_logic); end COMPONENT; --------------------------------- COMPONENT fdnegneg IS PORT( clk : IN STD_LOGIC; nrst : IN STD_LOGIC; Inp : IN STD_LOGIC; Outp : OUT STD_LOGIC ); END COMPONENT; ----------------------------------------------- COMPONENT R_Diskr IS PORT( clk : IN STD_LOGIC; nrst : IN STD_LOGIC; sph1 : IN STD_LOGIC; sph0 : IN STD_LOGIC; dir : IN STD_LOGIC;--Richtung =0 default res1 : IN STD_LOGIC;--Auflösung 1 res0 : IN STD_LOGIC;--Auflösung 0 nimp : OUT STD_LOGIC; vorw : OUT STD_LOGIC ); END COMPONENT; ------------------------------------------------------------ COMPONENT refctrl IS PORT( clk :IN STD_LOGIC; nrst :IN STD_LOGIC; frqimp :IN STD_LOGIC; --frq Impulse (Leitfrequenz) stop :IN STD_LOGIC; RUNX :IN STD_LOGIC; --start RefX oder IndX RUNY :IN STD_LOGIC; --start RefY oder IndY ENDLX :IN STD_LOGIC; --EndlagemodusX; =0:inaktiv, =1 aktiv ENDLY :IN STD_LOGIC; --EndlagemodusY; =0:inaktiv, =1 aktiv RAX :IN STD_LOGIC; -- Bits aus ARTXY IDX :IN STD_LOGIC; RAY :IN STD_LOGIC; IDY :IN STD_LOGIC; RDIRX :IN STD_LOGIC; -- Bits aus REFDIR IDIRX :IN STD_LOGIC; RDIRY :IN STD_LOGIC; IDIRY :IN STD_LOGIC; DISTX :IN STD_LOGIC_VECTOR(1 DOWNTO 0); --Distanz in Anzahl Indx(1..4),für Endlage Modus DISTY :IN STD_LOGIC_VECTOR(1 DOWNTO 0); --Distanz in Anzahl Indx(1..4),für Endlage Modus PoserX :IN STD_LOGIC; -- Pos.Erreicht+ X PoserY :IN STD_LOGIC; -- Pos.Erreicht+ Y REstat :IN STD_LOGIC_VECTOR(7 DOWNTO 0);--Xref,Xind,Yind,Yref,YLend,YRend,XLend,XRend vrefX :IN STD_LOGIC_VECTOR(7 DOWNTO 0); --Vorschub Ref anfahren vrefY :IN STD_LOGIC_VECTOR(7 DOWNTO 0); vindX :IN STD_LOGIC_VECTOR(7 DOWNTO 0); --Vorschub Index anfahren vindY :IN STD_LOGIC_VECTOR(7 DOWNTO 0); nimpX :OUT STD_LOGIC; --Soll Impulse X vorX :OUT STD_LOGIC; -- Richtung X nimpY :OUT STD_LOGIC; --Soll Impulse Y vorY :OUT STD_LOGIC; -- Richtung Y clrIndX :OUT STD_LOGIC; -- clr IndexX Impuls Speicher in Rstat(6) clrIndY :OUT STD_LOGIC; -- clr IndexY Impuls Speicher in Rstat(5) RclrX :OUT STD_logic; -- clr SollX/IstX bei Refanfahren RclrY :OUT STD_logic; -- clr SollY/IstY bei Refanfahren rzuXY :OUT STD_LOGIC_VECTOR(7 DOWNTO 0) --refYrun,endY,inderY,referY,refXrun,endX,inderX,referX ); END COMPONENT; --------------------------------------------------- COMPONENT clk_gen is port (-- Clock in ports CLK_IN1_P : in std_logic; CLK_IN1_N : in std_logic; -- Clock out ports CLK_OUT1 : out std_logic; CLK_OUT2 : out std_logic; CLK_OUT3 : out std_logic; -- Status and control signals RESET : in std_logic; LOCKED : out std_logic ); end COMPONENT; -------------------------------------------------------- COMPONENT CrefGen is port (-- Clock in ports CLK_IN1_P : in std_logic; CLK_IN1_N : in std_logic; -- Clock out ports CLK_OUT1 : out std_logic; -- Status and control signals RESET : in std_logic ); END COMPONENT CrefGen; --============================================ ----------------------------------------- COMPONENT subFP IS port ( a: IN std_logic_VECTOR(31 downto 0); b: IN std_logic_VECTOR(31 downto 0); clk: IN std_logic; ce: IN std_logic; result: OUT std_logic_VECTOR(31 downto 0)); END COMPONENT; ------------------------------------------------ COMPONENT IntToFP IS port ( a: IN std_logic_VECTOR(31 downto 0); clk: IN std_logic; ce: IN std_logic; result: OUT std_logic_VECTOR(31 downto 0)); END COMPONENT; ------------------------------------------------------------ COMPONENT divFP IS port ( a: IN std_logic_VECTOR(31 downto 0); b: IN std_logic_VECTOR(31 downto 0); clk: IN std_logic; ce: IN std_logic; result: OUT std_logic_VECTOR(31 downto 0)); END COMPONENT; ------------------------------------------- COMPONENT CosFP is port( nrst : in std_logic; clk : in std_logic; cecos: in std_logic;-- startimpuls ArcCosFP ainp :in std_logic_vector(31 downto 0);-- input X= cos(x), FP format cos :OUT std_logic_vector(31 downto 0)-- output arccos(X), FP format ); END COMPONENT; ----------------------------------------------------- COMPONENT atanFP is port( nrst : in std_logic; clk : in std_logic; ceatan : in std_logic;-- startimpuls afkt Xinp :in std_logic_vector(31 downto 0);-- input X FP FP format Yinp :in std_logic_vector(31 downto 0);-- input Y FP FP format atanFP :OUT std_logic_vector(31 downto 0):=X"00000000"-- output Winkel(rad) in FP format ); END COMPONENT; ---------------------------------------------------- COMPONENT mulFP IS port ( a: IN std_logic_VECTOR(31 downto 0); b: IN std_logic_VECTOR(31 downto 0); clk: IN std_logic; ce: IN std_logic; result: OUT std_logic_VECTOR(31 downto 0)); END COMPONENT; --------------------------------------------------------------------- COMPONENT FPtoInt IS port ( a: IN std_logic_VECTOR(31 downto 0); clk: IN std_logic; ce: IN std_logic; result: OUT std_logic_VECTOR(24 downto 0)); END COMPONENT; --============Component für vorherige LRKREG Modul===================== --use LUT's, Create LPM,PortA=16 bit signed,PortB= 8 Bit,unsigned --Output 24 bit Registered,signed COMPONENT mulkorr IS port ( clk: IN std_logic; a: IN std_logic_VECTOR(15 downto 0); b: IN std_logic_VECTOR(7 downto 0); p: OUT std_logic_VECTOR(23 downto 0) ); END COMPONENT; --================================================== COMPONENT sqrt32 IS port ( x_in: IN std_logic_VECTOR(31 downto 0); nd: IN std_logic; x_out: OUT std_logic_VECTOR(16 downto 0); rdy: OUT std_logic; clk: IN std_logic); END COMPONENT; ------------------------------------------------------------- --use LUT's, Create LPM,PortA=16 bit usigned,PortB= 8 Bit,unsigned --Output 24 bit Registered,unsig, 3 clk COMPONENT mul1608 IS PORT ( clk : IN STD_LOGIC; a : IN STD_LOGIC_VECTOR(15 DOWNTO 0); b : IN STD_LOGIC_VECTOR(7 DOWNTO 0); ce : IN STD_LOGIC; p : OUT STD_LOGIC_VECTOR(23 DOWNTO 0) ); END COMPONENT; --===========Ende Component Deklaration=========================================== --================================================================== ATTRIBUTE DONT_TOUCH : string; ATTRIBUTE DONT_TOUCH of ITPModul: COMPONENT is "yes"; --================================================================= --- CONSTANT BCODEclk :INTEGER RANGE 0 TO 2047:= 720;-- =7 us ---VARIABLE AnzClk :INTEGER RANGE 0 TO 2047:= 0; -------Konstanten für Virtuelle Achsen XYZ, gemessen CONSTANT C_FSmax : INTEGER:=22250;--Fullscale:44.5N/+-22.25 N * 1000 ----- Uebersetzungen FSx to Fx ---------------------------------------------- --- Fx = FSx / Ux : Fx[N] = Kraft am Fräser, FSx[N] = kraft am Sensor ---- CONSTANT UXFP :std_logic_vector(31 DOWNTO 0):= X"40184189";-- UX = 69/ 29 = 2.379 CONSTANT UYFP :std_logic_vector(31 DOWNTO 0):= X"3ff74bc7";-- UY = 85/44 = 1.932 CONSTANT UZFP :std_logic_vector(31 DOWNTO 0):= X"3f800000";-- UZ = 61.5/ 61.5 = 1.00 ------- 1 Grd = 0.0174532925 rad -------------------- CONSTANT C_IG0 :INTEGER:=12391;-- Achse0 Auflösung in Inkr/rad 12.391 * 1000 CONSTANT C_IG1 :INTEGER:=11999;--Achse1 Auflösung in Inkr/rad 11.999 * 1000 CONSTANT C_IG2 :INTEGER:=05889;-- Achse2 Auflösung in Inkr/rad 5.8889 * 1000 CONSTANT C_IG3 :INTEGER:=06050;-- Achse3 Auflösung in Inkr/rad 6.050* 1000 CONSTANT C_IG4 :INTEGER:=000135;-- Achse4 Auflösung in Inrk/rad 0.1352 * 1000 --CONSTANT IG5 :INTEGER:=;-- Achse4 Auflösung in Inrk/rad ..... * 1000 --===================================================================================== ----------------------------------------------------------- CONSTANT PIdiv2 :std_logic_vector(31 DOWNTO 0):=X"3FC90FDB";-- +1.57079632679 PI/2 in FP Format --============================================================================= CONSTANT mult :INTEGER RANGE 0 TO 31 := 1;----********************************* CONSTANT ctrin : INTEGER := 210; --15 * 14 =210Länge ITP Pulse für Rampe :96 * 10nS =0.96UuS --- sampleclk = 1Mhz, 15 Abtast clk => m 257296 Inkr für 1 Arm Umdrehung ---------------------- --CONSTANT C_A0res :std_logic_vector(31 DOWNTO 0):=X"48799a00";--255592 inkr /U,709.977 --CONSTANT C_A1res :std_logic_vector(31 DOWNTO 0):=X"4871b2c0";--247499 inkr/U,687.497 --CONSTANT C_A2res :std_logic_vector(31 DOWNTO 0):=X"47ed3e80";--121469 inkr/U,337.414 --CONSTANT C_A3res :std_logic_vector(31 DOWNTO 0):=X"47f3c000";--124800 inkr/U,346.666 --CONSTANT C_A4res :std_logic_vector(31 DOWNTO 0):=X"45f22800";--7749 inkr/U,21.525 --CONSTANT C_A5res :std_logic_vector(31 DOWNTO 0):=X"478ba800";--71504 inkr/U,198.622 ----- ----CONSTANT C_A0rad :std_logic_vector(31 DOWNTO 0):=X"471ee6b3";--40678.70 inkr /rad ----CONSTANT C_A1rad :std_logic_vector(31 DOWNTO 0):=X"4719deae";--39390.68 inkr /rad ----CONSTANT C_A2rad :std_logic_vector(31 DOWNTO 0):=X"469708c8";--19332.39 inkr /rad ----CONSTANT C_A3rad :std_logic_vector(31 DOWNTO 0):=X"469b2d0f";--19862.53 inkr /rad ----CONSTANT C_A4rad :std_logic_vector(31 DOWNTO 0):=X"449a28f6";--1233.28 inkr /rad ----CONSTANT C_A5rad :std_logic_vector(31 DOWNTO 0):=X"4631d0d7";--11380.21 inkr /rad ------- --CONSTANT C_radA0 :std_logic_vector(31 DOWNTO 0):=X"37ce375b";--0.00002458289 rad/inkr --CONSTANT C_radA1 :std_logic_vector(31 DOWNTO 0):=X"37d4f591";--0.00002538672 rad/inkr --CONSTANT C_radA2 :std_logic_vector(31 DOWNTO 0):=X"3858f514";--0.00005172666 rad/inkr --CONSTANT C_radA3 :std_logic_vector(31 DOWNTO 0):=X"38532aa9";--0.00005034605 rad/inkr --CONSTANT C_radA4 :std_logic_vector(31 DOWNTO 0):=X"3a548ef2";--0.00081084587 rad/inkr --CONSTANT C_radA5 :std_logic_vector(31 DOWNTO 0):=X"38b847d6";--0.00008787184 rad/inkr ---------- CONSTANT C_A12res :std_logic_vector(31 DOWNTO 0):=X"3ae4c388";--FP=121469.162inkr/U CONSTANT C_AGres :std_logic_vector(31 DOWNTO 0):= X"3ae4c388";--FP=X"39a4b5be";--3c4ccccd ------------------------------------------------------------------- CONSTANT C_RES21 :std_logic_vector(7 downto 0):= X"11";-- Multipl. Dikr 1x CONSTANT C_RES43 :std_logic_vector(7 downto 0):= X"11"; CONSTANT C_RES65 :std_logic_vector(7 downto 0):= X"11"; ----------Anzahl warte clk für FP Funktionen------------------------------------- CONSTANT clkToFP : integer range 0 to 127 := 1; CONSTANT clkTosq : integer range 0 to 127 := 1; CONSTANT clkTomul : integer range 0 to 127 := 1; CONSTANT clkToadd : integer range 0 to 127 := 1; CONSTANT clkTosub : integer range 0 to 127 := 1; CONSTANT clkTosqrt : integer range 0 to 127 := 1; CONSTANT clkTodiv : integer range 0 to 127 := 1; CONSTANT clkFPtoInt : integer range 0 to 127 := 1; CONSTANT clkAtan : integer range 0 to 127 := 30;--30; CONSTANT clkAtan32 : integer range 0 to 127 := 30; CONSTANT clkdiv32 : integer range 0 to 127 := 32; CONSTANT clkTosin : integer range 0 to 127 := 2; CONSTANT clkTocos : integer range 0 to 127 := 36;----36; ---------------------------------------------------------------- --====================Signale von vorherigen LRK REG Moduls================= ------------------------------------------------------------------ CONSTANT clkmul :integer range 0 to 31 := 4;-- Berechnungszeit für mulX, MulY CONSTANT scansoll :integer range 0 to 65535:= 30000;-- abtastinterval für sollwert => speed,1mS CONSTANT scanspeed :integer range 0 to 262143:= 90000;--abtastinterval für speed = beschleunigung,3.3ms CONSTANT intrval :STD_LOGIC_VECTOR(15 DOWNTO 0):= X"FFF5";--Anzahl clk/langsamste ITPFreq -- für die Berechnung AbtastX,Y = effektive sollvorschub X,Y --Max. Periode von "frq" =65525 * Tclk =2.184 ms = 457.9 Hz => 1 Impuls alle 2.18ms -- für frq = 100 kHz = 10uS/Tclk => = 300 clk -------------------------------------------------------------------- --================== startposition bei Ref. Anfahren mit 00 für IST/SOLL- ----gemässs sketch Simulation, auflösung z.bsp A0 = 709.977 inkr/grd=========== CONSTANT C_A0 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"FFFFC3B4";--- -15436 CONSTANT C_A1 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"0000BA90";--- 47760 CONSTANT C_A2 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"FFFF97A6";--- -26714 CONSTANT C_A3 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"FFFFF2C7";--- -3385 CONSTANT C_A4 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"FFFFFF59";--- -167 CONSTANT C_A5 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000";--- 0 -------------------------------------------------------------- --================================================================================== TYPE T_m_data IS ARRAY(0 to 31) OF STD_LOGIC_VECTOR(31 DOWNTO 0);--Adress_Umsetz Tabelle für 32 bit Bus RD -------------------------------------------------------------------- TYPE T_BUFF IS ARRAY(0 to 3) OF STD_LOGIC_VECTOR(15 DOWNTO 0); TYPE T_BUFF1 IS ARRAY(0 to 7) OF STD_LOGIC_VECTOR(15 DOWNTO 0); TYPE T_BUFF2 IS ARRAY(0 to 4) OF STD_LOGIC_VECTOR(15 DOWNTO 0); ----------------------------------------------------------------- TYPE T_ZWSP IS ARRAY(0 TO 5) OF STD_LOGIC_VECTOR(23 DOWNTO 0); TYPE T_BUFF3 IS ARRAY(0 to 4) OF STD_LOGIC_VECTOR(31 DOWNTO 0); TYPE T_BUFF4 IS ARRAY(0 to 6) OF STD_LOGIC_VECTOR(31 DOWNTO 0); TYPE T_BUFF5 IS ARRAY(0 to 8) OF STD_LOGIC_VECTOR(31 DOWNTO 0); TYPE T_BUFF6 IS ARRAY(0 to 7) OF STD_LOGIC_VECTOR(26 DOWNTO 0);-- 27 bit ----------------------------------------------------- ATTRIBUTE FSM_ENCODING: string; -------------------------------------------------------------------------------------- TYPE STATE_TYPE IS (z0,z1,z2,z3,z4,z5,z6,z7,z8,z9,z10, Z11, Z12, Z13, Z14, Z15); SIGNAL stateX :STATE_TYPE; -- Berchnungszustand DA WertX ATTRIBUTE FSM_ENCODING OF stateX: SIGNAL IS "one-hot"; SIGNAL stateY :STATE_TYPE; -- Berchnungszustand DA WertX ATTRIBUTE FSM_ENCODING OF stateY: SIGNAL IS "one-hot"; --------------------------------------------------------------------------- -- Konfig Werte aus uP für Roboter für ITPModul TYPE T_KonfigTab is array(0 to 47) of Std_logic_vector(31 DOWNTO 0); -- konfig Werte für Achsen A1..A6 kompatibel mit Meldungen von CPU16.1 TYPE T_AxKonTab IS ARRAY(0 TO 71) OF STD_LOGIC_VECTOR(7 DOWNTO 0);-- total 3 x 24 Byte ----------type für Deformation berechnen------------------------------------------- TYPE T_FP IS ARRAY(0 to 5) OF STD_LOGIC_VECTOR(31 DOWNTO 0);--FP Berechnung Einzel Achse TYPE T_ADINP IS ARRAY(0 to 3) OF STD_LOGIC_VECTOR(11 DOWNTO 0);--Daten Kraftsensoren TYPE T_Dx IS ARRAY(0 TO 2) OF INTEGER;-- Kraftberechnung in der XYZ TYPE T_Ax IS ARRAY(0 to 2) OF STD_LOGIC_VECTOR(31 DOWNTO 0); -- auch fü FP ---------------- TYPE T_StrCtrlR IS ARRAY(0 TO 2) OF STD_LOGIC;--Start der ControlREF in Ebenen 0..3 TYPE T_STAT IS ARRAY(0 to 2) OF STD_LOGIC_VECTOR(7 DOWNTO 0); TYPE T_RefBef IS ARRAY(0 to 2) OF STD_LOGIC_VECTOR(7 DOWNTO 0); TYPE T_AnzInkr IS ARRAY(0 to 5) OF INTEGER;-- Anzahl Inkremente Endlage zu Endlage TYPE T_AxReg IS ARRAY(0 to 5) OF STD_LOGIC_VECTOR(31 DOWNTO 0);--Achsen Register Ist,Soll usw TYPE T_iAxReg IS ARRAY(0 to 5) OF INTEGER;--Kopie Achsen Register Ist,Soll usw als integer TYPE T_EbReg IS ARRAY(0 to 2) OF STD_LOGIC_VECTOR(31 DOWNTO 0);-- Ebenen Regoster (jeweils XY AchsReg) TYPE T_Ax16 IS ARRAY(0 to 5) OF STD_LOGIC_VECTOR(15 DOWNTO 0);-- Register für D/A Berechnungen TYPE T_Eb16 IS ARRAY(0 to 1) OF STD_LOGIC_VECTOR(15 DOWNTO 0);--2 X 16 bit reg für D/A TYPE DPSTATE IS (S0,S1,S2,S3); TYPE T_DAXY IS ARRAY(5 DOWNTO 0) OF STD_LOGIC_VECTOR(15 DOWNTO 0); TYPE T_IstBuff IS ARRAY(0 TO 23) OF STD_LOGIC_VECTOR(7 DOWNTO 0);--Istwert A0..A5(6 x 4Byte) ----------------------------------------- TYPE T_iPOSLIM IS ARRAY(0 TO 5) OF INTEGER RANGE 0 TO 255; TYPE T_iLIMIT IS ARRAY(0 TO 5) OF INTEGER; ------------------------------ TYPE T_NCSatz IS ARRAY(0 TO 15) OF STD_LOGIC_VECTOR(7 DOWNTO 0);-- NC Satz Speicher TYPE T_SatzBuff IS ARRAY(0 TO 15) OF STD_LOGIC_VECTOR(7 DOWNTO 0);-- Satz XYZ,NCSatz 1 Ebene TYPE T_MaxAx IS ARRAY(0 TO 3) OF STD_LOGIC_VECTOR(7 DOWNTO 0);-- MaxAx Speicher TYPE T_recstate IS (S0,S1,S100, S11,S12,S2,S3,S30, S300,S301,S302,S303,S304,S305,S306,S307,S308,S309, S31, S310,S311,S312,S313, S32,S320,S321,S322, S33,S34,S340,S35,S36,S37,S38, S39,s391,s392,s393,s394, S4,S41,S42,S43,s44,s45,s46,s47,s48, S5,S52,S51,S53,S54,S55,s56,s57, s550,S5501,S5502,S5503,S5504, S560, S520,S5200,S5201,S5202,S5203,S5204,S5205,S5206,S5207,S5208,S5209, S521,S5210,S5211,S5212,S5213, S522,S5220,S5221,S5222,S5223, S523,S5230,S5231,S5232,S5233, S524,S5240,S5241,S5242,S5243, S525,S5250,S5251,S5252,S5253, S526,S5260,S5261,S5262,S5263,S5264,S5265,S5266,S5267,S5268, S527,S5270,S5271,S5272,S5273,S5274,S5275,S5276,S5277, S7,S70,S71,S72,S73,S74,S75,S76,S77,S78,S79, S8,S81,S82,S83,S84, S9); --------------------------------------------------------------------- --ATTRIBUTE FSM_ENCODING: string; SIGNAL recstate :T_recstate; ATTRIBUTE FSM_ENCODING OF recstate:SIGNAL IS "one-hot"; --================================================================ SIGNAL m_data: T_m_data;-- adr umsetzen 32 bit zugriff --------------------- RECEIV -------------------------------------- SIGNAL AnzClk :INTEGER RANGE 0 TO 2047:= 0; SIGNAL BCODE :STD_LOGIC_VECTOR(7 DOWNTO 0):=X"00"; SIGNAL anzaxis :integer range 0 to 5 :=0; SIGNAL ZBETR :STD_LOGIC_VECTOR(7 DOWNTO 0):=X"08";--CNC Betriebswahl Schalter ref default SIGNAL CTRL :STD_LOGIC_VECTOR(7 DOWNTO 0):=X"00"; --RUN, FREI, EY, EX , CCW, ROT, DV, DU SIGNAL flsatz :STD_LOGIC := '0'; -- Koord satz empfangen (16 Byte) SIGNAL flkonf :STD_LOGIC := '0';-- Konfigsatz empfangen von CPU SIGNAL Iebene :STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";-- Interpolationsebene für LinSatz ---------------Receiv / Homing------------------------------------- SIGNAL invZuEnd :STD_LOGIC_VECTOR(11 DOWNTO 0):=X"000";-- nicht Synchronisierte Endlagen invertiert SIGNAL ZuEnds :STD_LOGIC_VECTOR(11 DOWNTO 0):=X"000";-- Synchronisierte invertierte Endlagen --TYPE T_RefBef IS ARRAY(0 to 2) OF STD_LOGIC_VECTOR(7 DOWNTO 0) --SIGNAL RefBefehl :T_RefBef;--3 Byte für Ebene 0,1,2 --TYPE T_AnzInkr IS ARRAY(0 to 5) OF INTEGER RANGE 0 TO 65535;-- Anzahl Inkremente Endlage zu fahren SIGNAL AnzInkr :T_AnzInkr;-- Signal RefImp0 :STD_LOGIC_VECTOR(1 DOWNTO 0):="10";--Achse 0 Imp & Dir Signal RefImp1 :STD_LOGIC_VECTOR(1 DOWNTO 0):="10";--Achse 1 Imp & Dir Signal RefImp2 :STD_LOGIC_VECTOR(1 DOWNTO 0):="10";--Achse 2 Imp & Dir Signal RefImp3 :STD_LOGIC_VECTOR(1 DOWNTO 0):="10";--Achse 3 Imp & Dir Signal RefImp4 :STD_LOGIC_VECTOR(1 DOWNTO 0):="10";--Achse 4 Imp & Dir Signal RefImp5 :STD_LOGIC_VECTOR(1 DOWNTO 0):="10";--Achse 5 Imp & Dir Signal REFEND0 :STD_LOGIC := '0';-- Ref A0 fertig = 1 Signal REFEND1 :STD_LOGIC := '0';-- Ref A1 fertig = 1 Signal REFEND2 :STD_LOGIC := '0';-- Ref A2 fertig = 1 Signal REFEND3 :STD_LOGIC := '0';-- Ref A3 fertig = 1 Signal REFEND4 :STD_LOGIC := '0';-- Ref A4 fertig = 1 Signal REFEND5 :STD_LOGIC := '0';-- Ref A5 fertig = 1 Signal REFRUN :STD_LOGIC := '0';-- Ref anfahren läuft Signal REFRUN0 :STD_LOGIC := '0';-- Ref0 (Achse0)anfahren starten Signal REFRUN1 :STD_LOGIC := '0';-- Ref1 (Achse1)anfahren starten Signal REFRUN2 :STD_LOGIC := '0';-- Ref2 (Achse2)anfahren starten Signal REFRUN3 :STD_LOGIC := '0';-- Ref3 (Achse3)anfahren starten Signal REFRUN4 :STD_LOGIC := '0';-- Ref4 (Achse4)anfahren starten Signal REFRUN5 :STD_LOGIC := '0';-- Ref5 (Achse5)anfahren starten --------------------- SIGNAL SetIstSoll0 :STD_LOGIC := '0'; -- wenn 1 werden IST & Soll auf C_A0...CA1 gesetzt SIGNAL SetIstSoll1 :STD_LOGIC := '0'; -- wenn 1 werden IST & Soll auf C_A2...CA3 gesetzt SIGNAL SetIstSoll2 :STD_LOGIC := '0'; -- wenn 1 werden IST & Soll auf C_A4...CA5 gesetzt SIGNAL SetIstSoll :STD_LOGIC := '0'; -- wenn 1 werden IST & Soll auf C_A0...CA5 gesetzt -------------------- SIGNAL IniPos :T_AxReg;-- (0 to 5) OF SLV(31 DOWNTO 0);--Init Winkel der Roboterarme SIGNAL SetIniPos0 :STD_LOGIC := '0';-- Iniposition setzen Achse 0 SIGNAL SetIniPos1 :STD_LOGIC := '0';-- Iniposition setzen Achse 0 SIGNAL SetIniPos2 :STD_LOGIC := '0';-- Iniposition setzen Achse 0 SIGNAL SetIniPos3 :STD_LOGIC := '0';-- Iniposition setzen Achse 0 SIGNAL SetIniPos4 :STD_LOGIC := '0';-- Iniposition setzen Achse 0 SIGNAL SetIniPos5 :STD_LOGIC := '0';-- Iniposition setzen Achse 0 SIGNAL SetIniPos :STD_LOGIC := '0';-- Iniposition setzen alle Achsen ----------------- SIGNAL REF00 :STD_LOGIC := '0';-- signal für REF Befehl 00 EBENE 0 SIGNAL REF01 :STD_LOGIC := '0';-- signal für REF Befehl 00 EBENE 1 SIGNAL REF02 :STD_LOGIC := '0';-- signal für REF Befehl 00 EBENE 2 ------------------- neue Signale für Ref anfahren------------------- SIGNAL RefBefehl :T_RefBef;--3 Byte für Ebene 0,1,2 SIGNAL StrtCntrR :T_StrCtrlR; --Start control Ref Ebene 0,1,2 SIGNAL StRcntr0 :INTEGER RANGE 0 TO 51:= 0;--State für REF Ausführung EBENE 0 SIGNAL StRcntr1 :INTEGER RANGE 0 TO 51:= 0;--State für REF Ausführung EBENE 1 SIGNAL StRcntr2 :INTEGER RANGE 0 TO 51:= 0;--State für REF Ausführung EBENE 2 --==================================================================== ------ Clock Generator ------------------------------ SIGNAL clk : STD_LOGIC:='0'; -- System Clk 100 MHz SIGNAL frq : STD_LOGIC:='0';-- interpolator frequenz SIGNAL rst : STD_LOGIC:='0';-- Reset Pos aktiv = NOT nrst SIGNAL nrst : STD_LOGIC:='1';-- Reset Pos aktiv = NOT nrst SIGNAL clkSDI :STD_LOGIC:='0'; -- clk für SDI, 50 MHz SIGNAL clk5 : STD_LOGIC:='0';-- 5 Mhz für Debounce SIGNAL clkAD : STD_LOGIC:='0';-- 25 Mhz CLK für SDI A/D Converter SIGNAL clkREC : STD_LOGIC:='0';-- 50 Mhz CLK für RECEIVER SIGNAL RESET_IN :STD_LOGIC:='0';-- für clkgenerator SIGNAL LOCKED_OUT :STD_LOGIC:='0'; ------------------------------------- SIGNAL updatSkor :STD_LOGIC:='0'; SIGNAL resetUpdat :STD_LOGIC:='0'; --================================================================ ----------- RECEIV SIGNALE ---------------------------------------- ----------- Master seite ----------------------------------- --SIGNAL m_dbus : STD_LOGIC_VECTOR;-- Master Bus in der Entity SIGNAL m_adr : STD_LOGIC_VECTOR(3 DOWNTO 0):="0000";--reg Adressen SIGNAL m_nrd : STD_LOGIC:='1'; -- Master rd, synchronisiert SIGNAL m_nwr : STD_LOGIC:='1'; -- Master wr, synchronisiert SIGNAL m_ncs : STD_LOGIC:='1'; -- Master cs, synchronisiert SIGNAL fm_nwr : STD_LOGIC:='1';-- flanke m_nwr SIGNAL fm_nrd : STD_LOGIC:='1';-- flanke m_nrd ----------------- Slave Seite ------------------- --================================================================ ---------------uC uControler Signale ------------------------- SIGNAL ncs :STD_LOGIC:= '1';--Konfig uController Signale SIGNAL nrd :STD_LOGIC:= '1'; SIGNAL nwr :STD_LOGIC:= '1'; SIGNAL Axdata : STD_LOGIC_VECTOR(7 DOWNTO 0):= X"00";--Zwischenspeicher SIGNAL Axadr : STD_LOGIC_VECTOR(7 DOWNTO 0):= X"00";-- für AXkonTAB SIGNAL Axwr :STD_LOGIC:= '0'; SIGNAL allTabOK :std_logic:='0'; --=1 tabellen von up wurden empfangen ---------------------------------------------- ---SIGNAL IstBuff :T_IstBuff;-- Speicher für Istwert (0..5 of StdLog(31..0) SIGNAL XYZSatz :T_SatzBuff;-- NC SAtz Speicher 0..14 byte SIGNAL NCSatz :T_NCSatz;-- Satz Speicher für eine Ebene 0..14 SIGNAL MaxAx :T_MaxAx;-- MaxAx Daten Speicher 0..3 Byte SIGNAL RBuff :T_NCsatz; --allg Buffer für alle andere Daten als Nc + Ref satz : SIGNAL sollstate :INTEGER RANGE 0 TO 5:= 0; SIGNAL sordAX :STD_LOGIC:= '1'; ---------------- SIGNAL XE :STD_LOGIC_VECTOR(31 DOWNTO 0):=(OTHERS => '0'); -- Endpunkt Koordinaten SIGNAL YE :STD_LOGIC_VECTOR(31 DOWNTO 0):=(OTHERS => '0'); SIGNAL ZE :STD_LOGIC_VECTOR(31 DOWNTO 0):=(OTHERS => '0'); ------------- SIGNAL XS :STD_LOGIC_VECTOR(31 DOWNTO 0):=(OTHERS => '0');-- Startpunkt Koordinaten SIGNAL YS :STD_LOGIC_VECTOR(31 DOWNTO 0):=(OTHERS => '0'); SIGNAL ZS :STD_LOGIC_VECTOR(31 DOWNTO 0):=(OTHERS => '0'); --------------------------------------------- SIGNAL XT :STD_LOGIC_VECTOR(31 DOWNTO 0):=(OTHERS => '0');-- Target Koordinaten(XS- XE) SIGNAL YT :STD_LOGIC_VECTOR(31 DOWNTO 0):=(OTHERS => '0'); SIGNAL ZT :STD_LOGIC_VECTOR(31 DOWNTO 0):=(OTHERS => '0'); ------------------------------------------ SIGNAL sstrimp :STD_LOGIC := '0'; --------------------------------------- SIGNAL srmpzu :std_logic_vector(1 DOWNTO 0):="00"; --SIGNAL STATUS :T_STAT:=((others=> (others=>'0')));--0..2 slv(7..0) wie vorherige STATUS aber für 3Ebenen SIGNAL STAT :T_STAT:=((others=> (others=>'0'))); SIGNAL stateSatz :INTEGER RANGE 0 TO 31:= 0; SIGNAL srampRun :STD_LOGIC := '0';-- interne Signal RampRun --============ Signale für LinITP Modul ====================== SIGNAL Xlin :STD_LOGIC_VECTOR(15 DOWNTO 0):= X"0000";-- Lin Koordinate für LinItp SIGNAL Ylin :STD_LOGIC_VECTOR(15 DOWNTO 0):= X"0000"; SIGNAL celin :STD_LOGIC:='0';--startImp für LinItp Modul SIGNAL Xactiv :STD_LOGIC:='0'; SIGNAL Yactiv :STD_LOGIC:='0'; SIGNAL LinLk :STD_LOGIC_VECTOR(31 DOWNTO 0):=(OTHERS => '0');--LinAX Leitachse --SIGNAL LinEbene :STD_LOGIC_VECTOR(3 DOWNTO 0):= "0000";-- Ebene von LinSatz --=========== Signale für ITP MOdul ======================= SIGNAL ITPmod :std_logic_vector(2 DOWNTO 0):="000";-- itp bits von ITPmodul SIGNAL ITP :std_logic_vector(2 DOWNTO 0):="000";--Itp bits für Status signal A0 :std_logic_vector(19 downto 0):=X"00000"; signal A1 :std_logic_vector(19 downto 0):=X"00000"; signal A2 :std_logic_vector(19 downto 0):=X"00000"; signal A3 :std_logic_vector(19 downto 0):=X"00000"; signal A4 :std_logic_vector(19 downto 0):=X"00000"; SIGNAL itprun :STD_LOGIC:= '0';-- interpolator(itp) läuft(linsatz oderInv.Trans) SIGNAL enditp :STD_LOGIC:= '0';-- Kontur Ende =0,run Kontur = 1 SIGNAL sImpLk :STD_LOGIC:= '1'; SIGNAL ce :STD_LOGIC:= '0'; SIGNAL sAXdif :std_logic_vector(95 downto 0):=(OTHERS => '0');--Inkr.Werte von Inv.Trans für Input Ramp SIGNAL pfrq :std_logic_vector(23 downto 0);--Periode dauer in CLK für XYZ INterpolation SIGNAL scalcok :STD_LOGIC:='0';-- Berechnungen beginend ab LkImp fertig ----------Signale für Encoder -- Wird später über konfig abgefüllt --RESAxx :Bits[7..0]AchseY,Bits[3..0]AchseX:DisAchs,Richtg(Dir),Res1,Res0 :Auflösungen /Ebene SIGNAL RESA21 :std_logic_vector(7 downto 0):= X"11"; --Achsen A2, A1 Auflösung 1X SIGNAL RESA43 :std_logic_vector(7 downto 0):= X"11"; --Auflösung A4, A3,Auflösung 1X SIGNAL RESA65 :std_logic_vector(7 downto 0):= X"11"; --Auflösung A6,A5,Auflösung 1X SIGNAL Encods :std_logic_vector(17 DOWNTO 0):= "00" & X"0000";--Encoder Signale A6..A1 Synchron ------------------------------------------- ------- signale für LRK RD /WR-------------------------------- SIGNAL StateRDuP :INTEGER RANGE 0 TO 31:= 0;-- State für Empfang Konfig Daten für KonfigTAB SIGNAL sKonRegOK :STD_LOGIC:='0';--+ Register eingelesen SIGNAL Konfstate :STD_LOGIC_VECTOR (7 downto 0):=X"00";--wenn 0 =>s=KonRegOK <= 0 -------------------------------------------------------------------- ------------Impulse --------------- --SIGNAL SollImp :STD_LOGIC_VECTOR(11 DOWNTO 0):=X"AAA";--Impulse von ITP oder Rampe --SIGNAL sISollImp :STD_LOGIC_VECTOR(11 DOWNTO 0):=X"AAA";--Impulse von Rampe umgewandelt auf 10ns --SIGNAL sZRefImp :STD_LOGIC_VECTOR (11 DOWNTO 0):=X"AAA";--Impulse von Ref Anfahren Controller SIGNAL ImpIst :STD_LOGIC:='0';-- Impulse IST von Enkoder Aktiv (A0.A6) --------------------------------------------------------------------------- ------------------------------------------- SIGNAL srefrun :STD_LOGIC:='0';-- Referenz am Anfahren SIGNAL skorron :STD_LOGIC:='0';-- schleppfehler Korrektur = 1: eingeschaltet SIGNAL srampzu :STD_LOGIC_VECTOR(1 DOWNTO 0):= "00"; SIGNAL sclrAx :STD_LOGIC:='0';-- clr für alle Axen register ------------------------------------------- SIGNAL sLimXY :STD_LOGIC_VECTOR(5 DOWNTO 0):="000000";--LRKLimit Erreicht sLimXy(5):A6...sLimXY(0):A1 SIGNAL sPoser :STD_LOGIC_VECTOR(5 DOWNTO 0):="000000"; -- PoserA1.. A6 für Erreicht = 1 -------------LRK----------------------------------------- SIGNAL IstImp :std_logic_vector(11 downto 0):=X"AAA";--erste bits[3..0]nimpA1,vorwA1,nimpA0,VorwA9 ---------- Ist- soll usw werte von LRK --T_AxReg IS ARRAY(0 to 5) OF STD_LOGIC_VECTOR(31 DOWNTO 0) SIGNAL SOLL :T_Axreg:=((others=> (others=>'0'))); SIGNAL IST :T_Axreg;--:=((others=> (others=>'0')));--für meldungen an master SIGNAL SIDiff :T_Axreg:=((others=> (others=>'0'))); SIGNAL SIABS :T_AxReg:=((others=> (others=>'0'))); --Abs.Wert von SIDif für 6 Achsen SIGNAL Diff :T_AxReg:=((others=> (others=>'0'))); --Diff abs wert inkl Schleppfehler ---SIGNAL DADiff :T_AxReg:=((others=> (others=>'0'))); --abs(Soll + vors - Ist)für 6 Achsen,alte wert SIGNAL DAXY :T_Ax16:=((others=> (X"8000")));-- Output Reg für D/A Wandler, Wert für D/A(15..0) ---------------Reg für WR zugriff auf IST/SOLL usw-------------------- SIGNAL SollRegWR :STD_LOGIC:='0'; SIGNAL IstRegWR :STD_LOGIC:='0'; SIGNAL iadrREG :INTEGER RANGE 0 TO 63 := 0;-- Reg Adresse SIGNAL WERT :STD_LOGIC_VECTOR(31 DOWNTO 0):= (OTHERS => '0'); --SIGNAL ISTD :T_Axreg;--Istwert für Deformationkorrektur SIGNAL AXINI :T_Axreg:=((others=> (others=>'0'))); SIGNAL sDAX10 :STD_LOGIC_VECTOR(31 DOWNTO 0):= X"80008000"; SIGNAL sDAX32 :STD_LOGIC_VECTOR(31 DOWNTO 0):= X"80008000"; SIGNAL sDAX54 :STD_LOGIC_VECTOR(31 DOWNTO 0):= X"80008000"; --------------------------------- ---------signale für RAMPE ----------------------- --SIGNAL sRAMPout :std_logic_vector(11 downto 0):=X"AAA"; SIGNAL sprgrun :STD_LOGIC:='0'; SIGNAL strout :STD_LOGIC:='0'; SIGNAL ormpzu :std_logic_vector(1 DOWNTO 0):="00"; SIGNAL sOutdif :std_logic_vector(95 DOWNTO 0):=(OTHERS => '0');--Ramp Inkr Output(inv.Trans) ------------------------------------------------------------------------- ----------Konfig Dateien kopien --------------------------------------- SIGNAL Steilheit :std_logic_vector(15 downto 0):= X"0000";--Rempensteilheit,Konfneu= --Enkoder:DisY(7),RichtgY(6),ResolY(5,4),DisX(3),RichtgX(2),ResolX(1,0)--- ---ResXY(78):(31..24),ResXY(56):(23..16),ResXY(34):(15..8),ResXY(12):(7..0) SIGNAL sRESAx :std_logic_vector(31 downto 0):=X"00000000";-- --=========================für Entity Inputs LRK ======================================== ---********************************************************************************************************** --=========es ist nötig diese Signale definieren wegen entity LrkREG , Konfigdaten aus CNC Memory (CPU16.1) ------============================================================= -----S526 = AxKonTAB an Master senden (nach Memory Fail) --=========================================================================== --Signal LIM = Poser und SIDif Limit vorläufig für alle Ebenen gleich Limits Ebene 0 -- wurde im Receiv s526 gesetzt,AxKonTAB an Master senden (nach Memory Fail) ---SIGNAL LIM :std_logic_vector(31 downto 0):=X"00000000";--Limit Soll/IST(31..16),(15..10)=INVERT(A5..A0), PoserLimit(7..0) --======================================================================================== --================================================================================================ ----------------- vrtuelle aktuelle Koordinaten---------------------------------------- SIGNAL Xa :std_logic_vector(31 downto 0):=X"00000000"; SIGNAL Ya :std_logic_vector(31 downto 0):=X"00000000"; SIGNAL Za :std_logic_vector(31 downto 0):=X"00000000"; SIGNAL Lka :std_logic_vector(31 downto 0):=X"00000000"; -----------Deformationberechnung der Achsen-------------------------------------- --========================================================================== -----------signale für SDI Interface- SDIAD---------------------------- --SIGNAL StateDAout :INTEGER RANGE 0 to 15:= 0; --SIGNAL ShiftReg :std_logic_vector(31 downto 0):= (OTHERS => '0'); SIGNAL StateAD :INTEGER RANGE 0 to 15:= 0; SIGNAL AnzAx :INTEGER RANGE 0 to 7:= 6; SIGNAL ADINP :T_ADINP;--Daten Kraftsensoren 12 bit (0..3) SIGNAL SDIADOK :STD_LOGIC:='0';-- AD Inputs Eingelesen SIGNAL StateDA12 :INTEGER RANGE 0 to 63:= 0; SIGNAL StateDA34 :INTEGER RANGE 0 to 63:= 0; SIGNAL StateDA56 :INTEGER RANGE 0 to 63:= 0; SIGNAL LDAC12 :STD_LOGIC:='0'; SIGNAL LDAC34 :STD_LOGIC:='0'; SIGNAL LDAC56 :STD_LOGIC:='0'; SIGNAL SDIok12 :STD_LOGIC:='0';--DA Ausgabe fertig,sdiDa12 SIGNAL SDIok34 :STD_LOGIC:='0';--DA Ausgabe fertig,sdiDa34 SIGNAL SDIok56 :STD_LOGIC:='0';--DA Ausgabe fertig,sdiDa56 --- SIGNAL init12 :STD_LOGIC:='0'; SIGNAL init34 :STD_LOGIC:='0'; SIGNAL init56 :STD_LOGIC:='0'; SIGNAL SERVOEN :STD_LOGIC:='0';-- servo ENABLE+ =0 ------------------------------------------------------ --========================================================== -------signale für Process AxDcalc -------------------------------------------------- --TYPE T_FP IS ARRAY(0 to 5) OF STD_LOGIC_VECTOR(31 DOWNTO 0);--FP Berechnung Einzel Achse SIGNAL InpFP1 :std_logic_vector(31 downto 0):=X"00000000";-- Inp & Outp für FP Funktionen SIGNAL InpFp2 :std_logic_vector(31 downto 0):=X"00000000"; SIGNAL OutFP1 :std_logic_vector(31 downto 0):=X"00000000"; SIGNAL OutFP2 :std_logic_vector(31 downto 0):=X"00000000"; SIGNAL ResAxRad :T_FP:=((others=> (others=>'0')));-- (A0..A5)Auflösung rad/inkr SIGNAL ISTD_FP :T_FP:=((others=> (others=>'0')));--ISTD in FP format SIGNAL AxDrad :T_FP:=((others=> (others=>'0')));--Achsenwinkel in FP format ----- SIGNAL ceIstFP :STD_LOGIC:='0';-- Start IntTo FP für ISTD SIGNAL ceIstAxD :STD_LOGIC:='0';-- Start DivFP für Achsen Winkel berechnn SIGNAL AxDradOK :STD_LOGIC:='0';-- Achsenwinkel fertigberechnet --============================================================================ --=============Signale Für Xdef=========================================== --TYPE T_ADINP IS ARRAY(0 to 3) OF STD_LOGIC_VECTOR(11 DOWNTO 0);--Daten Kraftsensoren --TYPE T_Dx IS ARRAY(0 TO 2) OF INTEGER;-- Kraftberechnung in der XYZ --TYPE T_Ax IS ARRAY(0 to 2) OF STD_LOGIC_VECTOR(31 DOWNTO 0); -- auch fü FP ---------------Signale für Xdef -------------------------------- ----------------------------------------------- --TYPE T_ADINP IS ARRAY(0 to 3) OF STD_LOGIC_VECTOR(11 DOWNTO 0);--Daten Kraftsensoren --TYPE T_Dx IS ARRAY(0 TO 2) OF INTEGER;-- Kraftberechnung in der XYZ --TYPE T_Ax IS ARRAY(0 to 2) OF STD_LOGIC_VECTOR(31 DOWNTO 0); -- auch fü FP --Tabelle: TAxrad :T_Ax; --------------------------- SIGNAL TAXrad :T_Ax:=((others=> (others=>'0'))); SIGNAL IstAX :T_Ax:=((others=> (others=>'0'))); SIGNAL CosAX :T_Ax:=((others=> (others=>'0'))); SIGNAL DAXdef :T_Ax:= ((others=> (others=>'0')));-- deformation Daten für A1,A,A4 SIGNAL FSX :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL FSX_FP :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000";-- Kraft in INT am sensor (FP) SIGNAL FSX_FPN :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000";--Kraft in N am sensor (Fp) SIGNAL Fx_FP :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000";-- Kraft in N am fräser (FP) SIGNAL DaXFP :T_Ax; SIGNAL DaXcFP :T_Ax; SIGNAL AXdef :T_Ax;--Deformationwinkel[rad] in den AchsenA1,A2,A4 (relev.Achsen in Richtun X) SIGNAL D_LAX :T_Ax;-- Armlängen Relevanten Achsen A1,A2,A4 SIGNAL RsAX :T_AX;-- Auflösung für RelevAchsen A1,A2,A4 SIGNAL IncrAX :T_Ax;--Korrektur Werte für A1,A2,A4 Achsen in Richtun X in Inkrementen SIGNAL inpX1 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- zwischen Speicher für Input FD Fkt SIGNAL inpX2 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outX1 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outX2 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outX3 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outX4 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outX5 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outX6 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -------------------------------------------------------- SIGNAL ceXD0 :STD_LOGIC:='0';-- start signale für FP Fkt SIGNAL ceXD1 :STD_LOGIC:='0'; SIGNAL ceXD2 :STD_LOGIC:='0'; SIGNAL ceXD3 :STD_LOGIC:='0'; SIGNAL ceXD4 :STD_LOGIC:='0'; SIGNAL ceXD5 :STD_LOGIC:='0'; SIGNAL ceXD6 :STD_LOGIC:='0'; SIGNAL ceXD7 :STD_LOGIC:='0'; SIGNAL ceXD8 :STD_LOGIC:='0'; --========================== Ende XDEf ========================= --=========================================================================== --=============Signale Für Ydef======================================================= --TYPE T_ADINP IS ARRAY(0 to 3) OF STD_LOGIC_VECTOR(11 DOWNTO 0);--Daten Kraftsensoren --TYPE T_Dx IS ARRAY(0 TO 2) OF INTEGER;-- Kraftberechnung in der XYZ --TYPE T_Ax IS ARRAY(0 to 2) OF STD_LOGIC_VECTOR(31 DOWNTO 0); -- auch fü FP ---------------Signale für Xdef -------------------------------- ----------------------------------------------- --TYPE T_ADINP IS ARRAY(0 to 3) OF STD_LOGIC_VECTOR(11 DOWNTO 0);--Daten Kraftsensoren --TYPE T_Dx IS ARRAY(0 TO 2) OF INTEGER;-- Kraftberechnung in der XYZ --TYPE T_Ax IS ARRAY(0 to 2) OF STD_LOGIC_VECTOR(31 DOWNTO 0); -- auch fü FP --Tabelle: TAxrad :T_Ax; --------------------------- SIGNAL TAYrad :T_Ax:=((others=> (others=>'0'))); SIGNAL IstAY :T_Ax:=((others=> (others=>'0'))); SIGNAL CosAY :T_Ax:=((others=> (others=>'0'))); SIGNAL DAYdef :T_Ax:= ((others=> (others=>'0')));-- deformation Daten für A1,A,A4 SIGNAL FSY :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL FSY_FP :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000";-- Kraft in INT am sensor (FP) SIGNAL FSY_FPN :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000";--Kraft in N am sensor (Fp) SIGNAL Fy_FP :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000";-- Kraft in N am fräser (FP) SIGNAL DaYFP :T_Ax; SIGNAL DaYcFP :T_Ax; SIGNAL AYdef :T_Ax;--Deformationwinkel[rad] in den AchsenA1,A2,A4 (relev.Achsen in Richtun X) SIGNAL D_LAY :T_Ax;-- Armlängen Relevanten Achsen A1,A2,A4 SIGNAL RsAY :T_AX;-- Auflösung für RelevAchsen A1,A2,A4 SIGNAL IncrAY :T_Ax;--Korrektur Werte für A1,A2,A4 Achsen in Richtun X in Inkrementen SIGNAL inpY1 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- zwischen Speicher für Input FD Fkt SIGNAL inpY2 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outY1 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outY2 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outY3 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outY4 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outY5 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outY6 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -------------------------------------------------------- SIGNAL ceYD0 :STD_LOGIC:='0';-- start signale für FP Fkt SIGNAL ceYD1 :STD_LOGIC:='0'; SIGNAL ceYD2 :STD_LOGIC:='0'; SIGNAL ceYD3 :STD_LOGIC:='0'; SIGNAL ceYD4 :STD_LOGIC:='0'; SIGNAL ceYD5 :STD_LOGIC:='0'; SIGNAL ceYD6 :STD_LOGIC:='0'; SIGNAL ceYD7 :STD_LOGIC:='0'; SIGNAL ceYD8 :STD_LOGIC:='0'; --============================================================ --=============Signale Für XDef Zdef======================================================= ----------------------------------------------- --TYPE T_ADINP IS ARRAY(0 to 3) OF STD_LOGIC_VECTOR(11 DOWNTO 0);--Daten Kraftsensoren --TYPE T_Dx IS ARRAY(0 TO 2) OF INTEGER;-- Kraftberechnung in der XYZ --TYPE T_Ax IS ARRAY(0 to 2) OF STD_LOGIC_VECTOR(31 DOWNTO 0); -- auch fü FP --Tabelle: TAxrad :T_Ax; --------------------------- SIGNAL TAZrad :T_Ax:=((others=> (others=>'0'))); SIGNAL IstAZ :T_Ax:=((others=> (others=>'0'))); SIGNAL CosAZ :T_Ax:=((others=> (others=>'0'))); SIGNAL DAZdef :T_Ax:= ((others=> (others=>'0')));-- deformation Daten für A1,A,A4 SIGNAL FSZ :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL FSZ_FP :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000";-- Kraft in INT am sensor (FP) SIGNAL FSZ_FPN :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000";--Kraft in N am sensor (Fp) SIGNAL Fz_FP :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000";-- Kraft in N am fräser (FP) SIGNAL DaZFP :T_Ax; SIGNAL DaZcFP :T_Ax; SIGNAL AZdef :T_Ax;--Deformationwinkel[rad] in den AchsenA1,A2,A4 (relev.Achsen in Richtun X) SIGNAL D_LAZ :T_Ax;-- Armlängen Relevanten Achsen A1,A2,A4 SIGNAL RsAZ :T_AX;-- Auflösung für RelevAchsen A1,A2,A4 SIGNAL IncrAZ :T_Ax;--Korrektur Werte für A1,A2,A4 Achsen in Richtun X in Inkrementen SIGNAL inpZ1 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- zwischen Speicher für Input FD Fkt SIGNAL inpZ2 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL inpZ3 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outZ1 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outZ2 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outZ3 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outZ4 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outZ5 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outZ6 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; SIGNAL outZ7 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -------------------------------------------------------- SIGNAL ceZD0 :STD_LOGIC:='0';-- start signale für FP Fkt SIGNAL ceZD1 :STD_LOGIC:='0'; SIGNAL ceZD2 :STD_LOGIC:='0'; SIGNAL ceZD3 :STD_LOGIC:='0'; SIGNAL ceZD4 :STD_LOGIC:='0'; SIGNAL ceZD5 :STD_LOGIC:='0'; SIGNAL ceZD6 :STD_LOGIC:='0'; SIGNAL ceZD7 :STD_LOGIC:='0'; SIGNAL cezD8 :STD_LOGIC:='0'; --===================LRK Testsignale =========================================== SIGNAL sSIout :STD_LOGIC_VECTOR(3 DOWNTO 0):= "0000"; SIGNAL sDAXout :STD_LOGIC_VECTOR(3 DOWNTO 0):= "0000"; SIGNAL sDAwertOUT :STD_LOGIC_VECTOR(15 DOWNTO 0):=X"0000"; --========************************************************************************************* --==================================================================================== -------------------------------------------------------------------------- -- Registers --Enkoder:DisY(7),RichtgY(6),ResolY(5,4),DisX(3),RichtgX(2),ResolX(1,0)--- ---ResXY(78):(31..24),ResXY(56):(23..16),ResXY(34):(15..8),ResXY(12):(7..0) ---inputs mulkorr -TYPE T_Ax16:IS ARRAY(0 to 5) OF STD_LOGIC_VECTOR(15 DOWNTO 0);---- SIGNAL Acc :STD_LOGIC_VECTOR(15 DOWNTO 0):=X"0000";-- Input multipl SIGNAL accel :T_Ax16:=((others=> (others=>'0'))); -- beschleunigung 16 bit sig SIGNAL KorrS :STD_LOGIC_VECTOR(7 DOWNTO 0):=X"00";--InputB SpeedKorAX( mulkorr):8bit unsig SIGNAL KorrA :STD_LOGIC_VECTOR(7 DOWNTO 0):=X"00";--InputB AccKorAX(mulkorr):8bit unsig SIGNAL svk :STD_LOGIC_VECTOR(23 DOWNTO 0):=X"000000";-- SpeedX korrig: Multkorr outputP SIGNAL sacc :STD_LOGIC_VECTOR(23 DOWNTO 0):=X"000000";-- AccelX korrig: Multkorr outputP -------T_Axreg:ARRAY(0 to 5) OF STD_LOGIC_VECTOR(31 DOWNTO 0);-- SIGNAL svorsk :T_AxReg:=((others=> (others=>'0')));--Speed + accel extended 32 ---- signale für abtast X,Y:T_Ax16: ARRAY(0 to 5) OF STD_LOGIC_VECTOR(15 DOWNTO 0);----- SIGNAL Spd :STD_LOGIC_VECTOR(15 DOWNTO 0):=X"0000";-- Input multipl SIGNAL Speed :T_Ax16:=((others=> (others=>'0'))); -- Ableitung von Sollw Impulse SIGNAL Espd :T_AXReg:=((others=> (others=>'0')));--Extended Speed SIGNAL Eacc :T_AXReg:=((others=> (others=>'0')));--Extended Acceleration SIGNAL spdOut :STD_LOGIC:= '0'; ---vorsXY :out Entity STD_LOGIC_VECTOR (31 downto 0);speedX,Y auf Output -------------------------------------------------------------- SIGNAL stateSpd :INTEGER RANGE 0 TO 7:=0;-- Berecnung Speed(i) & Espd(i) SIGNAL stateAcc :INTEGER RANGE 0 TO 7:=0;-- Berecnung Acc & Eacc --====================================================== -------------------------------------------------------------------- --SIGNAL ImpSoll :STD_LOGIC:= '0'; SIGNAL fnegAX :STD_LOGIC_VECTOR(5 DOWNTO 0):= "000000";-- vorzeichen für alle Achsen SIGNAL finvAX :STD_LOGIC_VECTOR(5 DOWNTO 0):= "000000";-- invertierung für alle Achsen -------- DA Werte Berechnung ---T_AxReg: ARRAY(0 to 5) OF STD_LOGIC_VECTOR(31 DOWNTO 0)----- SIGNAL DAWertAX :T_Ax16:=((others=> (X"0000")));----Abs. DA Integer Outputwert SIGNAL KPtAX :T_AxReg:=((others=> (others=>'0')));-- Resultat KNPKTX * K2X -------- DA-Werte ---TYPE T_Ax16:IS ARRAY(0 to 5) OF STD_LOGIC_VECTOR(15 DOWNTO 0); SIGNAL InpA :STD_LOGIC_VECTOR(15 DOWNTO 0):=X"0000";-- Input multipl SIGNAL InpB :STD_LOGIC_VECTOR(7 DOWNTO 0):=X"00"; SIGNAL OutpP :STD_LOGIC_VECTOR(23 DOWNTO 0):=X"000000";--Resultatt Multipl. ------Konfig Daten--T_EbReg:ARRAY(0 to 2) OF STD_LOGIC_VECTOR(31 DOWNTO 0)----- -------------------------- SIGNAL KNPTXY :T_EbReg:=((others=> (others=>'0')));--Knickpunkt konfig KNPKTY | KNPKTX SIGNAL KXY :T_EbReg:=((others=> (others=>'0')));---- Kreisverstärkung K2Y,K1Y | K2X,K1X SIGNAL korrXY :T_EbReg:=((others=> (others=>'0')));--31..24:KaccY,23..16:KorrY | 15..8:KaccX, 7..0:KorrX --------------------------------------------------------------------- SIGNAL stateDIFF :INTEGER RANGE 0 TO 7:=0; SIGNAL ce1608 :std_logic := '0'; --================frqperiod======================================== SIGNAL StatePer :INTEGER RANGE 0 to 15:= 0; SIGNAL periode :INTEGER RANGE 0 TO 16777215:=maxper;-- 24 bit(17..0) --================================================================ SIGNAL TIMER :STD_LOGIC:='0';-- es wird alle 0.2 sek ein Impuls erzeugt --============================================================= SIGNAL stestdata :STD_LOGIC_VECTOR(15 DOWNTO 0):=X"0000"; --============================================================== -- KonnfBuff---Empfangen von uP------------------------------------ --TYPE T_KonfTab is array(0 to 175) of STD_LOGIC_VECTOR(7 downto 0); --000,8x1B poslim --008,8x1B RESAX --010, Limit Soll/Ist --020,16x1B KACCXY --030,16x1B KORXY --040,8x2B, STEIL weiter L1,L",L3 usw. --Total 176 Byte --========================================================================== --*********************************************************************** -------------------------------------------------------------------- --====================================================================== -- konfig Werte für Achsen A1..A6 kompatibel mit Meldungen von CPU16.1 -- Wird bei CNC Memory(CPU16.1) Verlust an Master(CPU16.1) gesendet --TYPE T_AxKonTab IS ARRAY(0 TO 71) OF STD_LOGIC_VECTOR(7 DOWNTO 0);-- total 3 x 24 Byte ------ HARDWARE KONFIGURATION KONSTANTEN -- --für BCODE ="0110"--KONFIGTABELLE an CPU16.1 senden ---- ------------------------------------------------------------------------ SIGNAL AxKonTab :T_AxKonTab := ( --Hex dez X"33",-- 00 00 RARTXY | CNGY |ENDY+| IDY | RAY | CNGX |ENDX+| IDX | RAX | X"11",-- 01 01 REFDIR |INVY0| - |IDIRY|RDIRY |INVX0| - |IDIRX|RDIRX| X"37",-- 02 02 LIMITX Limit XHB,LB =FF,+/-20Grd X"35",-- 03 03 LIMITY Limit YHB,LB= FF,+/-20Grd X"11",-- 04 04 POSXY Y:bit 7..4 & "11"=7,X:bit3..0 & "11"=7 X"05",-- 05 05 VORINX VORSCH.INDX ANFAHREN = frq/(vorinX *2)+1 X"05",-- 06 06 VORINY X"00",-- 07 07 KACCX Beschleunigung Schleppfehlerkorrektur X"00",-- 08 08 KACCY X"00",-- 09 09 KORRX Speed_X Schleppfehlerkorrektur X"00",-- 0A 10 KORRY X"55",-- 0B 11 RESXY Bit1,0:00/01=1x,10=2x,11=4x; Bit2:RichtungX, Bit3:=1: DISX X"03",-- 0C 12 VREFX VORSCH.REF.ANFAHREN X =frq/(vrefX *2)+1 X"03",-- 0D 13 13VREFY X"00",-- 0E 14 TKPKTX KNICKPUNKT KV-KENNLINIE X"01",-- 0F 15 TKPKTX X"00",-- 10 16TKPKTY KNICKPUNKT KV-KENNLINIE X"01",-- 11 17 TKPKTY X"60",-- 12 18 K1XT Verstärkung KV-LB ACHSE X :K1=xxxxxxx.x X"A0",-- 13 19 K2XT Verstärkung KV-HB ACHSE X :K2=xxx.xxxxx X"60",-- 14 20 K1YT Verstärkung KV-LB ACHSE Y :K1=xxxxxxx.x X"A0",-- 15 21 K2YT Verstärkung KV-HB ACHSE Y :K2=xxx.xxxxx X"FF",-- 16 22 STEILH STEILHEIT RAMPE LB : 2000 = 07D0H X"7F",-- 17 23 STEILH (byte23) ----------- Achsen A4, A3 ----------------------- X"33",-- 18 24 RARTXY | CNGY |ENDY+| IDY | RAY | CNGX |ENDX+| IDX | RAX | X"11",-- 19 25 REFDIR |INVY1| - |IDIRY|RDIRY |invX1| - |IDIRX|RDIRX| X"1A",-- 1A 26 LIMITX Limit XHB,LB =FF,+/-20Grd, max für test X"1B",-- 1B 27 LIMITY Limit YHB,LB =FF,+/-30Grd X"11",-- 1C 28 POSXY Y:bit 7..4 & "11"=7,X:bit3..0 & "11"=7 X"05",-- 1D 29 VORINX VORSCH.INDX ANFAHREN = frq/(vorinX *2)+1 X"05",-- 1E 30 VORINY X"00",-- 1F 31 KACCX Beschleunigung Schleppfehlerkorrektur X"00",-- 20 32 KACCY X"00",-- 21 33 KORRX Speed_X Schleppfehlerkorrektur X"00",-- 22 34 KORRY X"51",-- 23 35 RESXY Bit1,0:00/01=1x,10=2x,11=4x,Bit2:RichtungX, Bit3:=1: DISX X"03",-- 24 36 VREFX VORSCH.REF.ANFAHREN X =frq/(vrefX *2)+1 X"03",-- 25 37 VREFY X"00",-- 26 38 TKPKTX KNICKPUNKT KV-KENNLINIE X"01",-- 27 39 TKPKTX X"00",-- 28 40 TKPKTY KNICKPUNKT KV-KENNLINIE X"01",-- 29 41 TKPKTY X"80",-- 2A 42 K1XT Verstärkung KV-LB ACHSE X :K1=xxxxxxx.x X"A0",-- 2B 43 K2XT Verstärkung KV-HB ACHSE X :K2=xxx.xxxxx X"60",-- 2C 44 K1YT Verstärkung KV-LB ACHSE Y :K1=xxxxxxx.x X"A0",-- 2D 45 K2YT Verstärkung KV-HB ACHSE Y :K2=xxx.xxxxx X"FF",-- 2E 46 STEILH STEILHEIT RAMPE LB : 2000 = 07D0H X"7F",-- 2F 47 STEILH (byte47) ----------- Achsen A5, A6 ----------------------- X"33",-- 30 48 RARTXY | CNGY |ENDY+| IDY | RAY | CNGX |ENDX+| IDX | RAX | X"11",-- 31 49 REFDIR |INVY2| - |IDIRY|RDIRY |INVX2| - |IDIRX|RDIRX| X"20",-- 32 50 LIMITX Limit XHB,LB =FF,+/-30Grd X"20",-- 33 51 LIMITY Limit YHB,LB =FF,+/-30Grd X"11",-- 34 52 POSXY Y:bit 7..4 & "11"=7,X:bit3..0 & "11"=7 X"05",-- 35 53 VORINX VORSCH.INDX ANFAHREN = frq/(vorinX *2)+1 X"05",-- 36 54 VORINY X"00",-- 37 55 KACCX Beschleunigung Schleppfehlerkorrektur X"00",-- 38 56 KACCY X"00",-- 39 57 KORRX Speed_X Schleppfehlerkorrektur X"00",-- 3A 58 KORRY X"15",-- 3B 59 RESXY Bit1,0:00/01=1x,10=2x,11=4x,Bit2:RichtungX,Bit3:=1:DISX X"03",-- 3C 60 VREFX VORSCH.REF.ANFAHREN X =frq/(vrefX *2)+1 X"03",-- 3D 61 VREFY X"00",-- 3E 62 TKPKTX KNICKPUNKT KV-KENNLINIE X"01",-- 3F 63 TKPKTX X"00",-- 40 64 TKPKTY KNICKPUNKT KV-KENNLINIE X"01",-- 41 65 TKPKTY X"20",-- 42 66 K1XT Verstärkung KV-LB ACHSE X :K1=xxxxxxx.x X"A0",-- 43 67 K2XT Verstärkung KV-HB ACHSE X :K2=xxx.xxxxx X"20",-- 44 68 K1YT Verstärkung KV-LB ACHSE Y :K1=xxxxxxx.x X"A0",-- 45 69 K2YT Verstärkung KV-HB ACHSE Y :K2=xxx.xxxxx X"FF",-- 46 70 STEILH STEILHEIT RAMPE LB : 2000 = 07D0H X"7F"-- 47 71 STEILH (byte 71) );-- AxkonTAB --====================================================================== --====================================================================== -- konfig Werte für Achsen A1..A6 kompatibel mit Meldungen von CPU16.1, editierbar -- Wird bei Aenderung der AS Konfig Werte in KonfigMenue (OPTI) und bei -- PWRUP beschrieben mitb den Werten aus CNC Memory (CPU16.1) --TYPE T_AxKonTab IS ARRAY(0 TO 71) OF STD_LOGIC_VECTOR(7 DOWNTO 0);-- total 3 x 24 Byte ------ HARDWARE KONFIGURATION KONSTANTEN -- --für BCODE ="02"--KONFIG Satz Master(CPU16.1) an AS21 ---- Label S7 im RECEIV Process ------------------------------------------------------------------------ SIGNAL AxKonREG :T_AxKonTab := ( ------- Achsen A1,A2 (Y,X),RefA0,RefA1 X"33",-- 00 00 RARTXY | CNGY |ENDY+| IDY | RAY | CNGX |ENDX+| IDX | RAX | X"11",-- 01 01 REFDIR |INVY0| - |IDIRY|RDIRY |INVX0| - |IDIRX|RDIRX| X"37",-- 02 LIMITX Limit XHB,LB =FF,+/-20Grd X"35",-- 03 LIMITY Limit YHB,LB= FF,+/-20Grd X"11",-- 04 POSXY Y:bit 7..4 & "11"=7,X:bit3..0 & "11"=7 X"05",-- 05 VORINX VORSCH.INDX ANFAHREN = frq/(vorinX *2)+1 X"05",-- 06 VORINY X"00",-- 07 KACCX Beschleunigung Schleppfehlerkorrektur X"00",-- 08 KACCY X"00",-- 09 KORRX Speed_X Schleppfehlerkorrektur X"00",-- 0A KORRY X"55",-- 0B RESXY Bit1,0:00/01=1x,10=2x,11=4x,Bit2:RichtungX, Bit3:=1: DISX X"03",-- 0C VREFX VORSCH.REF.ANFAHREN X =frq/(vrefX *2)+1 X"03",-- 0D VREFY X"00",-- 0E TKPKTX KNICKPUNKT KV-KENNLINIE X"01",-- 0F TKPKTX X"00",-- 10 TKPKTY KNICKPUNKT KV-KENNLINIE X"01",-- 11 TKPKTY X"60",-- 12 K1XT Verstärkung KV-LB ACHSE X :K1=xxxxxxx.x X"A0",-- 13 K2XT Verstärkung KV-HB ACHSE X :K2=xxx.xxxxx X"60",-- 14 K1YT Verstärkung KV-LB ACHSE Y :K1=xxxxxxx.x X"A0",-- 15 K2YT Verstärkung KV-HB ACHSE Y :K2=xxx.xxxxx X"FF",-- 16 STEILH STEILHEIT RAMPE LB : 2000 = 07D0H X"7F",-- 17 STEILH (byte23) ----------- Achsen A3, A4 ,RefA2,RefA3 fü Test:nur achse A3 in Endlage Modus----------------------- X"33",-- 18 RARTXY | CNGY |ENDY+| IDY | RAY | CNGX |ENDX+| IDX | RAX | X"11",-- 19 REFDIR |INVY1| - |IDIRY|RDIRY |invX1| - |IDIRX|RDIRX| X"1A",-- 1A LIMITX Limit XHB,LB =FF,+/-20Grd X"1B",-- 1B LIMITY Limit YHB,LB =FF,+/-30Grd X"11",-- 1C POSXY Y:bit 7..4 & "11"=7,X:bit3..0 & "11"=7 X"05",-- 1D VORINX VORSCH.INDX ANFAHREN = frq/(vorinX *2)+1 X"05",-- 1E VORINY X"00",-- 1F KACCX Beschleunigung Schleppfehlerkorrektur X"00",-- 20 KACCY X"00",-- 21 KORRX Speed_X Schleppfehlerkorrektur X"00",-- 22 KORRY X"51",-- 23 RESXY Bit1,0:00/01=1x,10=2x,11=4x,Bit2:RichtungX, Bit3:=1: DISX X"03",-- 24 VREFX VORSCH.REF.ANFAHREN X =frq/(vrefX *2)+1 X"03",-- 25 VREFY X"00",-- 26 TKPKTX KNICKPUNKT KV-KENNLINIE X"01",-- 27 TKPKTX X"00",-- 28 TKPKTY KNICKPUNKT KV-KENNLINIE X"01",-- 29 TKPKTY X"80",-- 2A K1XT Verstärkung KV-LB ACHSE X :K1=xxxxxxx.x X"A0",-- 2B K2XT Verstärkung KV-HB ACHSE X :K2=xxx.xxxxx X"60",-- 2C K1YT Verstärkung KV-LB ACHSE Y :K1=xxxxxxx.x X"A0",-- 2D K2YT Verstärkung KV-HB ACHSE Y :K2=xxx.xxxxx X"FF",-- 2E STEILH STEILHEIT RAMPE LB : 2000 = 07D0H X"7F",-- 2F STEILH (byte47) ----------- Achsen A5, A6 ,RefA4,RefA5,----------------------- X"33",-- 30 RARTXY | CNGY |ENDY+| IDY | RAY | CNGX |ENDX+| IDX | RAX | X"11",-- 31 REFDIR |INVY2| - |IDIRY|RDIRY |INVX2| - |IDIRX|RDIRX| X"20",-- 32 LIMITX Limit XHB,LB =FF,+/-30Grd X"20",-- 33 LIMITY Limit YHB,LB =FF,+/-30Grd X"11",-- 34 POSXY Y:bit 7..4 & "11"=7,X:bit3..0 & "11"=7 X"05",-- 35 VORINX VORSCH.INDX ANFAHREN = frq/(vorinX *2)+1 X"05",-- 36 VORINY X"00",-- 37 KACCX Beschleunigung Schleppfehlerkorrektur X"00",-- 38 KACCY X"00",-- 39 KORRX Speed_X Schleppfehlerkorrektur X"00",-- 3A KORRY X"15",-- 3B RESXY Bit1,0:00/01=1x,10=2x,11=4x,Bit2:RichtungX, Bit3:=1: DISX X"03",-- 3C VREFX VORSCH.REF.ANFAHREN X =frq/(vrefX *2)+1 X"03",-- 3D VREFY X"00",-- 3E TKPKTX KNICKPUNKT KV-KENNLINIE X"01",-- 3F TKPKTX X"00",-- 40 TKPKTY KNICKPUNKT KV-KENNLINIE X"01",-- 41 TKPKTY X"20",-- 42 K1XT Verstärkung KV-LB ACHSE X :K1=xxxxxxx.x X"A0",-- 43 K2XT Verstärkung KV-HB ACHSE X :K2=xxx.xxxxx X"20",-- 44 K1YT Verstärkung KV-LB ACHSE Y :K1=xxxxxxx.x X"A0",-- 45 K2YT Verstärkung KV-HB ACHSE Y :K2=xxx.xxxxx X"FF",-- 46 STEILH STEILHEIT RAMPE LB : 2000 = 07D0H X"7F"-- 47 STEILH (byte 71) );-- AxKonREG --=========******************************************============================= --======================================================================== -- Roboter Konfig Werte aus u-Controller für: -- Roboter Abmessungen, Achsen Auflösungen, ITP Frequenz, -- und später Kraft/Deformation Korrekturwerte --TYPE T_KonfigTab is array(0 to 41) of Std_logic_vector(31 DOWNTO 0); ----SIGNAL KonfigTab :T_KonfigTAb:=((others=> (others=>'0')));-- --------------------------------------- SIGNAL KonfigTab :T_KonfigTAB:= ( --- Arm längen des Roboters----indx X"0000015E",-- L1=350 0/0 X"00000186",-- L2=390 X"00000096",-- L3=150 X"00000000",-- L4= 0 15-12/3 ----Achsenauflösungen in FP Format,Anz.Inkr für 1 U des Rob.Arm X"48799a00", --Achse A0,255592 Inkr/U Arm 19-16/4 X"4871B2c0", --Achse A1,247499 I/U X"47ED3E80", --Achse A2,121469 X"47F3C000", --Achse A3,124800 X"45F22800", --Achse A4,7749 X"478BA800", --Achse A5,71504 I/U , 39-36/9 ---- ITP Frq Periode ------ X"00000E10", -- 43-40/10 ---- AnzIncr für Ref Anfahren --- X"0000F629",--Achse A0 -- 47-44/11 X"00002007",--Achse A1 X"FFFF8475",--Achse A2 X"47f3c000",--Achse A3 X"45f22800",--Achse A4 X"478ba800",--Achse A5 64/16 --INit Wert Ax: nach ref anfahren Soll/IST auf diese wert setzen X"00000000",--68 Init wert Soll /IST A0=0 -- /17 X"0000F1B2",--72 Init wert Soll /IST A1=90Grd X"FFFF8961",--76 Init wert Soll /IST A2=-90Grd X"00000000",--80 Init wert Soll /IST A3=0 X"00000000",--84 Init wert Soll /IST A4=0 X"00000000",--88 Init wert Soll /IST A5=0 /22 ---Deformations werte im FP Format: inkr/rad X"471ee6b3",--A0:40678.70 inkr /rad,C_A0rad /23 X"4719deae",--A1:39390.68 inkr /rad,C_A1rad X"469708c8",--A2:19332.39 inkr /rad,C_A2rad X"469b2d0f",--A3:19862.53 inkr /rad,C_A3rad X"449a28f6",--A4:1233.28 inkr /rad,C_A4rad X"4631d0d7",--A5:11380.21 inkr /rad,C_A5rad /28 ---Deformations werte im FP Format: rad/inkr X"37ce375b",--A0:0.00002458289 rad/inkr,C_radA0 /29 X"37d4f591",--A1:0.00002538672 rad/inkr,C_radA1 X"3858f514",--A2:0.00005172666 rad/inkr,C_radA2 X"38532aa9",--A3:0.00005034605 rad/inkr,C_radA3 X"3a548ef2",--A4:0.00081084587 rad/inkr,C_radA4 X"38b847d6",--A5:0.00008787184 rad/inkr,C_radA5 139-136,34 ----Roboter arm länge für Deformation Berechnung ------------------- X"3f800000",-- 378 mm,nur nach Ref.Anfahren, C_L0 /35 X"43aa0000",-- 340 mm, C-L1 X"43bc0000",-- 376, C_L2 X"43750000",-- 245 mm, Drehachse, C_L3 X"43750000",-- 245 mm,inkl Fräse, c_L4 X"3f800000",-- 1 mm, drehachse, C_L5 163-160/40 --Achsen Deformation bei max Kraft Fmax in FP format, D[mm]/FSmax[N](22.25)- -- Achsendeformation bei FSmax(22.25 N):DA0=0.4mm,DA1=0.01mm,DA2=0.1mm,Da3=0.3mm,DA4=0.5mm,Da5=0.01mm -- D_DAx = DAx / FS_max X"3c93459c",--0.4mm/22.25=0.01797752809, C_DA0 167-164/41 X"39eba293",--0.01mm/22.25=0.00044943820, C_DA1 X"3b93459c",--0.1mm/22.25=0.00449438202, C_DA2 X"3c5ce86a",--0.3mm/22.25=0.01348314607, C_DA3 X"3cb81703",--0.5mm/22.25=0.02247191011, C_DA4 X"39eba293",--0.01mm/22.25=0.00044943820, C_DA5 187-184/46 --- KonfigTAB Status ------ X"00000001" ---- indexByte:191-188, index Integer /47 ); ----- KonfigTAB Status ---------------------------------- --X"01",-- =1: = 1 :Neue Daten,sonst 0 wenn bereits gesendet,indexByte:188, index Integer /47 --X"00",-- = 00: 8 bit Bus, =01: 32 Bit buss 189 --X"00", --X"00" -- Deformation.Korrektur aktiv, = 0 Korr.inaktiv 191 --================================================================================= --------------KonfigTAB INIT inhalt in bytes--------------------------------------- --( --X"5E", --00,L1 LB, nax 65535 mm --Byte Index 0,Integeg Index 0 --X"01", --L1 HB in mm =350mm --X"00", --X"00", --3, ----- --X"86", --04d,L2 LB --4,1 --X"01", --L2 HB in mm = 390mm --X"00", --X"00", --7, ----- --X"96", --08,L3 LB --8,2 --X"00", --L3 HB in mm = 150mm --X"00", --X"00", --11 ---- --X"00", --12,L4 LB --12,3 --X"00", --L4 HB in mm 00 --X"00", --X"00", --15 ----=====Achsenauflösungen am Roboterarm===================== --X"00", --16,C_A0res LSB in FP Format, 2PI/Resolution -16,4 --X"9a", -- --X"79", --48799a00=255592 Unkr/U Roboterarm,gemesssen --X"48", --19,MSB A0res, Achse A1,1:102,Motor2500Imp/U A1 --19 ---- --X"c0", --20,C_A1res LSB in FP Format -20,5 --X"b2", -- --X"71", --4871b2c0 = 247499 Imp/U Roboterarm,gemesssen --X"48", --23,MSB A1res ,Achse A2,1:99,Motor2500 Imp/U ---23 -------------- --X"80", --24,C_A2res LSB in FP Format --24,6 --X"3e", -- --X"ed", --47ed3e80=121469 Imp/U Roboterarm,gemesssen --X"47", --27 A2res MSB ,Achse A3,1:15.133,Motor 1500Imp/U --27 ----- --X"00", --28,C_A3res LSB in FP Format --28,7 --X"c0", -- --X"f3", --47f3c000 = 124800 imp/u Roboterarm,gemesssen --X"47", --31,A3res MSB Achse A4,1:83.2,Motor 1500Imp/U --31 ---- --X"00", --32,C_A4res LSB in FP Format --32,8 --X"28", -- --X"f2", --45f22800 = 7749 imp/u Roboterarm,gemesssen --X"45",--35,A4res MSB,Achse A5, 1:5.166,Motor 1500Imp/U --35 ---- --X"00", --36,C_A5res LSB in FP Format --36,9 --X"a8", -- --X"8b", --478ba800 = 71504 imp/u Roboterarm,gemesssen --X"47", --39,A5res,MSB,Achse A6,1:47.67, Motor 1500Imp/u --39 ----====================================================== --X"10", --40, ITP Frq Periode LSB --40,10 --X"0E", --X"00", --X"00", -- ITP Frq Periode MSB X"000E10" = 3600 clk --43 -----=================================================================== ------********** AnzInc(5..0):integer für Ref.Anfahren----********------ --X"29", --LSB AnzInc(0), Achse A0,+63017 imp= 0000F629 --44,11 --X"F6",-- fahren zuerst in neg Richtung --X"00",-- motor Auflösung 2500/U --X"00", --MSB Auflösung 255592 Imp/Roboterarm 360 Grd, Get 1:102 ---------- --X"07", --LSB AnzInc(1), Achse A1,+8199 imp 00002007 --48,12 --X"20",-- fahren zuerst in neg Richtung --X"00",-- motor Auflösung 2500/U --X"00", --MSB Auflösung 247499.48 Imp/Roboterarm 360 Grd, Getr: 1:99 ---------- --X"75", --LSB AnzInc(2), Achse A2,-31627 imp FFFF8475 --52,13 --X"84", --fahren zuerst in pos Richtung --X"FF", --X"FF", --MSB Auflösung 121469 Imp/Roboterarm360 Grd,Getr: 1:15.1333,--55 --------- --X"7B", --LSB AnzInc(3) Achse A3,-1932 imp FFFFF87B --56,14 --X"F8", --fahren zuerst in pos Richtung --X"FF", --X"FF", --MSB Auflösung 121469 Imp/Roboterarm 360 Grd, Getr: 1:83.2 ---------- --X"68", --LSB AnzInc(4),Achse A4,+6504 imp 00001968 --60,15 --X"19", --fahren zuerst in neg Richtung danach positiv --X"00", --X"00", --MSB,Auflösung 7749 Imp/Roboterarm 360 Grd, Getr: 1:5.166 ---------- --X"00", --LSB AnzInc(5) --64,16 --X"00", --zuerst keine Ref anfahren --X"00", --X"00", --MSB --------*********ANINC fertig***************************************** --------INit Wert Ax------------------------------------------------ --X"00", --68 Init wert Soll /IST A0=0 --68,17 --X"00",--255592 Imp/U roboter Arm --X"00", --X"00", --71d, ---------------- --X"B2", --72 Init wert Soll /IST A1=90Grd --72,18 --X"F1",--247499.4848 Imp/U roboter Arm --X"00",--:4 =61874 = F1B2 --X"00", --75d, -------------- --X"61", --76 Init wert Soll /IST A2=-90Grd --76,19 --X"89", --121469.1621 Imp/U roboter Arm --X"FF", --:4 =30367=-769F.. FFFF8961 --X"FF", --79d, ---------------- --X"00", --80 Init wert Soll /IST A3=0 --80,20 --X"00", --124800 Imp/U roboter Arm --X"00", --X"00", --83d, -------------------- --X"00", --84 Init wert Soll /IST A4=0 --84,21 --X"00", --7749 Imp/U roboter Arm --X"00", --X"00", --87d, ------------------------- --X"00", --88 Init wert Soll /IST A5=0 --88,22 --X"00", --71504 Imp/U roboter Arm --X"00", --X"00", --91d, -- 91d -----========Ende INit Wert Ax ==================================== ---Deformations werte im FP Format: inkr/rad --X"B3", --40678.70,inkr /rad,C_A0rad --92,23 --X"E6", --X"1E", --X"47", ---------------------------- --X"AE",--39390.68 ,inkr /rad,C_A1rad --96,24 --X"DE", --X"19", --X"47", ------------------------------ --X"C8",--19332.39 inkr /rad,C_A2rad --100,25 --X"08", --X"97", --X"46", ---------------------------------- --X"0F",--19862.53 inkr /rad,C_A3rad --104,26 --X"2D", --X"9B", --X"46", ------------------------------- --X"F6",--A4:1233.28 inkr /rad,C_A4rad --108,27 --X"28", --X"9A", --X"44", ------------------------------------- --X"D7", 11380.21 inkr /rad,C_A5rad --112,28 --X"D0", --X"31", --X"46", -----Deformations werte im FP Format: rad/inkr --X"5B",--0.00002458289 rad/inkr,C_radA0 --116,29 --X"37", --X"CE", --X"37", --------------------------------------- --X"91",--0.00002538672 rad/inkr,C_radA1 --120,30 --X"F5", --X"D4", --X"37", --------------------------------------------- --X"14", --0.00005172666 rad/inkr,C_radA2 --124,31 --X"F5", --X"58", --X"38", --------------------------------------------- --X"A9",--0.00005034605 rad/inkr,C_radA3 --128,32 --X"2A", --X"53", --X"38", ---------------------------------------------- --X"F2",--0.00081084587 rad/inkr,C_radA4 --132,33 --X"8E", --X"54", --X"3A", -------------------------------------------------- --X"D6",--0.00008787184 rad/inkr,C_radA5 --136,34 --X"47", --X"B8", --X"38", -----C_L0 bis C_L5 Armlänge für Deformation------------------- --X"00",--X"3f800000";-- 378 mm,nur nach Ref.Anfahren, C_L0, 140/35 --X"00", --X"80", --X"3f", --------------------------- --X"00",--X"43aa0000";-- 340 mm, C-L1 --X"00", --X"aa", --X"43", --------------------------- --X"00",--X"43bc0000";-- 376, C_L2 --X"00", --X"bc", --X"43", ----------------------------- --X"00",--X"43750000";-- 245 mm, Drehachse, C_L3 --X"00", --X"75", --X"43", --------------------------------- --X"00",--X"43750000";-- 245 mm,inkl Fräse, c_L4 --X"00", --X"75", --X"43", ------------------------------------ --X"00",--X"3f800000";-- 1 mm, drehachse, C_L5 --X"00", --X"80", --X"3f", 163-160/40 -------Achsen Deformation bei max Kraft Fmax in FP format, D[mm]/FSmax[N](22.25)- --X"9c",--X"3c93459c";--0.4mm/22.25=0.01797752809, C_DA0 167-164/41 --X"45", --X"93", --X"3c", ------------------------------------------------------- --X"93",--X"39eba293";--0.01mm/22.25=0.00044943820, C_DA1 --X"a2", --X"eb", --X"39", ------------------------------------------------------- --X"9c",--X"3b93459c";--0.1mm/22.25=0.00449438202, C_DA2 --X"45", --X"93", --X"3b", ------------------------------------------------------- --X"6a",--X"3c5ce86a";--0.3mm/22.25=0.01348314607, C_DA3 --X"e8", --X"5c", --X"3c", ------------------------------------------------------- --X"03",--X"3cb81703";--0.5mm/22.25=0.02247191011, C_DA4 --X"17", --X"b8", --X"3c", ------------------------------------------------------- --X"93",X"39eba293";--0.01mm/22.25=0.00044943820, C_DA5 184/46 --X"a2", --X"eb", --X"39", 187 ----- KonfigTAB Status ---------------------------------- --X"01",-- =1: = 1 :Neue Daten,sonst 0 wenn bereits gesendet,indexByte:188, index Integer /47 --X"00",-- = 00: 8 bit Bus, =01: 32 Bit buss 189 --X"00", --X"00" -- Deformation.Korrektur aktiv, = 0 Korr.inaktiv 191 --); --============================================================== SIGNAL IniPosFP :T_FP:= ( -----------------Initposition der Achsen in FP RAD nach Ref =0 ------------------------------ X"00000000",-- Achse A0 (a1 Servo),0 rad X"3FD22AD4",-- Achse A1 (a2 Servo),1.641932 rad,94.07577384 Grd X"BFC49B24",-- Achse A2 (a3 Servo),-1.5359845 rad, -88.005429248 X"BE71C064",-- Achse A3 (a4 Servo),-0.23608547 rad,-13,526701035 X"BD11B3AA",-- Achse A4 (a5 Servo),-0.03557173 rad, -2.038109999 X"00000000" -- Achse A5 (a6 servo), 0 rad ); --======================================================= BEGIN -- begin VHDL CODE --============================================================================= --********************************************************************************************** --======================================================================= RECEIV:PROCESS(clkREC) --VARIABLE AnzEbenen :INTEGER RANGE 1 TO 8;-- Aktuelle Anzahl(=BCODE(2..0) RANGE 1 to 8:=0..7 VARIABLE MaxMldgbyte :INTEGER RANGE 0 to 192:= 0;--Letzte Index einer Meldung pro Ebene VARIABLE i,j,k,m,n :INTEGER RANGE 0 to 192:= 0;--schleifen index innerhalb eine koordinate VARIABLE SatzIndex :INTEGER RANGE 0 to 7 := 0; --NC-SAtz Index beim Empfang VARIABLE ByteIndex :INTEGER RANGE 0 to 7 := 0; VARIABLE BitNr :INTEGER RANGE 0 TO 31; VARIABLE X,Y :integer;-- zwischenspeicher ---TYPE T_AxReg IS ARRAY(0 to 5) OF STD_LOGIC_VECTOR(31 DOWNTO 0);--Achsen Register Ist,Soll usw VARIABLE AxBuff :T_Axreg;-- zwischenspeicher für Ist,Soll,SiDiff --TYPE T_RefBef IS ARRAY(0 to 2) OF STD_LOGIC_VECTOR(7 DOWNTO 0); VARIABLE EndBuff :T_RefBef;-- speicher für Endlage Meldung BEGIN IF rising_edge(clkREC) THEN IF nrst = '0' THEN FOR i IN 0 TO 14 LOOP XYZSatz(i) <= X"00"; NCsatz(i) <= X"00"; rBuff(i) <= X"00"; END LOOP; FOR i IN 0 TO 3 LOOP MaxAx(i) <= X"00"; END LOOP; ----------------------------- FOR i IN 0 TO 2 LOOP STAT(i) <= X"00"; EndBuff(i) := X"00"; END LOOP; m_nobf <= '1'; m_ibf <= '0'; BCODE <= X"00"; SatzIndex := 0; recstate <= S0; MaxMldgbyte := 0; i:= 0; k:= 0; m:= 0;n:=0; flsatz <= '0';--init Satz Empfangen flkonf <= '0';-- init konfig daten empfangen -----------Init div LRK Var mit Std Werten------------------------------- RESA21 <= AxKonTAB(11);-- auflösung RESA43 <= AxKonTAB(35); RESA65 <= AxKonTAB(59); --------------------------------- KNPTXY(1) <= AxKonTAB(41)& AxKonTAB(40)& AxKonTAB(39) & AxKonTAB(38);--Knickpkt Konfig KNPKY|KNPKTX A4,A3 KNPTXY(0) <= AxKonTAB(17)& AxKonTAB(16)& AxKonTAB(15) & AxKonTAB(14);--Knickpkt Konfig KNPKY|KNPKTX A2,A1 KNPTXY(2) <= AxKonTAB(65)& AxKonTAB(64)& AxKonTAB(63) & AxKonTAB(62);--Knickpkt Konfig KNPKY|KNPKTX A6,A5 ----------------------------- KXY(0) <= AxKonTAB(21)& AxKonTAB(20)& AxKonTAB(19) & AxKonTAB(18); --KreisVerstärkung K2A2,K1A2|K2A1,K1A1 KXY(1) <= AxKonTAB(45)& AxKonTAB(44)& AxKonTAB(43) & AxKonTAB(42); --KreisVerstärkung K2A4,K1A4|K2A3,K1A3 KXY(2) <= AxKonTAB(69)& AxKonTAB(68)& AxKonTAB(67) & AxKonTAB(66); --KreisVerstärkung K2A6,K1A6|K2A5,K1A5 ----------------------- ----für Ref Anfahren------------------------- ByteIndex := 0;--index in aktuelle RefBefehl FOR i IN 0 TO 2 LOOP RefBefehl(i) <= "01000000";--Ref nicht anfahren END LOOP; FOR i IN 0 TO 2 LOOP --Reset Start Control strtCntrR(i) <= '0'; END LOOP; FOR i IN 0 TO 5 LOOP -- init AnzInt mit Werten aus KonfigTab AnzInkr(i) <= conv_integer(KonfigTab(i + 11)); --Anzahl Inkremente nach Endlage END LOOP; FOR i IN 0 TO 5 LOOP AxBuff(i) := X"00000000"; END LOOP; ---------Initialwerte nach Ref Anfahren, vorläufig-------------------------- -- XS = 500=0000001F4, YS = -200=FFFFFF38, ZS = 120=00000078 ---- -------------- XS = 370=00000172h ,YS = 000000000 ; ZS = 140= 0000008Ch-- XS <= X"000001F4";-- 500 mm , werte aus simulation: YS <= X"FFFFFF38";-- -200 mm = ZS <= X"00000078";-- 120 mm ------------------------------------------------------- ZBETR <= X"08";-- Betriebswahl(BW) default = Ref Stellung ce <= '0'; celin <= '0'; resetUpdat <= '0'; EndOut <= '1';-- keine Endlage -------------------------------------------------------------------- ELSE m_dbus <= "ZZZZZZZZ"; --------------------------------- CASE recstate IS WHEN S0 => -- warten auf nobf (Meldung vom MasterCPU) IF (m_nwr = '0') AND (m_ncs = '0') THEN -- wenn Meldung dann weiter BCODE <= m_dbus ; m_nobf <= '0'; --BCode vorhanden, meldung von master recstate <= S1; ELSE -- warten auf meldungen i:= 0; j:= 0; m:= 0; IF AXwr = '1' THEN--- AxKonREG bei PwrUP laden n := conv_integer(AXAdr); AXkonREG(n) <= AXData; END IF; ------------------- IF updatSkor = '1' THEN XS <= XA; YS <= YA; ZS <= ZA; resetUpdat <= '1'; ELSE resetUpdat <= '0'; END IF; --------------------------------------------- -- Status Setzen STAT(2)(7) <= SERVOEN;--SERVOEN-=0 Alle Sollw DAC sind init und Aktiviert STAT(1)(7) <= SERVOEN; STAT(0)(7) <= SERVOEN; --------------------------------------- --STATUS(6) <= sLimXY; --limit bits STAT(2)(6) <= '0';--sLimXY(4)OR sLimXY(5); STAT(1)(6) <= '0';--sLimXY(2)OR sLimXY(3); STAT(0)(6) <= '0';--sLimXY(0) OR sLimXY(1); ---------------------------------------- --STATUS(1..0) <= sPoser;--Poser bit sposer=0 für erreicht -- statusbits 1..0 =0 für erreicht STAT(2)(1 DOWNTO 0) <= sPoser(5 DOWNTO 4); STAT(1)(1 DOWNTO 0) <= sPoser(3 DOWNTO 2); STAT(0)(1 DOWNTO 0) <= sPoser(1 DOWNTO 0); ---------------------------- --STATUS(4)--Ref Angefahren='0' (FLRER-) STAT(0)(4) <= NOT(REFEND1 AND REFEND0); --OR (sLimXY(0)) OR (sLimXY(1)); STAT(1)(4) <= NOT(REFEND3 AND REFEND2); --OR (sLimXY(2)) OR (sLimXY(3)); STAT(2)(4) <= NOT(REFEND5 AND REFEND4); --OR (sLimXY(4)) OR (sLimXY(5)); --STATUS(3,2) <= -- Endlage FLENDY+,FLENX+ --Endlage:ZUENDs(11..0)=A6EL,A6ER,....A1EL,A1ER,für Inaktiv = 0 und Synchronisiert --Endlage(entity):ZUEND(11..0)=A6EL,A6ER,....A1EL,A1ER,für Inaktiv = 1 STAT(2)(3) <= (ZUENDS(11) OR ZUENDS(10));--A6EL, A6ER STAT(2)(2) <= (ZUENDS(9) OR ZUENDS(8));--A5EL,A5ER ------------- STAT(1)(3) <= (ZUENDS(7) OR ZUENDS(6));--A4EL,A4ER STAT(1)(2) <= (ZUENDS(5) OR ZUENDS(4));--A3EL,A3ER ------------ STAT(0)(3) <= (ZUENDS(3) OR ZUENDS(2));--A2EL,A2ER STAT(0)(2) <= (ZUENDS(1) OR ZUENDS(0));--A1EL,A1ER -- ITP-:=0 Interpolation fertig STAT(0)(5) <= ITP(0);---=Itprun & Zuramp=0 or 3 OR Poser STAT(1)(5) <= ITP(1);--- STAT(2)(5) <= ITP(2);---- -------------------------------- m_nobf <= '1'; -- init zustand m_ibf <= '0'; -- init zustand ---------------------------------------- recstate <= S0; -- warten auf Meldung END IF; -- Ablauf 8 bit bus --------------------------- WHEN S1 => --MSG einlesen (BCODE) IF m_nwr = '0' THEN BCODE <= m_dbus; recstate <= S1;-- warten bis wr fertig ELSE m_nobf <= '1'; -- init nobf recstate <= S2;-- und auswählen MSG END IF; ------MSG AUSWäHLEN,Bcode Analysieren------------------------------- WHEN S2 => CASE BCODE IS WHEN X"80"|X"A0"|X"90" => --dann NC-Satz Meldung empfangen MaxMldgbyte := 15;--Koordinaten = 1 Satz-Meldung 15 byte inkl BCODE recstate <= S3; WHEN X"8E" => --- dann kreissatz oder XYZ Satz MaxMldgbyte := 15;--Koordinaten = 1 Satz-Meldung 15-2 byte inkl BCODE recstate <= S3; WHEN X"40"|X"41"|X"42"|X"44"|X"48"|X"50" => -- dann Ref.Befehl empfangen MaxMldgbyte := 4;-- 0 te byte Speichern BCode =00 + 3 Byte NCSatz(0) <= BCODE;-- erste Byte i:= 1;-- Bcode bereits empfangen recstate <= S4; WHEN X"10" => -- MaxAx Meldung :daten Bcode + 4 byte MaxMldgbyte := 4;-- 4 i:= 0;-- Bcode bereits empfangen recstate <= S8; WHEN X"20"|X"21"|X"22"|X"23"|X"24"|X"25"|X"26"|X"27" => --dann Request Anforderung empfangen MaxMldgbyte := 0;-- recstate <= S5; WHEN X"30"|X"31"|X"32"|X"33"|X"34"|X"35"|X"36"|X"37" --request Status & Status BW |X"38"|X"39"|X"3A"|X"3B"|X"3C"|X"3D"|X"3F" => -- dann Request Anforderung empfangen mit BW ZBETR(3 DOWNTO 0) <= BCODE(3 DOWNTO 0); -- BW Speichern BCODE(3 DOWNTO 0) <= "0000";--und BW entfernen recstate <= S5; WHEN X"02" => --BCODE=02 dann KonfigSatz von CPU Empfangen MaxMldgbyte := 72;-- 3 x 24 =72 byte recstate <= S7; WHEN OTHERS => MaxMldgbyte := 0;-- 1 byte recstate <= S9;-- EXIT (RECE9) END CASE; --==============MSG Ausführen=========================================== -----------------BCODE= 1xxxxxxx------------------------------------- -- Ablauf NC Satz Empfang inkl BCODE -- Empfang der NC Sätze solangbis MAXAX Meldung kommt -- MaxMldgbyte := 15 WHEN S3 => --BCODE + NC-Satz Meldung i := 0; -- Byte Index j:= 0; IF BCODE(6) = '1' THEN -- IF XYZ SAtz XYZSatz(0) <= BCODE;-- BCODE auf Adr0 Speichern recstate <= S30;-- XYZ Satz Empfangen i := i + 1;--Byte Index inkrementieren ELSE NCSatz(0) <= BCODE;-- BCODE auf Adr0 Speichern recstate <= S300;-- testen auf Kreisatz = Ersatz für XYZ satz, oder LinSatz i := i + 1;--Byte Index inkrementieren END IF; ---===================================================== ---XYZSatz :T_SatzBuff;-- NC SAtz Speicher (0..15) --0 15--- --C0,03,00,00,XX,XX,XX,XX,YY,YY,YY,YY,ZZ,ZZ,ZZ,ZZ--- ---XYZ Satz ohne angehängte MAXAX bytes WHEN S30 => --LOOP koord holen für interpolator (NC Satz) IF (m_nwr = '0') AND (m_ncs = '0') THEN m_nobf <= '0'; -- neue Meldungsbyte da recstate <= S31; -- dan weiter ELSE -- m_nrd ='0' m_nobf <= '1'; -- init zustand m_ibf <= '0'; recstate <= S30;-- warten auf nächste Byte END IF; WHEN S31 => IF m_nwr = '0' THEN XYZSatz(i) <= m_dbus; -- Byte Speichern recstate <= S31;-- Warten bis wr fetig ELSE recstate <= S33; END IF; WHEN S33 => IF i < MaxMldgbyte - 1 THEN -- alle Koordinaten gespeichert i := i + 1; -- index inkrem recstate <= S30;--und nächste KoordByte holen ELSE recstate <= S34;-- dann fertig beenden END IF;-- loop Ende WHEN S34 => -- XYZSatz für Interpolator wurde fertig empfangen i := 0;-- init schleifen index --------------------------------------------------------------- -- Xt=-200,YT=500,ZT=-170: aus As21_test XT <= XYZsatz(7) & XYZsatz(6) & XYZsatz(5) & XYZsatz(4);-- Target Koordinaten,relativ YT <= XYZsatz(11) & XYZsatz(10) & XYZsatz(9) & XYZsatz(8);--"" ZT <= XYZsatz(15) & XYZsatz(14) & XYZsatz(13) & XYZsatz(12);--"" ---------------------------------------------- ce <= '1'; -- start für ITP Modul recstate <= S37; WHEN S37 => ce <= '0';-- reset CE recstate <= S312;-- zu Ende mit Verzögerung --=========================================================== ----------Empfang für NCsatz ------------------- --Kreissatz: 8E,00,F7,X,X,X,Y,Y,Y,U,U,U,V,V,V--- --XYZ satz C0,03,00,00,XX,XX,XX,XX,YY,YY,YY,YY,ZZ,ZZ,ZZ,ZZ--- ---XYZSatz :T_SatzBuff;-- NC SAtz Speicher (0..15) --MaxMldgbyte := 15 -1 = 14 WHEN S300 => --LOOP koord holen für interpolator (NC Satz) IF (m_nwr = '0') AND (m_ncs = '0') THEN m_nobf <= '0'; -- neue Meldungsbyte da recstate <= S301;-- und weiter ELSE -- m_nrd ='0' m_nobf <= '1'; -- init zustand recstate <= S300;-- warten auf neue Byte END IF; WHEN S301 => IF m_nwr = '0' THEN NCSatz(i) <= m_dbus; -- Byte Speichern recstate <= S301;-- Warten bis RD fetig ELSE m_nobf <= '1'; -- reset nobf recstate <= S303; END IF; WHEN S303 =>-- total mit BCODE 15 Byte, IF i < MaxMldgbyte - 1 THEN -- alle NCKoordinaten gespeichert i := i + 1; -- index inkrem recstate <= S300;--und nächste KoordByte holen ELSE -- Satz fertig Empfangen => NCSatz i := 0; MaxMldgbyte := 4;--4 recstate <= S304;-- und zu MaxAX Empfang END IF; ---- Empfang von MaXAX ---------------------- -------------MaxMldgbyte := 4;-------------------------------------- WHEN S304 => -- MAXAX empfangen IF (m_nwr = '0') AND (m_ncs = '0') THEN m_nobf <= '0'; -- BCODE ist da recstate <= S307;-- und weiter ELSE -- m_nrd ='0' m_nobf <= '1'; -- init zustand recstate <= S304;-- warten END IF; WHEN S307 => -- IF m_nwr = '0' THEN MAXAX(i) <= m_dbus; -- Byte Speichern recstate <= S307;-- Warten bis wr fertig ELSE m_nobf <= '1'; -- reset nobf IF i < MaxMldgbyte - 1 THEN i:= i + 1; recstate <= S304;-- und wiederholen für Anzahl Bytes ELSE recstate <= S0;-- und fertig empfang maxax Daten --- nach S0 warten auf Meldung 10 MAXAX END IF; END IF; --------------------------------------------- --=========================================================== --=========================================================================== --- Empfang für MAXAX Meldung, BCODE = 10 -----MaxMldgbyte := 4; ----- i:= 0;-- Bcode bereits empfangen ------------------------------------------------ WHEN S8 => -- bcode bereits empfangen IF (m_nwr = '0') AND (m_ncs = '0') THEN m_nobf <= '0'; -- neue byte ist da recstate <= S81;-- und weiter ELSE -- m_nrd ='0' m_nobf <= '1'; -- init zustand recstate <= S8;-- warten END IF; WHEN S81 => -- IF m_nwr = '0' THEN MAXAX(i) <= m_dbus; -- Byte Speichern recstate <= S81;-- Warten bis wr fertig ELSE m_nobf <= '1'; -- reset nobf IF i < MaxMldgbyte - 1 THEN i:= i + 1; recstate <= S8;-- und wiederholen für Anzahl Bytes ELSE m_nobf <= '1'; -- reset nobf recstate <= S82;-- und fertig END IF; END IF;--- fertig empfang maxax meldung WHEN S82 => --immer nach lin oder Kreissatz recstate <= S308; ---=============================================================== --------------------------------------------- WHEN S308 => --auswerten Kreisatz oder LinSatz ************************ IF NCSatz(2)(2 DOWNTO 0) = "111" THEN recstate <= S309;-- Dann kreisSatz=> in XYZ Umwandeln ELSE recstate <= S320;-- Dann LIN Satz END IF; ------------------------------------------------- ---------------- KREISSATZ Ausführung ------------------------------ --Kreissatz: 8E,00,F7,X,X,X,Y,Y,Y,U,U,U,V,V,V--- --XYZ satz C0,03,00,00,XX,XX,XX,XX,YY,YY,YY,YY,ZZ,ZZ,ZZ,ZZ--- WHEN S309 => -- if Kreis Satz dann in XYZ umwandeln XYZSatz(0)<= X"80";-- NC Satz XYZSatz(1)<= X"03";-- Anzahl Ebenen = 3 XYZSatz(2)<= X"00"; XYZSatz(3)<= X"00"; -------------------- XYZSatz(4)<= NCSatz(3); XYZSatz(5)<= NCSatz(4); XYZSatz(6)<= NCSatz(5); IF NCSatz(5)(7) = '0' THEN --Extension auf 4 Byte XYZSATZ(7)<= X"00"; ELSE XYZSATZ(7)<= X"FF"; END IF; XYZSatz(8)<= NCSatz(6); XYZSatz(9)<= NCSatz(7); XYZSatz(10)<= NCSatz(8); IF NCSatz(8)(7) = '0' THEN --Extension auf 4 Byte XYZSATZ(11)<= X"00"; ELSE XYZSATZ(11)<= X"FF"; END IF; XYZSatz(12)<= NCSatz(9); XYZSatz(13)<= NCSatz(10); XYZSatz(14)<= NCSatz(11); IF NCSatz(11)(7) = '0' THEN --Extension auf 4 Byte XYZSATZ(15)<= X"00"; ELSE XYZSATZ(15)<= X"FF"; END IF; recstate <= S310;-- dann start für ITP ----------------------------------------------------- WHEN S310 => ---- XYSatz koordinaten auf ITP mOdul senden--------- -- Xt=-200,YT=500,ZT=-170: aus As21_test XT <= XYZsatz(7) & XYZsatz(6) & XYZsatz(5) & XYZsatz(4);-- Target Koordinaten,relativ YT <= XYZsatz(11) & XYZsatz(10) & XYZsatz(9) & XYZsatz(8);--"" ZT <= XYZsatz(15) & XYZsatz(14) & XYZsatz(13) & XYZsatz(12);--"" ---------------------------------------------- ce <= '1'; -- start für ITP Modul recstate <= S311; WHEN S311 => ce <= '0';-- reset CE recstate <= S0;-- und Ende mit Verzögerung ------------------------------------------------ ----=============================================== --======Kreissatz + MaxAx Empfangen und itp Modul gestartet==== --==================Ende Kreissatz ausführen ============================= --========LINSATZ Aufbereiten ********************************************************* -- 10xy0000,2x,00,XX,XX,XX,YY,YY,YY,00,00,00,00,00,00 --======= IEbene : NCsatz(1) bits 2..0-------------------------------- --=======Daten Aufbereiten für LinSatz Ebene 0..2= satz A1.. A6 =============== WHEN S320 => --Linear satz im NCSatz IF NCSatz(0)(4) = '0' THEN --if X aktiv Xactiv <= '1'; Xlin(7 DOWNTO 0) <= NCSatz(3); Xlin(15 DOWNTO 8) <= NCSatz(4); ELSE Xactiv <= '0'; Xlin <= X"0000"; END IF; ---------------------------------- IF NCSatz(0)(5) = '0' THEN --if Y aktiv Yactiv <= '1'; Ylin(7 DOWNTO 0) <= NCSatz(6); Ylin(15 DOWNTO 8) <= NCSatz(7); ELSE Yactiv <= '0'; Ylin <= X"0000"; END IF; -------------------------------- Iebene <= NCSatz(1)(3 DOWNTO 0); -- Interpolation Ebene setzen(SLV) ---------------------------------- LinLk(7 DOWNTO 0) <= MaxAx(0);-- Leitkoordinate für lin LinLk(15 DOWNTO 8) <= MaxAx(1); LinLk(23 DOWNTO 16) <= MaxAx(2); LinLk(31 DOWNTO 24) <= MaxAx(3); recstate <= S321;-- dann weiter WHEN S321 => --LinEbene <= NCSatz(1)(2 DOWNTO 0);--LinsatzEbene Speichern celin <= '1'; --start für Modul IniLinITP m_nobf <= '1'; -- reset recstate <= S322; WHEN S322 => celin <= '0'; --start für Modul LinITP reset recstate <= S0;-- Ende NCsatz Lin Empfang ------------------------------------------------------------------------- ----=============Referenz Befehl======BCODE = 010xxxxx======================================= ---- Bcode = 05H ---- Byte1 = 00 ---- Byte2 = 00 -----Byte3=Ebene0,Byte4=Ebene1,Byte5=Ebene2, -- Ref. Befehl : 010x_xxxx, -------------------- : 0101_0000 :X + Y anfahren 50H -------------------- 0100_1000 :Y vor X Anfahren:48h -------------------- 0100_0100 :X vor Y Anfahren:44h -------------------- 0100_0010 :Y allein Anfahren:42 -------------------- 0100_0001 :X allein Anfahren:41 ----------------------- 0100_0000 :keine referenz aber Flag REf setzen = 40 ----------------------------------------------------------- -------Referenz Anfahren gemäss AxKonTab VREF,VORINDX,REFDIR------- ---Signale RefBefehl(2..0)of stdLV(7..0) -- StrtCntrR(0..2) of SL : start Control Ref Processe in jeweilige Ebene -- stateref0...stateref5 ---TYPE T_NCSatz IS ARRAY(0 TO 15) OF STD_LOGIC_VECTOR(7 DOWNTO 0);-- NC Satz Speicher -- Signale AnzInkr(5..0) of Integer 32bit -- Var ByteIndx : Byte Nr aus RefBefehl WHEN S4 => IF (m_nwr = '0') AND (m_ncs = '0') THEN m_nobf <= '0'; -- neue Meldungsbyte da recstate <= S41; -- dan weiter ELSE -- m_nrd ='0' m_nobf <= '1'; -- init zustand m_ibf <= '0'; recstate <= S4;-- warten auf nächste Byte END IF; WHEN S41 => IF m_nwr = '0' THEN NCSatz(i) <= m_dbus; -- Byte Speichern recstate <= S41;-- Warten bis wr fetig ELSE IF i < 2 THEN i := i + 1; recstate <= S4;-- dann repeat für alle Byte ELSE -- MSG empfang fertig, weiter zum flag setzen i := 0;-- Erste Ref Befehl,Ebene 0 =i + 3 strtCntrR(0) <= '0';-- init StartFlag für cntr processe strtCntrR(1) <= '0'; strtCntrR(2) <= '0'; recstate <= S42;-- Ref MSG ist in NCSatz END IF; END IF; WHEN S42 => ----Empfang ist Fertig,Ref Befehl speichern und flag setzen IF i < 3 THEN --- Ref Befehl sind in Adr 3..5= Ebene0..2 RefBefehl(i) <= NCSatz(i);-- start für Refcntr 0..2 strtCntrR(i) <= '1'; recstate <= S43; -- und Repeat für Ebene 0..2 ELSE strtCntrR(0) <= '0';-- init StartFlag für cntr processe strtCntrR(1) <= '0'; strtCntrR(2) <= '0'; recstate <= S9;-- REF Befehl Vorbereitet, und exit END IF; WHEN S43 => i:=i + 1; recstate <= S42; --============== ref Befehl Empfang fertig ============================================ --=========================================================================================== ----=============REQUEST Ausführung===================================================== -- bis da bereits ein BCODE empfangen -- BCODE = 0010 0000 = Status Byte, für 3 Ebenen zuerst 3x Bcode, dann 1 Byte /Ebene -- BCODE = 0011 0000 = Status Byte, für 3 Ebenen, mit Betriebswahl = Bit 3..0 -- 0010 0001 = Istwert für 3 Ebenen zuerst 3x Bcode, danach 6 Byte /Ebene -- 0010 = Endlage für 3 Ebenen zuerst 3x Bcode, danach 1 Byte/Ebene -- 0011 = Schleppfehler nur 1 Testebene(1x BCODE) , danach 6 Byte -- 0100 = Sollwert für 3 Ebenen zuerst 3x Bcode, danach 6 Byte /Ebene -- 0101 = ZUINP nur 1 Ebene gemäss P Ardesse, danach 1 Byte -- 0110 = Konfigreg ab FLASH uP8051 1+24+ 1 + 24 + 1 + 24 -- 0111 = Konfigreg ab FPGA 1+24+ 1 + 24 + 1 + 24 ----------------------------------------------------------------- ---------------- REQUEST 1.Bcode wurde bereits empfangen, mwr=1 ist der jetztige zusrand ----- WHEN S5 => -- REQUEST DATEN vom AS 21 , quasi wenn As Karten angewählt werden IF BCODE(7 DOWNTO 4)="0010" OR BCODE(7 DOWNTO 4)="0011" THEN ---- oder andere Request ---------------------------------------- CASE BCODE(3 DOWNTO 0) IS WHEN "0000" => recstate <= S52;-- STATUS,warten auf 2. un3. BCODE WHEN "0001" => recstate <= S52;-- ISTWERT----""---------------- WHEN "0010" => recstate <= S52;-- ENDLAGE--""------ WHEN "0011" => recstate <= S550;--SCHLEPPFEHLER, nur 1 BCODE WHEN "0100" => recstate <= S52;-- SOLLWERT,warten auf 2. un3. BCODE WHEN "0101" => recstate <= S550;--EBENESTATUS nur 1 BCODE WHEN OTHERS => recstate <= S550;-- 1.Bcode und Message:Konfig.. END CASE; m_ibf <= '0'; END IF; ------------------------------------------------------------- -- CASE BCODE IS -- WHEN X"20" => recstate <= S52;-- STATUS,warten auf 2. un3. BCODE -- WHEN X"30" => recstate <= S52;-- BWSTATUS,warten auf 2. un3. BCODE -- WHEN X"21" => recstate <= S52;-- ISTWERT----""---------------- -- WHEN X"22" => recstate <= S52;-- ENDLAGE--""------ -- WHEN X"23" => recstate <= S550;--SCHLEPPFEHLER, nur 1 BCODE -- WHEN X"24" => recstate <= S52;-- SOLLWERT,warten auf 2. un3. BCODE -- WHEN X"25" => recstate <= S550;--EBENESTATUS nur 1 BCODE -- WHEN OTHERS => recstate <= S0;-- -- END CASE; --========= Empfang von 2. und 3. BCODE -------- WHEN S52 => --warten auf 2 te BCODE IF (m_nwr = '0') AND (m_ncs = '0') THEN m_nobf <= '0'; -- Byte da recstate <= S53; ELSE -- , 2-te BCODE m_nobf <= '1'; -- init zustand m_ibf <= '0'; recstate <= S52;-- warten auf 2-te BCODE END IF; WHEN S53 => IF m_nwr = '0' THEN rBuff(0) <= m_dbus;-- allg speicher recstate <= S53; -- warten so lang WR aktiv ELSE recstate <= S55;-- 2. bcode empfangen END IF; WHEN S55 => --warten auf 3 te BCODE IF (m_nwr = '0') AND (m_ncs = '0') THEN m_nobf <= '0'; -- Byte da recstate <= S56; ELSE -- m_nobf <= '1'; -- init zustand recstate <= S55;--warten auf 3-te BCODE END IF; WHEN S56 => IF m_nwr = '0' THEN rBuff(1) <= m_dbus;-- allg speicher recstate <= S56; -- warten bis wr vorbei ELSE m_nobf <= '1'; -- init nobf recstate <= S5501;-- 3. bcode empfangen, warten für OBF zeit END IF; --=========== 2. un 3. Bcode fertig empfangen ,mnwr =1 --============================================= -- Request 1. Bcode bereits empfangen,, mnwr=1 WHEN S550 => -- m_nobf <= '1'; -- init nobf recstate <= S5501;-- warten für OBF zeit --------======================================================= -------------------------------------------------------------- ----BCODEclk:(0..2047) := 720 -----recclk T = 40 ns (25 MHz), 30 x 40ns = 1.2 uS WHEN S5501 => m_nobf <= '0'; -- init nobf AnzClk <= 157;-- dauer für m_obf 6.2 us --AnzClk <= BCODEclk;-- dauer für m_obf 29 us recstate <= S5502;-- und warten WHEN S5502 => IF AnzClk > 0 THEN AnzClk <= AnzClk - 1; recstate <= S5502;--warten nach obf für ibf ELSE m_nobf <= '1'; -- init zustand AnzClk <= 2;-- 0.2 us AnzClk <= 250;-- 11.4 us recstate <= S5503;--Warte Zeit fertig,warten auf rd von Master END IF; WHEN S5503 => IF AnzClk > 0 THEN AnzClk <= AnzClk - 1; recstate <= S5503;--warten nach obf für ibf ELSE recstate <= S57;--Warte Zeit fertig,warten auf rd von Master END IF; -----------------------Sendeteil Daten von AS21 an Master(cpu16.1)-------------------------- WHEN S57 => --(MLDTAB), ---******Für Request 20,21,22,24 wurde BCODE bereits 3x Emppfangen ********* CASE BCODE(3 DOWNTO 0) IS -- Daten zurück an CPU senden WHEN "0000" => -- STATUS 1 Byte /Ebene,** BCODE 3x bereits empfangen recstate <= S520; -- Senden Status an CPU,RDSTAT 2142(OEM01) WHEN "0001" => -- ISTWERT 8 Byte/Ebene,**BCODE 3x bereits empfangen --RegNrRd <= 2;-- Start RD Istwert Reg,GETPOS 1827 (OEM01) RECSTATE <= S521; WHEN "0010" => -- ENDLAGE+INDX 1 Byte /EBENE: INPZU, RDEND,2179 (OEM01) RECSTATE <= S522;--*******************BCODE 3x bereits empfangen WHEN "0011" => -- SCHLEPPFEHLER 6 Byte/EBENE, nur Eine Ebene (test Ebene) --RegNrRd <= 3;-- Start RD SiDIFF Reg RECSTATE <= S523; WHEN "0100" => -- SOLLWERT 8Byte/Ebene ,AXSOL,2008,(OEM01) --RegNrRd <= 1;--Start RD Sollwert Reg RECSTATE <= S524;--*********************BCODE 3x bereits empfangen WHEN "0101" => -- ZUINP Zustand 1 Byte /EBENE RECSTATE <= S525;-- Request für nur eine Ebene,ITPEB 2248(OEM01) ----------------------------------------- WHEN "0110" => --Request 26, KONFIGTABELLE(AxKonTAB) in AS21/FPGA Register(AxKonREG) kopieren -- und an Master senden 24 Byte/Ebene RECSTATE <= S526;-- Request für jeder Ebene, nicht voraus!!!IAXKON,2624(OEM00) WHEN "0111" => --Request 27, KONFIG Werte ab AS21/FPGA Register (AxKonREG) -- an master senden 24 Byte/Ebene RECSTATE <= S527;-- Request für jeder Ebene, nicht voraus!!!IAXKON,2624(OEM00) ----------------------------------------------- -- WHEN "1000" => -- SOLLWERTINKREMENT X&Y 4 Byte/Ebene -- RECSTATE <= S528; WHEN OTHERS => recstate <= S9;-- EXIT END CASE; --================================================================== ------------Signal STATUS :T_STAT IS ARRAY(0 to 2) OF STD_LOGIC_VECTOR(7 DOWNTO 0); ----========STATUS : ======================= --Byte2--------------- 7 6 5 4 3 2 1 0 --Byte1--------------- 7 6 5 4 3 2 1 0 --Byte0--------------- 7 6 5 4 3 2 1 0 ---- Statusbyte: SVEN-, Fllim+,ITP-, FlRER-, FLENDY+.FLENDX+,POSEY-,POSEX- -- RES(31 Downto 0): 31..24=X"00*, -- 23..16 =AxkonTAB(59) -- 15..8 =AxkonTAB(35) -- 7..0 =AxkonTAB(11) ---------------------------------------------------------------------------------------- WHEN S520 => -- Senden Status an CPU (1 Byte Ebene= 3Byte) -- Status Setzen STAT(2)(7) <= SERVOEN;--SERVOEN-=0 Alle Sollw DAC sind init und Aktiviert STAT(1)(7) <= SERVOEN; STAT(0)(7) <= SERVOEN; --------------------------------------- --STATUS(6) <= sLimXY; --limit bits STAT(2)(6) <= '0'; --sLimXY(4)OR sLimXY(5); STAT(1)(6) <= '0'; --sLimXY(2)OR sLimXY(3); STAT(0)(6) <= '0'; --sLimXY(0) OR sLimXY(1); ---------------------------------------- --STATUS(1..0) <= sPoser;--Poser bit sposer=0 für erreicht -- statusbits 1..0 =0 für erreicht STAT(2)(1 DOWNTO 0) <= sPoser(5 DOWNTO 4); STAT(1)(1 DOWNTO 0) <= sPoser(3 DOWNTO 2); STAT(0)(1 DOWNTO 0) <= sPoser(1 DOWNTO 0); ---------------------------- --STATUS(4)--Ref Angefahren='0' (FLRER-) STAT(0)(4) <= NOT(REFEND1 AND REFEND0); --OR (sLimXY(0)) OR (sLimXY(1)); STAT(1)(4) <= NOT(REFEND3 AND REFEND2); --OR (sLimXY(2)) OR (sLimXY(3)); STAT(2)(4) <= NOT(REFEND5 AND REFEND4); --OR (sLimXY(4)) OR (sLimXY(5)); --STATUS(3,2) <= -- Endlage FLENDY+,FLENX+ --Endlage:ZUENDs(11..0)=A6EL,A6ER,....A1EL,A1ER,für Inaktiv = 0 und Synchronisiert --Endlage(entity):ZUEND(11..0)=A6EL,A6ER,....A1EL,A1ER,für Inaktiv = 1 STAT(2)(3) <= (ZUENDS(11) OR ZUENDS(10));--A6EL, A6ER STAT(2)(2) <= (ZUENDS(9) OR ZUENDS(8));--A5EL,A5ER ------------- STAT(1)(3) <= (ZUENDS(7) OR ZUENDS(6));--A4EL,A4ER STAT(1)(2) <= (ZUENDS(5) OR ZUENDS(4));--A3EL,A3ER ------------ STAT(0)(3) <= (ZUENDS(3) OR ZUENDS(2));--A2EL,A2ER STAT(0)(2) <= (ZUENDS(1) OR ZUENDS(0));--A1EL,A1ER -- ITP-:=0 Interpolation fertig STAT(0)(5) <= ITP(0);---=Itprun & Zuramp=0 or 3 OR Poser STAT(1)(5) <= ITP(1);--- STAT(2)(5) <= ITP(2);---- -------------------------------- i := 0; -- soll Ebene Nr RECSTATE <= S5205; ---------------------------------------------------------------------- WHEN S5205 => -- loop, warten auf Ebene funktioniert nicht, blockiert ablauf IF (STAT(0)(3) OR STAT(1)(3) OR STAT(2)(3) OR STAT(0)(2) OR STAT(1)(2) OR STAT(2)(2) ) = '1' THEN EndOut <= '0'; -- irgendeine endlage aktiv END- ELSE EndOut <= '1';-- keine Endlage END IF; m_ibf <= '1'; -- slave wr, byte zum abholen ist da recstate <= S5207; WHEN S5207 => IF m_nrd = '0' AND m_ncs = '0' THEN--- If Master rd m_dbus <= STAT(i)(7 DOWNTO 0);-- eine Status Byte senden m_ibf <= '0'; -- init zustand recstate <= S5209; ELSE recstate <= S5207;-- Warten bis Master rd & CS aktiv END IF; WHEN S5209 => IF m_nrd = '0' THEN m_dbus <= STAT(i)(7 DOWNTO 0);-- eine Status Byte senden --m_dbus <= STAT(i);--Status Byte bereit recstate <= S5209;-- Warten bis RD fertig ELSE IF i < 2 THEN i := i + 1;-- --AnzClk <= 30; -- 1 us warten --AnzClk <= 200;-- 1 us warten recstate <= S5205;-- und repeat ELSE recstate <= S9; END IF; END IF; --========ISTWERT =======Atuelle Istwert im Reg IST(6 x 3 Byte von 32bit)============ --- REQUEST(21) VORAUS für alle Ebenen ----IST :T_AxReg IS ARRAY(0 to 5) OF STD_LOGIC_VECTOR(31 DOWNTO 0) --- AxBuff:T_AxReg : ist Variable zum zwischenspeichen von IST WHEN S521 => -- BCODE wurdev bereits 3x Empfangen i := 0;-- Reg NR j := 0; --Ebene NR BitNr := 0; FOR k IN 0 TO 5 LOOP -- aktuelle zustand von Ist speichern AxBuff(k) := IST(k);--Istwert Zwischenspeichern END LOOP; recstate <= S5210; ---- loop------------------ WHEN S5210 => m_ibf <= '1'; -- slave wr, byte zum abholen ist da ----------------- recstate <= S5212; WHEN S5212 =>-- ebene 0 IF m_nrd = '0' AND m_ncs = '0' THEN--- If Master rd m_ibf <= '0'; -- init zustand recstate <= S5213; ELSE recstate <= S5212;-- Warten bis Master rd END IF; WHEN S5213 => IF m_nrd = '0' THEN m_dbus <= AxBuff(i)((BitNr + 7) DOWNTO BitNr); recstate <= S5213;-- Warten bis RD fertig ELSE m_ibf <= '0'; -- ruhezustand, byte gelesen IF BitNr < 15 THEN BitNr := BitNr + 8; recstate <= S5210;-- und wiederholen für 3 Byte ELSE BitNr := 0; IF i < 5 THEN i:= i + 1;-- nächste Register j:= i / 2;-- nächste Ebene recstate <= S5210; ---- ende LOOP-------------- ELSE recstate <= S9; --dann Istwert Meldung Fertig END IF; END IF; END IF; --====Request 22H ====ENDLAGE und INDEX ZUstand senden= ZUEND an Master=================== ---ZUENDs( 1 Byte /Ebene) =Index(A6..A1) aus ENCOD Input (A6i....A1i)= für Endlage inaktiv = 0 --Aus Entity ZUEnd(11..0): A6L,A6R,.......A1L,A1R =für Endlage inaktiv =1 -- Pro Ebene:,--.XIND+,YInd+,--,YLEND+,YREND+,XLEND+,YREND+, --Bei Roboter gibt es keine REF schalter --------------------------= ENDLAGE(A6..A1) aus ZUEND Input ----- BCODE wurdev bereits 3x Empfangen WHEN s522 => -- ENDLAGE 3 Byte InpZU= vorherige ZuEND x 3 FOR i in 0 TO 2 LOOP --endlage speichern, konstant bleiben während MLDG EndBuff(i) := '0' & Encods((i*6)+2) & Encods((i*6)+5) & '0' & ZuEnds(((i*4)+3) Downto (i*4)); END LOOP; recstate <= S5220; WHEN S5220 => i := 0;-- Reg NR = Ebene recstate <= S5221;-- start LOOP WHEN S5221 => --loop --IF i = conv_integer(ebene) THEN --wenn Ebene Nr richtig,funktioniert nicht m_ibf <= '1'; -- slave wr, byte zum abholen ist da recstate <= S5222; --ELSE --recstate <= S5220; --END IF; WHEN S5222 => IF m_nrd = '0' AND m_ncs = '0' THEN--- If Master rd m_dbus <= EndBuff(i); m_ibf <= '0'; recstate <= S5223; ELSE recstate <= S5222;-- Warten bis Master rd END IF; WHEN S5223 => IF m_nrd = '0' THEN m_dbus <= EndBuff(i); recstate <= S5223;-- Warten bis RD fertig ELSE IF i < 2 THEN i := i + 1; recstate <= S5221;-- und repeat ELSE recstate <= S9; END IF; END IF; ----------------------------------------------------------------------------- --==== Request 23H ==== Schleppfehler senden gem. Ebene an Master ============== -- P10_13 = TestInp Eingang TopEntity, wird von der TestBench gesendet (0..2) -- meldung an Master Schleppfehler 2x 3 Byte in gegebene Ebene -- Speicher SIDIFF : T_AxReg --TYPE T_AxReg IS ARRAY(0 to 5) OF STD_LOGIC_VECTOR(31 DOWNTO 0);--Achsen Register Ist,Soll usw --- AxBuff:T_AxReg : ist Variable zum zwischenspeichen von SIDiff --========Schleppfehler =======Atuelle Reg SIDiff(6 x 24bit(32 bit))============ WHEN s523 => -- SCHLEPPFEHLER 6 Byte/EBENE FOR k IN 0 TO 5 LOOP -- aktuelle zustand von SIDiff speichern AxBuff(k) := SIDIFF(k);--SIDiff Zwischenspeichern END LOOP; i := conv_integer(ebene);-- Ebene Nr j := i * 2;-- Register Nr (0..5) BitNr := 0;-- innerhalb des 32 bit Registers (3..0) recstate <= S5231; ------- LOOP------------------------------- WHEN S5231 => m_ibf <= '1'; -- slave wr recstate <= S5232;-- dann nächste Byte WHEN S5232 => IF m_nrd = '0' AND m_ncs = '0' THEN--- If Master rd m_ibf <= '0'; -- init zustand recstate <= S5233; ELSE recstate <= S5232;-- Warten bis Master rd END IF; WHEN S5233 => IF m_nrd = '0' THEN m_dbus <= AxBuff(j)((BitNr + 7) DOWNTO BitNr);-- senden recstate <= S5233;-- Warten bis RD fertig ELSE IF BitNr < 16 THEN BitNr := BitNr + 8;-- der nächste Byte recstate <= S5231;-- und wiederholen für 3 Byte ELSE BitNr := 0; IF j < i*2+1 THEN j:= j + 1;-- nächste Register recstate <= S5231; ------ Ende Loop------------------------------- ELSE recstate <= S9; --dann Istwert Meldung Fertig END IF; END IF; END IF; ----------------------------------------------------------------------- --==== Request 24H ========== Sollwert senden a Master ============= --========SOLLWERT =======Atuelle Sollwert im Reg SOLL(6 x 24(32 bit))============ -- BCODE wurde bereits 3x Empfangen WHEN S524 => -- SOLLWERT 6Byte/Ebene FOR k IN 0 TO 5 LOOP -- aktuelle zustand von SOLL speichern AxBuff(k) := SOLL(k);--SOLL Zwischenspeichern END LOOP; i := 0;-- Reg NR j := 0;-- Ebene Nr BitNr := 0; recstate <= S5240; ------ LOOP--------------------------------------- WHEN S5240 => --IF j = conv_integer(ebene) THEN --wenn Ebene Nr richtig m_ibf <= '1'; -- slave wr, byte zum abholen ist da recstate <= S5242; --ELSE --recstate <= S5240;-- warten auf Ebene --END IF; WHEN S5242 =>-- ebene 0 IF m_nrd = '0' AND m_ncs = '0' THEN--- If Master rd m_ibf <= '0'; -- init zustand recstate <= S5243; ELSE recstate <= S5242;-- Warten bis Master rd END IF; WHEN S5243 => IF m_nrd = '0' THEN m_dbus <= AxBuff(i)((BitNr + 7) DOWNTO BitNr);--und senden recstate <= S5243;-- Warten bis RD fertig ELSE m_ibf <= '0'; -- ruhezustand, byte gelesen IF BitNr < 15 THEN BitNr := BitNr + 8; recstate <= S5240;-- und wiederholen für 3 Byte ELSE BitNr := 0; IF i < 5 THEN i:= i + 1;-- nächste Register j:= i / 2;-- nächste Ebene recstate <= S5240; ------------- LOOP END---------------------- ELSE recstate <= S9; --dann Istwert Meldung Fertig END IF; END IF; END IF; --===================================================================== ----Request 25H------ZUINP Senden---ENDEB OEM01 2230 --- vorläufig gibt es keine ZUINP bei Entity, es wird 0 gesendet wg CPU16.1 Programm ---- bei Opti :,-,-,-, STOP+,FFSTPX,FLSTPY,-,-, : vorläufig 0 senden ------ZUINP Senden (Request 25),1 Byte vorläufig wird Status der Ebene gesendet ----- BCODE wurdev bereits 1 Empfangen, vorläufig wirf Status der Ebene gesendet WHEN s525 => -- ENDLAGE 1 Byte InpZU= i := conv_integer(ebene); recstate <= S5250; WHEN S5250 => --IF i = conv_integer(ebene) THEN --wenn Ebene Nr richtig m_ibf <= '1'; -- slave wr, byte zum abholen ist da recstate <= S5252; --ELSE --recstate <= S5250; --END IF; WHEN S5252 => IF m_nrd = '0' AND m_ncs = '0' THEN--- If Master rd m_ibf <= '0'; -- init zustand recstate <= S5253; ELSE recstate <= S5252;-- Warten bis Master rd END IF; WHEN S5253 => IF m_nrd = '0' THEN m_dbus <= X"00";-- keine Angaben recstate <= S5253;-- Warten bis RD fertig ELSE recstate <= S9; END IF; --====================================================================== -----Request 26H, Konfigtabelle ab InitTabelle FPGA :AXKonTab in FPGA Register kopieren --- und an Master senden -- Erste Meldung nach CPU memory fail : --- entspricht ASMProgramm IAXKON aus OEM00 für CPU16.1 --============================================================================= WHEN S526 => i := 0;-- Reg NR j:= 0; -- ebene Nr m := 0;-- Tabellen Adresse recstate <= S5260; WHEN S5260 => -- loop IF j = conv_integer(ebene) THEN --wenn Ebene Nr richtig m_ibf <= '1'; -- slave wr, byte zum abholen ist da recstate <= S5262; ELSE recstate <= S5260;-- warten auf Ebene END IF; WHEN S5262 => --warten bis Master gelesen hat IF m_nrd = '0' AND m_ncs = '0' THEN--- If Master rd m_ibf <= '0'; -- master rd, Daten Abgeholt ibf:=0 m_dbus <= AxKonTab(m);-- Tabellen Wert senden recstate <= S5263; ELSE recstate <= S5262;-- Warten bis Master rd aktiv END IF; WHEN S5263 => --warten auf Master rd fertig gelesen IF m_nrd = '0' THEN m_dbus <= AxKonTab(m); recstate <= S5263;-- Warten bis RD fertig ELSE -- master RD inaktiv m_ibf <= '0'; -- reset IBF IF i < 23 THEN i := i + 1; m := m + 1; recstate <= S5260;-- und repeat ELSE --eine Ebene Fertig IF m < 71 THEN m := m + 1; j:= j + 1;--die nächste Ebene recstate <= S5264; -- dann nächste Ebene ELSE recstate <= S5267; -- dann alle Block fertig END IF; m_ibf <= '0'; -- reset IBF END IF; END IF; WHEN S5264 => -- warten auf nächste BCODE IF (m_nwr = '0') AND (m_ncs = '0') THEN m_nobf <= '0'; --neue BCODE gelesen recstate <= S5265;-- dann nächste Block empfangen ELSE recstate <= S5264;-- warten auf nächste BCODE END IF; WHEN S5265 => IF m_nwr = '0' THEN recstate <= S5265;-- Warten bis wr fertig ELSE i:= 0;--init für nächste block m_nobf <= '0'; --neue BCODE gelesen AnzClk <= 30;--BCODEclk;--- wartezeit = 1.2us recstate <= S5266;-- END IF; WHEN S5266 => IF AnzClk > 0 THEN AnzClk <= AnzClk - 1; recstate <= S5266;--warten auf Master ELSE m_nobf <= '1'; --reset nobf recstate <= S5260;-- warten zeit vorbei,nächste Ebene END IF; ---------------------------------------------------------------------------- WHEN S5267 => -- fertig , init aller AxKon Register mit werten aus AxKonTAB FOR i IN 0 to 71 LOOP AxKonREG(i) <= AxKonTAB(i);--Kopieren AxKonTAB in AxKonReg END LOOP; recstate <= S5268; WHEN S5268 => ---init Div Register --================= Update für Daten für entity LRKREG ===================== -----RESXY aus alle Ebenen aus AXkonREG = AxkonTAB --RES <= X"00"& AxKonREG(59)& AxKonREG(35)& AxKonREG(11);--RESXY A6..A1 RESA21 <= AxKonREG(11); RESA43 <= AxKonREG(35); RESA65 <= AxKonREG(59); --------------------------------- KNPTXY(0) <= AxKonREG(17)& AxKonREG(16)& AxKonREG(15) & AxKonREG(14);--Knickpkt Konfig KNPKY|KNPKTX A2,A1 KNPTXY(1) <= AxKonREG(41)& AxKonREG(40)& AxKonREG(39) & AxKonREG(38);--Knickpkt Konfig KNPKY|KNPKTX A4,A3 KNPTXY(2) <= AxKonREG(65)& AxKonREG(64)& AxKonREG(63) & AxKonREG(62);--Knickpkt Konfig KNPKY|KNPKTX A6,A5 ----------------------------- KXY(0) <= AxKonREG(21)& AxKonREG(20)& AxKonREG(19) & AxKonREG(18); --KreisVerstärkung K2A2,K1A2|K2A1,K1A1 KXY(1) <= AxKonREG(45)& AxKonREG(44)& AxKonREG(43) & AxKonREG(42); --KreisVerstärkung K2A4,K1A4|K2A3,K1A3 KXY(2) <= AxKonREG(69)& AxKonREG(68)& AxKonREG(67) & AxKonREG(66); --KreisVerstärkung K2A6,K1A6|K2A5,K1A5 ----------------------- KORRXY(0) <= AxKonREG(8)& AxKonREG(10)& AxKonREG(07) & AxKonREG(09); ----31..24:KacA2,23..16:KorrA2 |15..8:KacA1, 7..0:KorrA1 KORRXY(1) <= AxKonREG(32)& AxKonREG(34)& AxKonREG(31) & AxKonREG(33); ----31..24:Kaca4,23..16:KorrA4 |15..8:KacA3, 7..0:KorrA3 KORRXY(2) <= AxKonREG(56)& AxKonREG(58)& AxKonREG(55) & AxKonREG(57); ----31..24:KacA6,23..16:KorrA6 | 15..8:KacA5, 7..0:KorrA5 --=================================================================================================== BCODE <= X"00"; recstate <= S9; ---Request 26H, Konfigtabelle ab InitTabelle FPGA :AXKonTab in FPGA Register kopieren --- und an Master senden -- Erste Meldung nach CPU memory fail fertig --==================================================================================== --------------------------------------------------------------------------------------------- --Request 27, KONFIG Werte ab AS21/FPGA Register (AxKonREG) -- an master senden 24 Byte/Ebene WHEN S527 => i := 0;-- Reg NR j:= 0; -- ebene Nr m := 0;-- Tabellen Adresse recstate <= S5270; WHEN S5270 => -- loop IF j = conv_integer(ebene) THEN --wenn Ebene Nr richtig m_ibf <= '1'; -- slave wr, byte zum abholen ist da recstate <= S5272; ELSE recstate <= S5270;-- warten auf Ebene END IF; WHEN S5272 => --warten bis Master gelesen hat IF m_nrd = '0' AND m_ncs = '0' THEN--- If Master rd m_ibf <= '0'; -- master rd, Daten Abgeholt ibf:=0 m_dbus <= AxKonREG(m); recstate <= S5273; ELSE recstate <= S5272;-- Warten bis Master rd aktiv END IF; WHEN S5273 => --warten auf Master rd fertig gelesen IF m_nrd = '0' THEN m_dbus <= AxKonREG(m); recstate <= S5273;-- Warten bis RD fertig ELSE -- master RD inaktiv IF i < 23 THEN i := i + 1; m := m + 1; recstate <= S5270;-- und repeat ELSE --eine Ebene Fertig IF m < 71 THEN m := m + 1; j:= j + 1;--die nächste Ebene recstate <= S5274; -- dann nächste Ebene ELSE recstate <= S5277; -- dann alle Block fertig END IF; m_ibf <= '0'; -- reset IBF END IF; END IF; WHEN S5274 => -- warten auf nächste BCODE IF (m_nwr = '0') AND (m_ncs = '0') THEN recstate <= S5275;-- dann nächste Block empfangen ELSE recstate <= S5274;-- warten auf nächste BCODE END IF; WHEN S5275 => IF m_nwr = '0' THEN recstate <= S5275;-- Warten bis wr fertig ELSE i:= 0;--init für nächste block m_nobf <= '0'; --daten aktiv AnzClk <= 30;--BCODEclk;--- wartezeit = 1.2us recstate <= S5276;-- END IF; WHEN S5276 => IF AnzClk > 0 THEN AnzClk <= AnzClk - 1; recstate <= S5276;--warten auf Master ELSE m_nobf <= '1'; --reset nobf recstate <= S5270;-- warten zeit vorbei,nächste Ebene END IF; ---------------------------------------------------------------------------- WHEN S5277 => -- fertig , init aller AxKon Register mit werten aus AxKonTAB BCODE <= X"00"; recstate <= S9; --Request 27, KONFIG Werte ab AS21/FPGA Register (AxKonREG) -- an master senden 24 Byte/Ebene fertig --============================================================== -- WHEN S528 => -- SOLLWERTINKREMENT X&Y 4 Byte/Ebene -- RECSTATE <= S9 ----------------- Request Meldungen fertig ------------------------- --================================================================== -----Konfigsatz von Master (CPU16) empfangen, BCODE = 02 -------- --- Daten aus CNC Memory (CPU16.1) an AS21 Konfigregister (AxKonREG) senden -- Daten für entity LRKREG updaten -- Wenn Master CNC Memory OK ist, wird es beim PwrUP an ASKarten gesendet -- und gesppeichert in AxKonREG --- (In CPU16. Prog mit up WRASKR an AS Karte Gesendet) -- bei eine Aenderung in Menue ASkonfig , wird jedesmal an ASkarte gesendet -------------------------------------------------------------------- WHEN S7 => -- KonfigSatz von CPU Memory i := 0;--init schleifen Index für nächste Block (24 Byte) m := 0; -- Zeiger in AxKonREG flkonf <= '0'; --Fl Konfig daten init --m_nobf <= '1'; --m_ibf <= '0'; recstate <= S71; WHEN S71 => -- loop konfig daten empfangen von master für Ebene 0 IF (m_nwr = '0') AND (m_ncs = '0') THEN m_nobf <= '0'; -- neue Meldungsbyte da recstate <= S72; ELSE recstate <= S71;-- warten bis nächste Byte von MaSTER END IF; WHEN S72 => IF m_nwr = '0' THEN -- i AxKonREG(m) <= m_dbus; -- Byte Speichern recstate <= S72;-- dann warten bis nwr fertig ELSE m_nobf <= '1'; --reset nobf recstate <= S74; END IF; WHEN S74 => IF i < 23 THEN -- 1 Block länge 24 Byte m := m + 1;--index in AxKonREG inkr i := i + 1; recstate <= S71;-- und repeat ELSE IF m < 71 THEN recstate <= S75;-- und zum nächste Satz 02 Empfangen ELSE recstate <= S79;-- Empfang von 3 Block Beendet END IF; m_ibf <= '0'; -- reset IBF BCODE <= X"00"; END IF; WHEN S75 => -- warten auf nächste BCODE IF (m_nwr = '0') AND (m_ncs = '0') THEN m_ibf <= '0'; -- reset IBF BCODE <= m_dbus; recstate <= S76; ELSE -- m_nrd ='0' recstate <= S75;-- warten auf BCODE END IF; WHEN S76 => IF m_nwr = '0' THEN BCODE <= m_dbus; m_nobf <= '0'; -- byte ist da recstate <= S76;-- Warten bis wr fertig ELSE IF BCODE /= X"02" THEN recstate <= S75;-- warten bis BCODE = 02 ELSE i:= 0;--init für nächste block m := m + 1; recstate <= S71;-- dann weiter zum nächste block empfang END IF; m_nobf <= '1'; -- reset END IF; --------------------------------------------------- WHEN S79 => -- ende Konf daten vom Master m_ibf <= '0'; -- reset IBF m:= 0; i:=0; flkonf <= '1'; -- Konf Daten Empfangen --================= Update für Daten für entity LRKREG ===================== --RES <= X"00"& AxKonREG(59)& AxKonREG(35)& AxKonREG(11); --RESXY A6..A1 RESA21 <= AxKonREG(11); RESA43 <= AxKonREG(35); RESA65 <= AxKonREG(59); KNPTXY(0) <= AxKonREG(17)& AxKonREG(16)& AxKonREG(15) & AxKonREG(14); --Knickpkt Konfig KNPKY|KNPKTX A2,A1 KNPTXY(1) <= AxKonREG(41)& AxKonREG(40)& AxKonREG(39) & AxKonREG(38); --Knickpkt Konfig KNPKY|KNPKTX A4,A3 KNPTXY(2) <= AxKonREG(65)& AxKonREG(64)& AxKonREG(63) & AxKonREG(62); --Knickpkt Konfig KNPKY|KNPKTX A6,A5 KXY(0) <= AxKonREG(21)& AxKonREG(20)& AxKonREG(19) & AxKonREG(18); --KreisVerstärkung K2A2,K1A2|K2A1,K1A1 KXY(1) <= AxKonREG(45)& AxKonREG(44)& AxKonREG(43) & AxKonREG(42); --KreisVerstärkung K2A4,K1A4|K2A3,K1A3 KXY(2) <= AxKonREG(69)& AxKonREG(68)& AxKonREG(67) & AxKonREG(66); --KreisVerstärkung K2A6,K1A6|K2A5,K1A5 KORRXY(0) <= AxKonREG(8)& AxKonREG(10)& AxKonREG(07) & AxKonREG(09); ----31..24:KacA2,23..16:KorrA2 |15..8:KacA1, 7..0:KorrA1 KORRXY(1) <= AxKonREG(32)& AxKonREG(34)& AxKonREG(31) & AxKonREG(33); ----31..24:Kaca4,23..16:KorrA4 |15..8:KacA3, 7..0:KorrA3 KORRXY(2) <= AxKonREG(56)& AxKonREG(58)& AxKonREG(55) & AxKonREG(57); ----31..24:KacA6,23..16:KorrA6 | 15..8:KacA5, 7..0:KorrA5 recstate <= S9; -- Daten aus CNC Memory (CPU16.1) an AS21 Konfigregister senden fertig --==================================================================== WHEN S9 => m_nobf <= '1'; m_ibf <= '0'; i:= 0; j:= 0; m:= 0; recstate <= S0; --***************************************************** ------------Receiv Empfang fertig ---------------------- WHEN OTHERS => recstate <= S0; END CASE; END IF;-- nrst /ELSE END IF;-- CLK END PROCESS; --Ende Receiv --============ENDE Receiv================================================== --============================================================================== ----- Ausführungsfunktionen Für Ref Anfahren --- Rclkdiv ist konstante = 200000. -- AxKonTAb(0)RARTXY | CNGY |ENDY+| IDY | RAY | CNGX |ENDX+| IDX | RAX | -- Adr 00,18,30= Ebene0,1,2 --- AxKonTab(1)REFDIR Adr 01,19,31 :aus AxKonTab: x,x,IDIRY,RDIRY,x,x,IDIRX,RDIRX --- VREF aus AxKonTAB adr: 0C,0D,24,25,3C,3D --- VORINX aus AxKonTab adr: 04,05,1D,1E,35,36 -- Outputsignal RefImp(1..0)SLV gibt Impuls & Richtung für betrefende Achse => OR zu ZRefImp ---------------------------------------- -- Wartet auf Endlage :ZuEnds(11..0)SLV,A6EL,A6ER,....A1EL,A1ER -- Signal Encod(17..0)SLV, --EncoderA6..A1(I,B,A), Index: A16..A1i. -- Signal ZRefImp(11..0):bits[3..0]nimpA1,vorwA1,nimpA0,VorwA0: im Receiv -- Signal REFEND5..0,SL, wenn alle 1 dann Ref angefahren -- Signal REFRUN:SL -- SIGNAL IniPoint :T_AxReg;-- (0 to 5) OF SLV(31 DOWNTO 0);--Init Winkel der Roboterarme ------------Ref Anfahren A0---------------------------------------------------- --Richtung RDIR,IDIR;RefImp_(0) = 0 => rechte Endlage -- *** Spezifisch für Achse Nr -- nacherreichen der programmierte Endlage wird Anzahl Inkremente ab Endlage -- gefahren, danach Index suchen ------------------------------------------------- --TYPE T_KonfigTab is array(0 to 191) of Std_logic_vector(31 DOWNTO 0); -- AnzInkr := AnzInc (5..0) Achsen Konfiguration ----------Ref Anfahren A0 = Achse A1----------------------------------------- --======================================================================== -- zuerst CntrREF(0..2) : funktion zum Steuern der Ausführungs Processe Ref0 bis Ref5 -- gestartet mit strtCntrR <= '1', gesetzt in Receiv S4... ---Befehl sind gespeichert in RefBefehl(0..2), Ebene 0..2 ---Signal --SIGNAL StateRctr0 :INTEGER RANGE 0 TO 31:= 0; --State für REF Ausführung EBENE 0 ---StRcntr0. state für control ref Anfahren von A0 oder/und A1 (Ref0 und/oder Ref1) --============================================================================== --------------- cntr für Ebene 0 ---------------------------------------------- Rcntr0:PROCESS(clk) BEGIN IF rising_edge(clk) THEN -- auf neg.Takt Flanke speichernd **** IF nrst = '0' THEN StRcntr0 <= 0;-- state reset REFRUN0 <= '0'; REFRUN1 <= '0'; SetIstSoll0 <= '0'; ELSE CASE StRcntr0 IS WHEN 0 => IF strtCntrR(0) = '1' THEN StRcntr0 <= 1; ELSE StRcntr0 <= 0; END IF; WHEN 1 => CASE RefBefehl(0) IS WHEN X"41" => --X Allein StRcntr0 <= 2; WHEN X"42" => --Y Allein StRcntr0 <= 3; WHEN X"44" => --X vor Y StRcntr0 <= 4; WHEN X"48" => --Y vor X StRcntr0 <= 5; WHEN X"50" => -- X & Y StRcntr0 <= 6; WHEN X"40" =>--keine ref anfahren REF00 <= '1'; StRcntr0 <= 9; WHEN OTHERS => StRcntr0 <= 0;--für 00 kein ref END CASE;--RefBefehl WHEN 2 => --Ausführung RefBefehl:41= X Allein REFRUN0 <= '1'; IF REFEND0 = '1' THEN StRcntr0 <= 7;-- dann ref angefahren ELSE StRcntr0 <= 2;-- dann warten END IF; WHEN 3 => --Ausführung RefBefehl:42= Y Allein REFRUN1 <= '1'; IF REFEND1 = '1' THEN StRcntr0 <= 7;-- dann ref angefahren ELSE StRcntr0 <= 3;-- dann warten END IF; WHEN 4 => --Ausführung RefBefehl:44= X vor Y REFRUN0 <= '1'; IF REFEND0 = '1' THEN StRcntr0 <= 41;-- dann ref X angefahren und Weiter ELSE StRcntr0 <= 4;-- dann warten END IF; WHEN 41 => REFRUN1 <= '1'; IF REFEND1 = '1' THEN StRcntr0 <= 7;-- dann ref Y angefahren und fertig ELSE StRcntr0 <= 41;-- dann warten END IF; WHEN 5 => --Ausführung RefBefehl:48= Y vor X REFRUN1 <= '1'; IF REFEND1 = '1' THEN StRcntr0 <= 51;-- dann ref Y angefahren und fertig ELSE StRcntr0 <= 5;-- dann warten END IF; WHEN 51 => REFRUN0 <= '1'; IF REFEND0 = '1' THEN StRcntr0 <= 7;-- dann ref X angefahren und fertig ELSE StRcntr0 <= 51;-- dann warten END IF; WHEN 6 => --Ausführung RefBefehl:50= X & Y REFRUN0 <= '1'; REFRUN1 <= '1'; IF REFEND0 = '1' AND REFEND1 = '1' THEN StRcntr0 <= 7;-- dann ref X & Y angefahren ELSE StRcntr0 <= 6;-- dann warten END IF; WHEN 7 => REFRUN0 <= '0'; REFRUN1 <= '0'; StRcntr0 <= 8;--dann ref X & Y angefahren WHEN 8 => StRcntr0 <= 0;-- fertig WHEN 9 => --bei Ref Befehl 40 IF (REFEND1='1' AND REFEND0='1') THEN SetIstSoll0 <= '1'; REF00 <= '0'; StRcntr0 <= 10; END IF; WHEN 10 => SetIstSoll0 <= '0'; StRcntr0 <= 0;--und fertig WHEN OTHERS => StRcntr0 <= 0; END CASE;--StRctrl0 END IF;-- end nrst/else END IF;-- end clk END PROCESS;--Rcntr0 ---------------------CNTR für EBENE 1------------------------------------------ Rcntr1:PROCESS(clk) BEGIN IF rising_edge(clk) THEN -- auf neg.Takt Flanke speichernd **** IF nrst = '0' THEN StRcntr1 <= 0;-- state reset REFRUN2 <= '0'; REFRUN3 <= '0'; SetIstSoll1 <= '0'; ELSE CASE StRcntr1 IS WHEN 0 => IF strtCntrR(1) = '1' THEN StRcntr1 <= 1; ELSE StRcntr1 <= 0; END IF; WHEN 1 => CASE RefBefehl(1) IS WHEN X"41" => StRcntr1 <= 2; WHEN X"42" => StRcntr1 <= 3; WHEN X"44" => StRcntr1 <= 4; WHEN X"48" => StRcntr1 <= 5; WHEN X"50" => StRcntr1 <= 6; WHEN X"40" =>--keine ref anfahren REF01 <= '1'; StRcntr1 <= 9; WHEN OTHERS => StRcntr1 <= 0; END CASE;--RefBefehl WHEN 2 => --Ausführung RefBefehl:41= X Allein REFRUN2 <= '1'; IF REFEND2 = '1' THEN StRcntr1 <= 7;-- dann ref angefahren ELSE StRcntr1 <= 2;-- dann warten END IF; WHEN 3 => --Ausführung RefBefehl:42= Y Allein REFRUN3 <= '1'; IF REFEND3 = '1' THEN StRcntr1 <= 7;-- dann ref angefahren ELSE StRcntr1 <= 3;-- dann warten END IF; WHEN 4 => --Ausführung RefBefehl:44= X vor Y REFRUN2 <= '1'; IF REFEND2 = '1' THEN StRcntr1 <= 41;-- dann ref X angefahren und Weiter ELSE StRcntr1 <= 4;-- dann warten END IF; WHEN 41 => REFRUN3 <= '1'; IF REFEND3 = '1' THEN StRcntr1 <= 7;-- dann ref Y angefahren und fertig ELSE StRcntr1 <= 41;-- dann warten END IF; WHEN 5 => --Ausführung RefBefehl:48= Y vor X REFRUN3 <= '1'; IF REFEND3 = '1' THEN StRcntr1 <= 51;-- dann ref Y angefahren und fertig ELSE StRcntr1 <= 5;-- dann warten END IF; WHEN 51 => REFRUN2 <= '1'; IF REFEND2 = '1' THEN StRcntr1 <= 7;-- dann ref X angefahren und fertig ELSE StRcntr1 <= 51;-- dann warten END IF; WHEN 6 => --Ausführung RefBefehl:50= X & Y REFRUN2 <= '1'; REFRUN3 <= '1'; IF REFEND2 = '1' AND REFEND3 = '1' THEN StRcntr1 <= 7;-- dann ref X & Y angefahren und weiter ELSE StRcntr1 <= 6;-- dann warten END IF; WHEN 7 => REFRUN2 <= '0'; REFRUN3 <= '0'; StRcntr1 <= 8;-- dann ref X & Y angefahren und fertig WHEN 8 => StRcntr1 <= 0; WHEN 9 => --bei Ref Befehl 00 IF (REFEND3='1' AND REFEND2='1') THEN REF01 <= '0'; SetIstSoll1 <= '1';--start pos setzen StRcntr1 <= 10; END IF; WHEN 10 => SetIstSoll1 <= '0';--start pos reset StRcntr1 <= 0;--und fertig WHEN OTHERS => StRcntr1 <= 0; END CASE;--StRctrl0 END IF;-- end nrst/else END IF;-- end clk END PROCESS;--Rcntr1 ---------------------CNTR für EBENE 2------------------------------------------ Rcntr2:PROCESS(clk) BEGIN IF rising_edge(clk) THEN -- auf neg.Takt Flanke speichernd **** IF nrst = '0' THEN StRcntr2 <= 0;-- state reset REFRUN4 <= '0'; REFRUN5 <= '0'; SetIstSoll2 <= '0';--start pos reset ELSE CASE StRcntr2 IS WHEN 0 => IF strtCntrR(2) = '1' THEN StRcntr2 <= 1; ELSE StRcntr2 <= 0; END IF; WHEN 1 => CASE RefBefehl(2) IS WHEN X"41" => StRcntr2 <= 2; WHEN X"42" => StRcntr2 <= 3; WHEN X"44" => StRcntr2 <= 4; WHEN X"48" => StRcntr2 <= 5; WHEN X"50" => StRcntr2 <= 6; WHEN X"40" =>--keine ref anfahren REF02 <= '1'; StRcntr2 <= 9; WHEN OTHERS => StRcntr2 <= 0; END CASE;--RefBefehl WHEN 2 => --Ausführung RefBefehl:41= X Allein REFRUN4 <= '1'; IF REFEND4 = '1' THEN StRcntr2 <= 7;-- dann ref angefahren ELSE StRcntr2 <= 2;-- dann warten END IF; WHEN 3 => --Ausführung RefBefehl:42= Y Allein REFRUN5 <= '1'; IF REFEND5 = '1' THEN StRcntr2 <= 7;-- dann ref angefahren ELSE StRcntr2 <= 3;-- dann warten END IF; WHEN 4 => --Ausführung RefBefehl:44= X vor Y REFRUN4 <= '1'; IF REFEND4 = '1' THEN StRcntr2 <= 41;-- dann ref X angefahren und Weiter ELSE StRcntr2 <= 4;-- dann warten END IF; WHEN 41 => REFRUN5 <= '1'; IF REFEND5 = '1' THEN StRcntr2 <= 7;-- dann ref Y angefahren und fertig ELSE StRcntr2 <= 41;-- dann warten END IF; WHEN 5 => --Ausführung RefBefehl:48= Y vor X REFRUN5 <= '1'; IF REFEND5 = '1' THEN StRcntr2 <= 51;-- dann ref Y angefahren und fertig ELSE StRcntr2 <= 5;-- dann warten END IF; WHEN 51 => REFRUN4 <= '1'; IF REFEND4 = '1' THEN StRcntr2 <= 7;-- dann ref X angefahren und fertig ELSE StRcntr2 <= 51;-- dann warten END IF; WHEN 6 => --Ausführung RefBefehl:50= X & Y REFRUN4 <= '1'; REFRUN5 <= '1'; IF REFEND4 = '1' AND REFEND5 = '1' THEN StRcntr2 <= 7;-- dann ref X & Y angefahren ELSE StRcntr2 <= 6;-- dann warten END IF; WHEN 7 => REFRUN4 <= '0'; REFRUN5 <= '0'; StRcntr2 <= 8;--dann ref X & Y angefahren WHEN 8 => StRcntr2 <= 0;--und fertig WHEN 9 => --bei Ref Befehl 00 IF (REFEND5='1' AND REFEND4='1') THEN REF02 <= '0'; SetIstSoll2 <= '1';--start pos setzen StRcntr2 <= 10; END IF; WHEN 10 => SetIstSoll2 <= '0';--start pos reset StRcntr2 <= 0;--und fertig WHEN OTHERS => StRcntr2 <= 0; END CASE;--StRctrl0 END IF;-- end nrst/else END IF;-- end clk END PROCESS;--Rcntr2 --------------------ende Control Processe für Ref Anfahren in Ebenen 0..2 --=========Ausführung Referenz in Achsen A0 bis A5 ========================== ----------Ref Anfahren A0 = Achse A1----------------------------------------- RefA0 :PROCESS(clk) VARIABLE Rcntr :INTEGER:= 0; VARIABLE Vref32,Vindx32 :integer := 0; VARIABLE Stateref :INTEGER RANGE 0 TO 15 := 0; VARIABLE AnzahlImp :INTEGER RANGE 0 TO 65535:= 0; VARIABLE RA,ID,RDIR,IDIR :STD_LOGIC:= '0';--Kopie RAX,RAY,usw VARIABLE INDX :STD_LOGIC:= '0';-- speicher für index puls VARIABLE AnzInc :STD_LOGIC_VECTOR(31 DOWNTO 0) := X"00000010"; BEGIN IF rising_edge(clk) THEN -- auf neg.Takt Flanke speichernd **** IF nrst = '0' THEN Rcntr := Rclkdiv; Vref32 := 0; Vindx32:= 0; RefImp0(0) <= '0';--richtung= 0= rechte Endlage RefImp0(1) <= '1';-- Impuls = 0 StateRef := 0; AnzahlImp := 0; RA:='0';ID:='0';RDIR:='0';IDIR:='0'; INDX := '0'; AnzInc := X"00000010"; ELSE CASE StateRef IS WHEN 0 => --variable setzen gemäss Achse Nr IF REFRUN0 = '1' THEN Vref32 := conv_integer(X"000000" & AxKonREG(12));--Ref Grund-vorschub *** Vindx32 := conv_integer(X"000000" & AxKonREG(5));--Index Grund-vorschub *** RA := AxKonREG(0)(0); -- RA = RAX (Achse A0) *** ID := AxKonREG(0)(1); -- ID = IDX (Achse A0) *** RDIR := AxKonREG(1)(0);--Richtung gemäs RDIRX *** IDIR := AxKonREG(1)(1);--Richtung gemäs IDIRX *** RefImp0(1) <= '1';-- Impuls Ruhezustand *** StateRef := 1; AnzInc := KonfigTab(11); ELSIF REF00 ='1' THEN REFEND0 <= '1';--ebene0 StateRef := 0; ELSE IF REFEND1 = '1' THEN REFEND0 <= '1';-- ebene 0 END IF; StateRef := 0; END IF; WHEN 1 => --testen soll REF anfahren IF RA = '0' THEN -- keine REG Anfahren StateRef := 9; -- dann zu Index Anfahren ELSE -- REF sollte angefahren werden RefImp0(0) <= RDIR;-- Richtung Endlage suchen *** StateRef := 2; END IF; --------Loop Endlage anfahren----------------------------- WHEN 2 => --1.Loop Anzahlclk Pulse Abstand Rcntr := Vref32 * Rclkdiv;--Anz clk zwischen Imp laden StateRef := 3; WHEN 3 =>-- Pause abarbeiten zwischen Pulsen IF Rcntr = 0 THEN RefImp0(1) <= '0';-- Impuls Ausgabe *** StateRef := 4; ELSE Rcntr := Rcntr - 1; StateRef := 3;-- anzahl clk abarbeiten END IF; WHEN 4 => RefImp0(1) <= '1';-- Impuls in Ruhestellun *** IF (ZuEnds(0) AND RDIR) = '1' THEN -- If Endlage R oder L *** StateRef := 5;-- dann REF in Endlage ELSE StateRef := 2; -- dann repeat für nächste Impuls END IF; ---- Loop ende Endlage Anfahren ------ WHEN 5 => --vorbereitung zum Mitte AnzInkr fahren RDIR := NOT RDIR; --Fahrrichtung umkehren AnzahlImp := 0; StateRef := 6; ---------------------------------------- ----Loop Anzahl Impulse Abfahren(ca.mitte Bewegungsbereich9 WHEN 6 => -- 2. loop, fahre auf hälfte AnzInkr Rcntr := Vref32 * Rclkdiv;-- Impulsabstandzähler init RefImp0(0) <= RDIR;-- Fahr Richtung *** StateRef := 7; WHEN 7 => --Pause abarbeiten zwischen Pulsen IF Rcntr = 0 THEN RefImp0(1) <= '0';-- Impuls Ausgabe *** AnzahlImp := AnzahlImp + 1; StateRef := 8; ELSE Rcntr := Rcntr - 1; StateRef := 7;-- Anzahl clk abarbeiten=Impuls Abstand END IF; WHEN 8 => RefImp0(1) <= '1';-- Impuls in Ruhestellung """ IF AnzahlImp < conv_integer(KonfigTab(11)) THEN ---- Anzahl Inc für A0 StateRef := 6;-- dann nächste Impuls ELSE -- Ref Achse A0 fertig StateRef := 9; END IF; --- Ende Loop Impulse Abf ahren ----------------------------- WHEN 9 => --testen soll Index anfahren IF ID = '0' THEN --wen keine index dann beenden REFEND0 <= '1'; StateRef := 13;--und beenden ELSE StateRef := 10;-- zum INDX Anfahren init END IF; ------------loop Index Anfahren------------------------ WHEN 10 => -- Loop Index Anfahren IF Encods(2) = '1' THEN --IndexSpeichern INDX := Encods(2); ELSE INDX := INDX; END IF; -- Rcntr := Vindx32 * Rclkdiv;-- Impulsabstandzähler init RefImp0(0) <= IDIR;-- Fahr Richtung *** IF Encods(2) = '1' THEN --IndexSpeichern INDX := Encods(2); ELSE INDX := INDX; END IF; -- StateRef := 11;-- und zu Impulspause abarbeoiten WHEN 11 => -- Impuls Pause IF Encods(2) = '1' THEN --IndexSpeichern INDX := Encods(2); ELSE INDX := INDX; END IF; --- IF Rcntr = 0 THEN RefImp0(1) <= '0';-- Impuls Ausgabe *** StateRef := 12; ELSE Rcntr := Rcntr - 1; StateRef := 11;-- anzahl clk abarbeiten END IF; WHEN 12 => RefImp0(1) <= '1';-- Impuls in Ruhestellung *** IF Encods(2)='1' OR INDX='1' THEN -- wenn Index A1 Aktiv *** INDX := '0'; StateRef := 13;-- Index angefahren ELSE Stateref := 10; --und repesat in Loop Index Anfahren END IF; ----- Ende Loop Index Anfahren----------------------- WHEN 13 => --ref und/oder index angefahren REFEND0 <= '1'; --Referenz Achse A0,1 angefahren *** Stateref := 14; WHEN 14 => IF REFRUN = '0' THEN Stateref := 15;-- ref fertig, und warten auf nächste Ref ELSE Stateref := 14;-- Warten bis alle Achsen Fertig END IF; WHEN 15 => Stateref := 0;--warten auf nächste Ref WHEN OTHERS => StateRef := 0; END CASE; END IF; END IF; END PROCESS; -- refA0 ----------------Ref Anfahren A1 = Achse A2---------------------------------------- RefA1 :PROCESS(clk) VARIABLE Rcntr :INTEGER:= 0; VARIABLE Vref32,Vindx32 :integer := 0; VARIABLE Stateref :INTEGER RANGE 0 TO 15 := 0; VARIABLE AnzahlImp :INTEGER RANGE 0 TO 65535:= 0; VARIABLE RA,ID,RDIR,IDIR :STD_LOGIC:= '0';--Kopie RAX,RAY,usw VARIABLE INDX :STD_LOGIC:= '0';-- speicher für index puls VARIABLE AnzInc :STD_LOGIC_VECTOR(31 DOWNTO 0) := X"00000010"; BEGIN IF rising_edge(clk) THEN -- auf neg.Takt Flanke speichernd **** IF nrst = '0' THEN Rcntr := Rclkdiv; Vref32 := 0; Vindx32:= 0; RefImp1(0) <= '0';--richtung= 0= rechte Endlage *** RefImp1(1) <= '1';-- Impuls = 0 *** StateRef := 0; AnzahlImp := 0; RA:='0';ID:='0';RDIR:='0';IDIR:='0'; INDX := '0'; AnzInc := X"00000010"; ELSE CASE StateRef IS WHEN 0 => --variable setzen gemäss Achse Nr IF REFRUN1 = '1' THEN Vref32 := conv_integer(X"000000" & AxKonREG(13));--Ref Grund-vorschub Vindx32 := conv_integer(X"000000" & AxKonREG(6));--Index Grund-vorschub RA := AxKonREG(0)(3); -- RA = RAY (Achse A1) ID := AxKonREG(0)(4); -- ID = IDY (Achse A1) RDIR := AxKonREG(1)(3);--Richtung gemäs RDIRY IDIR := AxKonREG(1)(4);--Richtung gemäs IDIRY StateRef := 1; AnzInc := KonfigTab(12); ELSIF REF00 ='1' THEN REFEND1 <= '1';-- ebene0 StateRef := 0; ELSE IF REFEND0 = '1' THEN REFEND1 <= '1';-- ebene 0 END IF; StateRef := 0; END IF; WHEN 1 => --testen soll REF anfahren IF RA = '0' THEN -- keine REG Anfahren StateRef := 9; -- dann zu Index Anfahren ELSE -- REF sollte angefahren werden RefImp1(0) <= RDIR;-- Richtung Endlage suchen *** StateRef := 2; END IF; ------------------------------------- WHEN 2 => --1.Loop Anzahlclk Pulse Abstand Rcntr := Vref32 * Rclkdiv;--Anz clk zwischen Imp laden StateRef := 3; WHEN 3 =>-- Pause abarbeiten zwischen Pulsen IF Rcntr = 0 THEN RefImp1(1) <= '0';-- Impuls Ausgabe *** StateRef := 4; ELSE Rcntr := Rcntr - 1; StateRef := 3;-- anzahl clk abarbeiten END IF; WHEN 4 => RefImp1(1) <= '1';-- Impuls in Ruhestellun *** IF (ZuEnds(2) AND RDIR)= '1' THEN -- If Endlage A1 R *** StateRef := 5;-- dann REF in Endlage ELSE StateRef := 2; -- dann repeat für nächste Impuls END IF; WHEN 5 => --vorbereitung zum Mitte AnzInkr fahren RDIR := NOT RDIR; --Fahrrichtung umkehren AnzahlImp := 0; StateRef := 6; ---------------------------------------- WHEN 6 => -- 2. loop, fahre auf hälfte AnzInkr Rcntr := Vref32 * Rclkdiv;-- Impulsabstandzähler init RefImp1(0) <= RDIR;-- Fahr Richtung *** StateRef := 7; WHEN 7 => --Pause abarbeiten zwischen Pulsen IF Rcntr = 0 THEN RefImp1(1) <= '0';-- Impuls Ausgabe *** AnzahlImp := AnzahlImp + 1; StateRef := 8; ELSE Rcntr := Rcntr - 1; StateRef := 7;-- Anzahl clk abarbeiten=Impuls Abstand END IF; WHEN 8 => RefImp1(1) <= '1';-- Impuls in Ruhestellung *** IF AnzahlImp < conv_integer(KonfigTab(12)) THEN ---- Anzahl Inkr für A1 als konst StateRef := 6;-- dann nächste Impuls ELSE -- Ref Achse A0 fertig StateRef := 9; END IF; WHEN 9 => --testen soll Index anfahren IF ID = '0' THEN REFEND1 <= '1'; StateRef := 13; ELSE StateRef := 10;-- zum INDX Anfahren init END IF; ---------------------------------------------- WHEN 10 => -- Loop Index Anfahren IF Encods(5) = '1' THEN --IndexSpeichern INDX := Encods(5); ELSE INDX := INDX; END IF; -- Rcntr := Vindx32 * Rclkdiv;-- Impulsabstandzähler init RefImp1(0) <= IDIR;-- Fahr Richtung *** StateRef := 11;-- und zu Impulspause abarbeoiten WHEN 11 => -- Impuls Pause IF Encods(5) = '1' THEN --IndexSpeichern INDX := Encods(5); ELSE INDX := INDX; END IF; -- IF Rcntr = 0 THEN RefImp1(1) <= '0';-- Impuls Ausgabe StateRef := 12; ELSE Rcntr := Rcntr - 1; StateRef := 11;-- anzahl clk abarbeiten END IF; WHEN 12 => RefImp1(1) <= '1';-- Impuls in Ruhestellung *** IF Encods(5)='1' OR INDX='1' THEN -- wenn Index A1 Aktiv *** INDX := '0'; StateRef := 13;-- Index angefahren ELSE Stateref := 10; --und repesat in Loop Index Anfahren END IF; WHEN 13 => REFEND1 <= '1'; Stateref := 14;-- Warten bis alle Achsen Fertig WHEN 14 => IF REFRUN = '0' THEN Stateref := 15;-- ref fertig, und warten auf nächste Ref ELSE Stateref := 14;-- Warten bis alle Achsen Fertig END IF; WHEN 15 => Stateref := 0;--warten auf nächste Ref WHEN OTHERS => StateRef := 0; END CASE; END IF; END IF; END PROCESS; -- refA1 -------------------Ref Anfahren A2= Achse A3----------------------------------- RefA2 :PROCESS(clk) VARIABLE Rcntr :INTEGER:= 0; VARIABLE Vref32,Vindx32 :integer := 0; VARIABLE Stateref :INTEGER RANGE 0 TO 15 := 0; VARIABLE AnzahlImp :INTEGER RANGE 0 TO 65535:= 0; VARIABLE RA,ID,RDIR,IDIR :STD_LOGIC:= '0';--Kopie RAX,RAY,usw VARIABLE INDX :STD_LOGIC:= '0';-- speicher für index puls VARIABLE AnzInc :STD_LOGIC_VECTOR(31 DOWNTO 0) := X"00000010"; BEGIN IF rising_edge(clk) THEN -- IF nrst = '0' THEN Rcntr := Rclkdiv; Vref32 := 0; Vindx32:= 0; RefImp2(0) <= '0';--richtung= 0= rechte Endlage RefImp2(1) <= '1';-- Impuls = 0 StateRef := 0; AnzahlImp := 0; RA:='0';ID:='0';RDIR:='0';IDIR:='0'; INDX := '0'; AnzInc := X"00000010"; ELSE CASE StateRef IS WHEN 0 => --variable setzen gemäss Achse Nr IF REFRUN2 = '1' THEN Vref32 := conv_integer(X"000000" & AxKonREG(36));--Ref Grund-vorschub ***24 Vindx32 := conv_integer(X"000000" & AxKonREG(29));--Index Grund-vorschub ***1d RA := AxKonREG(24)(0); -- RA = RAX (Achse A2) *** ID := AxKonREG(24)(1); -- ID = IDX (Achse A2) *** RDIR := AxKonREG(25)(0);--Richtung gemäs RDIRX *** IDIR := AxKonREG(25)(1);--Richtung gemäs IDIRX *** RefImp2(1) <= '1';-- Impuls Ruhezustand *** StateRef := 1; AnzInc := KonfigTab(13); ELSIF REF01 ='1' THEN REFEND2 <= '1';--ebene1 StateRef := 0; ELSE IF REFEND3 = '1' THEN REFEND2 <= '1';-- ebene 1 END IF; StateRef := 0; END IF; WHEN 1 => --testen soll REF anfahren IF RA = '0' THEN -- keine REG Anfahren StateRef := 9; -- dann zu Index Anfahren ELSE -- REF sollte angefahren werden RefImp2(0) <= RDIR;-- Richtung Endlage suchen *** StateRef := 2; END IF; ------------------------------------- WHEN 2 => --1.Loop Anzahlclk Pulse Abstand Rcntr := Vref32 * Rclkdiv;--Anz clk zwischen Imp laden StateRef := 3; WHEN 3 =>-- Pause abarbeiten zwischen Pulsen IF Rcntr = 0 THEN RefImp2(1) <= '0';-- Impuls Ausgabe *** StateRef := 4; ELSE Rcntr := Rcntr - 1; StateRef := 3;-- anzahl clk abarbeiten END IF; WHEN 4 => RefImp2(1) <= '1';-- Impuls in Ruhestellun *** IF (ZuEnds(4) AND RDIR) = '1' THEN -- If Endlage R *** StateRef := 5;-- dann REF in Endlage ELSE StateRef := 2; -- dann repeat für nächste Impuls END IF; WHEN 5 => --vorbereitung zum Mitte AnzInkr fahren RDIR := NOT RDIR; --Fahrrichtung umkehren AnzahlImp := 0; StateRef := 6; ---------------------------------------- WHEN 6 => -- 2. loop, fahre auf hälfte AnzInkr Rcntr := Vref32 * Rclkdiv;-- Impulsabstandzähler init RefImp2(0) <= RDIR;-- Fahr Richtung *** StateRef := 7; WHEN 7 => --Pause abarbeiten zwischen Pulsen IF Rcntr = 0 THEN RefImp2(1) <= '0';-- Impuls Ausgabe *** AnzahlImp := AnzahlImp + 1; StateRef := 8; ELSE Rcntr := Rcntr - 1; StateRef := 7;-- Anzahl clk abarbeiten=Impuls Abstand END IF; WHEN 8 => RefImp2(1) <= '1';-- Impuls in Ruhestellung """ IF AnzahlImp < conv_integer(KonfigTab(13)) THEN ---- Anzahl Inkr für A2 als konst --IF AnzahlImp < conv_integer(AnzInc(52)) THEN --Anzahl Inkr für A2 aus konfig tab 52/13 StateRef := 6;-- dann nächste Impuls ELSE -- Ref Achse A0 fertig StateRef := 9; END IF; WHEN 9 => --testen soll Index anfahren IF ID = '0' THEN REFEND2 <= '1'; StateRef := 13; ELSE StateRef := 10;-- zum INDX Anfahren init END IF; ---------------------------------------------- WHEN 10 => -- Loop Index Anfahren IF Encods(8) = '1' THEN --IndexSpeichern INDX := Encods(8); ELSE INDX := INDX; END IF; -- Rcntr := Vindx32 * Rclkdiv;-- Impulsabstandzähler init RefImp2(0) <= IDIR;-- Fahr Richtung *** StateRef := 11;-- und zu Impulspause abarbeoiten WHEN 11 => -- Impuls Pause IF Encods(8) = '1' THEN --IndexSpeichern INDX := Encods(8); ELSE INDX := INDX; END IF; -- IF Rcntr = 0 THEN RefImp2(1) <= '0';-- Impuls Ausgabe *** StateRef := 12; ELSE Rcntr := Rcntr - 1; StateRef := 11;-- anzahl clk abarbeiten END IF; WHEN 12 => RefImp2(1) <= '1';-- Impuls in Ruhestellung *** IF Encods(8)='1' OR INDX='1' THEN -- wenn Index A1 Aktiv *** INDX := '0'; StateRef := 13;-- Index angefahren ELSE Stateref := 10; --und repesat in Loop Index Anfahren END IF; WHEN 13 => REFEND2 <= '1'; Stateref := 14;-- Warten bis alle Achsen Fertig WHEN 14 => IF REFRUN = '0' THEN Stateref := 15;-- ref fertig, und warten auf nächste Ref ELSE Stateref := 14;-- Warten bis alle Achsen Fertig END IF; WHEN 15 => StateRef := 0;-- und fertig WHEN OTHERS => StateRef := 0; END CASE; END IF; END IF; END PROCESS; -- refA2 ----------------Ref Anfahren A3 (Achse A4)---------------------------------------- RefA3 :PROCESS(clk) VARIABLE Rcntr :INTEGER:= 0; VARIABLE Vref32,Vindx32 :integer := 0; VARIABLE Stateref :INTEGER RANGE 0 TO 15 := 0; VARIABLE AnzahlImp :INTEGER RANGE 0 TO 65535:= 0; VARIABLE RA,ID,RDIR,IDIR :STD_LOGIC:= '0';--Kopie RAX,RAY,usw VARIABLE INDX :STD_LOGIC:= '0';-- speicher für index puls VARIABLE AnzInc :STD_LOGIC_VECTOR(31 DOWNTO 0) := X"00000010"; BEGIN IF rising_edge(clk) THEN -- auf neg.Takt Flanke speichernd **** IF nrst = '0' THEN Rcntr := Rclkdiv; Vref32 := 0; Vindx32:= 0; RefImp3(0) <= '0';--richtung= 0= rechte Endlage *** RefImp3(1) <= '1';-- Impuls = 0 *** StateRef := 0; AnzahlImp := 0; RA:='0';ID:='0';RDIR:='0';IDIR:='0'; INDX := '0'; AnzInc := X"00000010"; ELSE CASE StateRef IS WHEN 0 => --variable setzen gemäss Achse Nr IF REFRUN3 = '1' THEN Vref32 := conv_integer(X"000000" & AxKonREG(37));--Ref Grund-vorschub Vindx32 := conv_integer(X"000000" & AxKonREG(30));--Index Grund-vorschub RA := AxKonREG(24)(4); -- RA = RAY (Achse A1) ID := AxKonREG(24)(5); -- ID = IDY (Achse A1) RDIR := AxKonREG(25)(4);--Richtung gemäs RDIRY IDIR := AxKonREG(25)(5);--Richtung gemäs IDIRY StateRef := 1; AnzInc := KonfigTab(14); ELSIF REF01 ='1' THEN REFEND3 <= '1';-- ebene 1 StateRef := 0; ELSE IF REFEND2 = '1' THEN REFEND3 <= '1';-- ebene 1 END IF; StateRef := 0; END IF; WHEN 1 => --testen soll REF anfahren IF RA = '0' THEN -- keine REG Anfahren StateRef := 9; -- dann zu Index Anfahren ELSE -- REF sollte angefahren werden RefImp3(0) <= RDIR;-- Richtung Endlage suchen *** StateRef := 2; END IF; ------------------------------------- WHEN 2 => --1.Loop Anzahlclk Pulse Abstand Rcntr := Vref32 * Rclkdiv;--Anz clk zwischen Imp laden StateRef := 3; WHEN 3 =>-- Pause abarbeiten zwischen Pulsen IF Rcntr = 0 THEN RefImp3(1) <= '0';-- Impuls Ausgabe *** StateRef := 4; ELSE Rcntr := Rcntr - 1; StateRef := 3;-- anzahl clk abarbeiten END IF; WHEN 4 => RefImp3(1) <= '1';-- Impuls in Ruhestellun *** IF (ZuEnds(6) AND RDIR) = '1' THEN -- If Endlage A1 R oder L *** StateRef := 5;-- dann REF in Endlage ELSE StateRef := 2; -- dann repeat für nächste Impuls END IF; WHEN 5 => --vorbereitung zum Mitte AnzInkr fahren RDIR := NOT RDIR; --Fahrrichtung umkehren AnzahlImp := 0; StateRef := 6; ---------------------------------------- WHEN 6 => -- 2. loop, fahre auf hälfte AnzInkr Rcntr := Vref32 * Rclkdiv;-- Impulsabstandzähler init RefImp3(0) <= RDIR;-- Fahr Richtung *** StateRef := 7; WHEN 7 => --Pause abarbeiten zwischen Pulsen IF Rcntr = 0 THEN RefImp3(1) <= '0';-- Impuls Ausgabe *** AnzahlImp := AnzahlImp + 1; StateRef := 8; ELSE Rcntr := Rcntr - 1; StateRef := 7;-- Anzahl clk abarbeiten=Impuls Abstand END IF; WHEN 8 => RefImp3(1) <= '1';-- Impuls in Ruhestellung *** IF AnzahlImp < conv_integer(KonfigTab(14)) THEN ---- Anzahl Inc für A3 als konst StateRef := 6;-- dann nächste Impuls ELSE -- Ref Achse A0 fertig StateRef := 9; END IF; WHEN 9 => --testen soll Index anfahren IF ID = '0' THEN REFEND3 <= '1'; StateRef := 13; ELSE StateRef := 10;-- zum INDX Anfahren init END IF; ---------------------------------------------- WHEN 10 => -- Loop Index Anfahren IF Encods(11) = '1' THEN --IndexSpeichern INDX := Encods(11); ELSE INDX := INDX; END IF; -- Rcntr := Vindx32 * Rclkdiv;-- Impulsabstandzähler init RefImp3(0) <= IDIR;-- Fahr Richtung *** StateRef := 11;-- und zu Impulspause abarbeoiten WHEN 11 => -- Impuls Pause IF Encods(11) = '1' THEN --IndexSpeichern INDX := Encods(11); ELSE INDX := INDX; END IF; -- IF Rcntr = 0 THEN RefImp3(1) <= '0';-- Impuls Ausgabe StateRef := 12; ELSE Rcntr := Rcntr - 1; StateRef := 11;-- anzahl clk abarbeiten END IF; WHEN 12 => RefImp3(1) <= '1';-- Impuls in Ruhestellung *** IF Encods(11)='1' OR INDX='1' THEN -- wenn Index A1 Aktiv *** INDX := '0'; StateRef := 13;-- Index angefahren ELSE Stateref := 10; --und repesat in Loop Index Anfahren END IF; WHEN 13 => REFEND3 <= '1'; Stateref := 14;-- Warten bis alle Achsen Fertig WHEN 14 => IF REFRUN = '0' THEN Stateref := 15;-- ref fertig, und warten auf nächste Ref ELSE Stateref := 14;-- Warten bis alle Achsen Fertig END IF; WHEN 15 => Stateref := 0; WHEN OTHERS => StateRef := 0; END CASE; END IF; END IF; END PROCESS; -- refA3 -------------------------------------------------- -------------------Ref Anfahren A4 =Achse A5----------------------------------- RefA4 :PROCESS(clk) VARIABLE Rcntr :INTEGER:= 0; VARIABLE Vref32,Vindx32 :integer := 0; VARIABLE Stateref :INTEGER RANGE 0 TO 15 := 0; VARIABLE AnzahlImp :INTEGER RANGE 0 TO 65535:= 0; VARIABLE RA,ID,RDIR,IDIR :STD_LOGIC:= '0';--Kopie RAX,RAY,usw VARIABLE INDX :STD_LOGIC:= '0';-- speicher für index puls VARIABLE AnzInc :STD_LOGIC_VECTOR(31 DOWNTO 0) := X"00000010"; BEGIN IF rising_edge(clk) THEN -- IF nrst = '0' THEN Rcntr := Rclkdiv; Vref32 := 0; Vindx32:= 0; RefImp4(0) <= '0';--richtung= 0= rechte Endlage RefImp4(1) <= '1';-- Impuls = 0 StateRef := 0; AnzahlImp := 0; RA:='0';ID:='0';RDIR:='0';IDIR:='0'; INDX := '0'; AnzInc := X"00000010"; ELSE CASE StateRef IS WHEN 0 => --variable setzen gemäss Achse Nr IF REFRUN4 = '1' THEN Vref32 := conv_integer(X"000000" & AxKonREG(60));--Ref Grund-vorschub *** Vindx32 := conv_integer(X"000000" & AxKonREG(53));--Index Grund-vorschub *** RA := AxKonREG(48)(0); -- RA = RAX (Achse A0) *** ID := AxKonREG(48)(1); -- ID = IDX (Achse A0) *** RDIR := AxKonREG(49)(0);--Richtung gemäs RDIRX *** IDIR := AxKonREG(49)(1);--Richtung gemäs IDIRX *** RefImp4(1) <= '1';-- Impuls Ruhezustand *** StateRef := 1; AnzInc := KonfigTab(15); ELSIF REF02 ='1' THEN REFEND4 <= '1';-- ebene 2 StateRef := 0; ELSE IF REFEND5 = '1' THEN REFEND4 <= '1';-- ebene 2 END IF; StateRef := 0; END IF; WHEN 1 => --testen soll REF anfahren IF RA = '0' THEN -- keine REG Anfahren StateRef := 9; -- dann zu Index Anfahren ELSE -- REF sollte angefahren werden RefImp4(0) <= RDIR;-- Richtung Endlage suchen *** StateRef := 2; END IF; ------------------------------------- WHEN 2 => --1.Loop Anzahlclk Pulse Abstand Rcntr := Vref32 * Rclkdiv;--Anz clk zwischen Imp laden StateRef := 3; WHEN 3 =>-- Pause abarbeiten zwischen Pulsen IF Rcntr = 0 THEN RefImp4(1) <= '0';-- Impuls Ausgabe *** StateRef := 4; ELSE Rcntr := Rcntr - 1; StateRef := 3;-- anzahl clk abarbeiten END IF; WHEN 4 => RefImp4(1) <= '1';-- Impuls in Ruhestellun *** IF (ZuEnds(8) AND RDIR) = '1' THEN -- If Endlage R oder L *** StateRef := 5;-- dann REF in Endlage ELSE StateRef := 2; -- dann repeat für nächste Impuls END IF; WHEN 5 => --vorbereitung zum Mitte AnzInkr fahren RDIR := NOT RDIR; --Fahrrichtung umkehren AnzahlImp := 0; StateRef := 6; ---------------------------------------- WHEN 6 => -- 2. loop, fahre auf hälfte AnzInkr Rcntr := Vref32 * Rclkdiv;-- Impulsabstandzähler init RefImp4(0) <= RDIR;-- Fahr Richtung *** StateRef := 7; WHEN 7 => --Pause abarbeiten zwischen Pulsen IF Rcntr = 0 THEN RefImp4(1) <= '0';-- Impuls Ausgabe *** AnzahlImp := AnzahlImp + 1; StateRef := 8; ELSE Rcntr := Rcntr - 1; StateRef := 7;-- Anzahl clk abarbeiten=Impuls Abstand END IF; WHEN 8 => RefImp4(1) <= '1';-- Impuls in Ruhestellung """ IF AnzahlImp < conv_integer(KonfigTab(15)) THEN ---- Anzahl Inkr für A4 als konst StateRef := 6;-- dann nächste Impuls ELSE -- Ref Achse A0 fertig StateRef := 9; END IF; WHEN 9 => --testen soll Index anfahren IF ID = '0' THEN REFEND4 <= '1'; StateRef := 13; ELSE StateRef := 10;-- zum INDX Anfahren init END IF; ---------------------------------------------- WHEN 10 => -- Loop Index Anfahren IF Encods(14) = '1' THEN --IndexSpeichern INDX := Encods(14); ELSE INDX := INDX; END IF; -- Rcntr := Vindx32 * Rclkdiv;-- Impulsabstandzähler init RefImp4(0) <= IDIR;-- Fahr Richtung *** StateRef := 11;-- und zu Impulspause abarbeoiten WHEN 11 => -- Impuls Pause IF Encods(14) = '1' THEN --IndexSpeichern INDX := Encods(14); ELSE INDX := INDX; END IF; -- IF Rcntr = 0 THEN RefImp4(1) <= '0';-- Impuls Ausgabe *** StateRef := 12; ELSE Rcntr := Rcntr - 1; StateRef := 11;-- anzahl clk abarbeiten END IF; WHEN 12 => RefImp4(1) <= '1';-- Impuls in Ruhestellung *** IF Encods(14)='1' OR INDX='1' THEN -- wenn Index A1 Aktiv *** INDX := '0'; StateRef := 13;-- Index angefahren ELSE Stateref := 10; --und repesat in Loop Index Anfahren END IF; WHEN 13 => REFEND4 <= '1'; Stateref := 14;-- Warten bis alle Achsen Fertig WHEN 14 => IF REFRUN = '0' THEN Stateref := 15;-- ref fertig, und warten auf nächste Ref ELSE Stateref := 14;-- Warten bis alle Achsen Fertig END IF; WHEN 15 => Stateref := 0; WHEN OTHERS => StateRef := 0; END CASE; END IF; END IF; END PROCESS; -- refA4(achse A5) ----------------Ref Anfahren A5 = Achse A6---------------------------------------- RefA5 :PROCESS(clk) VARIABLE Rcntr :INTEGER:= 0; VARIABLE Vref32,Vindx32 :integer := 0; VARIABLE Stateref :INTEGER RANGE 0 TO 15 := 0; VARIABLE AnzahlImp :INTEGER RANGE 0 TO 65535:= 0; VARIABLE RA,ID,RDIR,IDIR :STD_LOGIC:= '0';--Kopie RAX,RAY,usw VARIABLE INDX :STD_LOGIC:= '0';-- speicher für index puls VARIABLE AnzInc :STD_LOGIC_VECTOR(31 DOWNTO 0) := X"00000010"; BEGIN IF rising_edge(clk) THEN -- auf neg.Takt Flanke speichernd **** IF nrst = '0' THEN Rcntr := Rclkdiv; Vref32 := 0; Vindx32:= 0; RefImp5(0) <= '0';--richtung= 0= rechte Endlage *** RefImp5(1) <= '1';-- Impuls = 0 *** StateRef := 0; AnzahlImp := 0; RA:='0';ID:='0';RDIR:='0';IDIR:='0'; INDX := '0'; AnzInc := X"00000010"; ELSE CASE StateRef IS WHEN 0 => --variable setzen gemäss Achse Nr IF REFRUN5 = '1' THEN Vref32 := conv_integer(X"000000" & AxKonREG(61));--Ref Grund-vorschub Vindx32 := conv_integer(X"000000" & AxKonREG(54));--Index Grund-vorschub RA := AxKonREG(48)(4); -- RA = RAY (Achse A1) ID := AxKonREG(48)(5); -- ID = IDY (Achse A1) RDIR := AxKonREG(49)(4);--Richtung gemäs RDIRY IDIR := AxKonREG(49)(5);--Richtung gemäs IDIRY StateRef := 1; AnzInc := KonfigTab(16); ELSIF REF02 ='1' THEN REFEND5 <= '1';-- ebene2 StateRef := 0; ELSE IF REFEND4 = '1' THEN REFEND5 <= '1';-- ebene 2 END IF; StateRef := 0; END IF; WHEN 1 => --testen soll REF anfahren IF RA = '0' THEN -- keine REG Anfahren StateRef := 9; -- dann zu Index Anfahren ELSE -- REF sollte angefahren werden RefImp5(0) <= RDIR;-- Richtung Endlage suchen *** StateRef := 2; END IF; ------------------------------------- WHEN 2 => --1.Loop Anzahlclk Pulse Abstand Rcntr := Vref32 * Rclkdiv;--Anz clk zwischen Imp laden StateRef := 3; WHEN 3 =>-- Pause abarbeiten zwischen Pulsen IF Rcntr = 0 THEN RefImp5(1) <= '0';-- Impuls Ausgabe *** StateRef := 4; ELSE Rcntr := Rcntr - 1; StateRef := 3;-- anzahl clk abarbeiten END IF; WHEN 4 => RefImp5(1) <= '1';-- Impuls in Ruhestellun *** IF (ZuEnds(10) AND RDIR) = '1' THEN -- If Endlage A1 R oder L *** StateRef := 5;-- dann REF in Endlage ELSE StateRef := 2; -- dann repeat für nächste Impuls END IF; WHEN 5 => --vorbereitung zum Mitte AnzInkr fahren RDIR := NOT RDIR; --Fahrrichtung umkehren AnzahlImp := 0; StateRef := 6; ---------------------------------------- WHEN 6 => -- 2. loop, fahre auf hälfte AnzInkr Rcntr := Vref32 * Rclkdiv;-- Impulsabstandzähler init RefImp5(0) <= RDIR;-- Fahr Richtung *** StateRef := 7; WHEN 7 => --Pause abarbeiten zwischen Pulsen IF Rcntr = 0 THEN RefImp5(1) <= '0';-- Impuls Ausgabe *** AnzahlImp := AnzahlImp + 1; StateRef := 8; ELSE Rcntr := Rcntr - 1; StateRef := 7;-- Anzahl clk abarbeiten=Impuls Abstand END IF; WHEN 8 => RefImp5(1) <= '1';-- Impuls in Ruhestellung *** IF AnzahlImp < conv_integer(KonfigTab(16)) THEN ---- Anzahl Inkr für A5 StateRef := 6;-- dann nächste Impuls ELSE -- Ref Achse A0 fertig StateRef := 9; END IF; WHEN 9 => --testen soll Index anfahren IF ID = '0' THEN REFEND5 <= '1'; StateRef := 13; ELSE StateRef := 10;-- zum INDX Anfahren init END IF; ---------------------------------------------- WHEN 10 => -- Loop Index Anfahren IF Encods(17) = '1' THEN --IndexSpeichern INDX := Encods(17); ELSE INDX := INDX; END IF; -- Rcntr := Vindx32 * Rclkdiv;-- Impulsabstandzähler init RefImp5(0) <= IDIR;-- Fahr Richtung *** StateRef := 11;-- und zu Impulspause abarbeoiten WHEN 11 => -- Impuls Pause IF Encods(17) = '1' THEN --IndexSpeichern INDX := Encods(17); ELSE INDX := INDX; END IF; -- IF Rcntr = 0 THEN RefImp5(1) <= '0';-- Impuls Ausgabe StateRef := 12; ELSE Rcntr := Rcntr - 1; StateRef := 11;-- anzahl clk abarbeiten END IF; WHEN 12 => RefImp5(1) <= '1';-- Impuls in Ruhestellung *** IF Encods(17)='1' OR INDX='1' THEN -- wenn Index A1 Aktiv *** INDX := '0'; StateRef := 13;-- Index angefahren ELSE Stateref := 10; --und repeat in Loop Index Anfahren END IF; WHEN 13 => REFEND5 <= '1'; Stateref := 14;-- Warten bis alle Achsen Fertig WHEN 14 => IF REFRUN = '0' THEN Stateref := 15;-- ref fertig, und weiter ELSE Stateref := 14;-- Warten bis alle Achsen Fertig END IF; WHEN 15 => Stateref := 0;--warten auf nächste Ref WHEN OTHERS => StateRef := 0; END CASE; END IF; END IF; END PROCESS; -- refA5 --============== Ende Ref Anfahren Processe ============================ ---*************************************************************************** --=========================================================================== --=============== sende Processe für SDI DA Ausgänge, 3 D/A Prallel -- Quelle : DAXY(5..0) 16 bit --TYPE T_Eb16 IS ARRAY(0 to 1) OF STD_LOGIC_VECTOR(15 DOWNTO 0);--2 X 16 bit reg für D/A --11000 = DAXY, 2x16 output für D/A A1,2 SDIDA12 :PROCESS(clk) CONSTANT A :std_logic_vector(2 DOWNTO 0):= "000"; -- SEL A TEIL CONSTANT B :std_logic_vector(2 DOWNTO 0):= "001"; -- SEL B TEIL VARIABLE i :INTEGER:= 0; VARIABLE BitNR :INTEGER RANGE 0 TO 31; --SIGNAL StateDA12 :INTEGER RANGE 0 to 23:= 0; VARIABLE ShiftReg :std_logic_vector(23 downto 0):= X"008000"; --SIG init :std_logic:= '0'; -- DAS nicht initialisiert BEGIN IF rising_edge(clk) THEN -- auf fallene Flanke Daten Einlesen IF nrst = '0' THEN StateDA12 <= 0; Syn12 <= '1';-- Chip select DAC 0 ruhe zustand ShiftReg := X"008000"; LDAC12 <= '1'; -- Ldac in Ruhe Zustand, update mit LDAC Signal CLRDA <= '1';--CLR inaktiv DA12 <= '1'; SDIok12 <= '0'; init12 <= '0'; -- DA Nicht initialisiert ELSE CASE StateDA12 IS WHEN 0 => IF init12 = '0' THEN -- noch nicht initialisiert LDAC12 <= '1'; -- Ldac in Ruhe Zustand, asynchrone modus CLRDA <= '0';---******************************************* i:= 100; StateDA12 <= 1; ELSE -- init fertig wenn init12 = '1' --init ctrl Reg fertig , normal Ablauf beginn--warten auf IST Imopulse--- IF (IstImp(1)= '0') OR (IstImp(3)='0')OR (sordAX = '0') THEN -- Wenn Impulse Achse A1,A0 SDIok12 <= '0'; LDAC12 <= '1'; -- Ldac in Ruhe Zustand, asynchrone modus StateDA12 <= 30;-- bereits initialisiert , dan starten Update A &B ELSE StateDA12 <= 0; END IF; END IF; -------------------------------------------------------- --=======init DA ctrl register=========================== WHEN 1 => --- CLRDA aktivieren IF i > 0 THEN i:= i - 1; StateDA12 <= 1;--1 us Warten ELSE CLRDA <= '1';-- init *********bei prototyp 3 fällt es weg StateDA12 <= 2; -- init Powerup END IF; ----------------------------------------------- WHEN 2 => --reset BitNr := 23; ShiftReg(15 DOWNTO 0) := X"0001";-- ShiftReg(21 DOWNTO 16) := "101000";-- reset all register StateDA12 <= 3; ---------------------------------------- WHEN 3 => -- aufsynchronisieren auf clkSDI IF clkSDI = '1' THEN StateDA12 <= 3; -- warten auf clkSDI = 0 ELSE LDAC12 <= '1'; --Asynchr Mode, StateDA12 <= 4;-- END IF; --------------------------------------------------- WHEN 4 => IF clkSDI = '0' THEN -- warten auf steigende Flanke von clk Syn12 <= '0';-- Inputdata aktiv StateDA12 <= 4; ELSE -- jetzt steigende Flanke von clk DA12 <= ShiftReg(BitNr);-- Daten zuschalten StateDA12 <= 5; END IF; ------ loop-begin------------------- WHEN 5 =>-- IF clkSDI = '1' THEN --warten auf fallende Flanke StateDA12 <= 5;-- warten ELSE --fallende Flanke jetzt, daten werden eingelesen --DA12 <= ShiftReg(BitNr);-- Daten zuschalten StateDA12 <= 6;--und weiter END IF; WHEN 6 => -- jetz ist clk=0 IF clkSDI = '0' THEN --warten auf steigende Flanke StateDA12 <= 6;-- warten ELSE -- jetzt steigende Flanke, clksdi ist jetzt 1 IF BitNr > 0 THEN BitNr := BitNr - 1; DA12 <= ShiftReg(BitNr);-- nächste Daten zuschalten StateDA12 <= 5;-- und repeat für alle bits ELSE -- alle bits abgearbeitet Syn12 <= '1';--inaktiv StateDA12 <= 9; END IF; END IF; --- loop ende, reset fertig --===============LDAC pin Aktiv============================= WHEN 9 =>-- BitNr := 23; ShiftReg(15 DOWNTO 0) := X"0000";-- -- ShiftReg(21 DOWNTO 16) := "110000";-- pwr up command StateDA12 <= 10; ----------------------------------------- WHEN 10 => -- wie 3,aufsynchronisieren auf clkSDI IF clkSDI = '1' THEN StateDA12 <= 10; -- warten auf clkSDI = 0 ELSE StateDA12 <= 11;-- END IF; --------------------------------------------------- WHEN 11 =>-- wie 4 IF clkSDI = '0' THEN -- warten auf steigende Flanke von clk Syn12 <= '0';-- Inputdata aktiv StateDA12 <= 11; ELSE -- jetzt steigende Flanke von clk DA12 <= ShiftReg(BitNr);-- Daten zuschalten StateDA12 <= 12; END IF; ------ loop-------------------- WHEN 12 => --wie 5 IF clkSDI = '1' THEN --warten auf fallende Flanke StateDA12 <= 12;--warten ELSE--fallende Flanke jetzt, daten werden eingelesen --DA12 <= ShiftReg(BitNr);-- Daten zuschalten StateDA12 <= 13;-- 5 warten solang clk =1 END IF; WHEN 13 => -- wie6,jetz ist clk=0 IF clkSDI = '0' THEN --warten auf steigende Flanke StateDA12 <= 13;--6 ELSE -- jetzt steigende Flanke IF BitNr > 0 THEN BitNr := BitNr - 1; DA12 <= ShiftReg(BitNr);-- nächse Daten zuschalten StateDA12 <= 12;--5 und repeat für alle bits ELSE -- alle bits abgearbeitet Syn12 <= '1';--inaktiv StateDA12 <= 16;---7 END IF; END IF; --- loop ende --================ Enable internal Reference ======================== WHEN 16 => --9 BitNr := 23; ShiftReg(15 DOWNTO 0) := X"0001";-- Enable internal Reference ShiftReg(21 DOWNTO 16) := "111000";-- comm Enable Ref StateDA12 <= 17;--10 --- loop reset ------- WHEN 17 => -- wie 3,10,aufsynchronisieren auf clkSDI IF clkSDI = '1' THEN StateDA12 <= 17; -- 10,warten auf clkSDI = 0 ELSE StateDA12 <= 18;--11 END IF; --------------------------------------------------- WHEN 18 => --wie 4,11 IF clkSDI = '0' THEN -- warten auf steigende Flanke von clk Syn12 <= '0';-- Inputdata aktiv StateDA12 <= 18;--11 ELSE -- jetzt steigende Flanke von clk DA12 <= ShiftReg(BitNr);-- Daten zuschalten StateDA12 <= 19; --12 END IF; ------ loop-------------------- WHEN 19 => --wie 5,12 IF clkSDI = '1' THEN --warten auf fallende Flanke StateDA12 <= 19;--warten ELSE --DA12 <= ShiftReg(BitNr);-- Daten zuschalten StateDA12 <= 20;-- und weiter END IF; WHEN 20 => -- 6,jetz ist clk=0 IF clkSDI = '0' THEN --warten auf steigende Flanke StateDA12 <= 20;--6 ELSE -- jetzt steigende Flanke IF BitNr > 0 THEN BitNr := BitNr - 1; DA12 <= ShiftReg(BitNr);-- nächste Daten zuschalten StateDA12 <= 19;--5 und repeat für alle bits ELSE -- alle bits abgearbeitet Syn12 <= '1';--inaktiv StateDA12 <= 21;---7 END IF; END IF; --- loop ende ------------------------------und speichern ----------------- WHEN 21 => --wie 7 LDAC12 <= '0';-- ldac aktiv, laden output mit Input daten i:= 100;--10 ns min dauer, 1us StateDA12 <= 22;--8 WHEN 22 => -- wie 8 IF i > 0 THEN i := i - 1; StateDA12 <= 22;--8 ELSE LDAC12 <= '1';--ldac inaktiv StateDA12 <=23; --9 END IF; WHEN 23 => --9 init12 <= '1'; -- DAC initialisiert StateDA12 <= 30;-- und warten auf IstImp,für erstemal update ---------------initialisation fertig-------------------------------------- --====================================================================== --=============update A normal ablauf============================================ --- D/A teil A -------------------------------------- WHEN 30 => --init,2 BitNr := 23; ShiftReg(15 DOWNTO 0) := sDAX10(15 DOWNTO 0);-- A1 Solwert laden ShiftReg(21 DOWNTO 16) := "000000";-- comm + Adr A StateDA12 <= 31;--3 ---------------------------------------- WHEN 31 => -- wie 3,aufsynchronisieren auf clkSDI IF clkSDI = '1' THEN StateDA12 <= 31; --3, warten auf clkSDI = 0 ELSE StateDA12 <= 32;--4 END IF; --------------------------------------------------- WHEN 32 => --wie 4 IF clkSDI = '0' THEN -- warten auf steigende Flanke von clk Syn12 <= '0';-- Inputdata aktiv StateDA12 <= 32;--4 ELSE -- jetzt steigende Flanke von clk DA12 <= ShiftReg(BitNr);-- Daten zuschalten StateDA12 <= 33;--5 END IF; ------ loop-Beginn------------------- WHEN 33 => --wie 5 IF clkSDI = '1' THEN --warten auf fallende Flanke StateDA12 <= 33;-- warten ELSE --DA12 <= ShiftReg(BitNr);-- Daten zuschalten StateDA12 <= 34;-- 5,warten solang clk =1 END IF; WHEN 34 => -- 6,jetz ist clk=0 IF clkSDI = '0' THEN --warten auf steigende Flanke StateDA12 <= 34;--6 ELSE -- jetzt steigende Flanke IF BitNr > 0 THEN BitNr := BitNr - 1; DA12 <= ShiftReg(BitNr);-- nächste Daten zuschalten StateDA12 <= 33;-- 5,und repeat für alle bits ELSE -- alle bits abgearbeitet Syn12 <= '1'; StateDA12 <= 40; -- END IF; END IF; --- loop ende --=================================================== ------ Kanal A fertig, D/A jetzt start B laden --- D/A teil B -------------------------------------- WHEN 40 => --init,2 BitNr := 23; ShiftReg(15 DOWNTO 0) := sDAX10(31 DOWNTO 16);-- A2 Solwert laden ShiftReg(21 DOWNTO 16) := "000001";-- comm + Adr B StateDA12 <= 41;--3 ---------------------------------------- WHEN 41 => -- 3,aufsynchronisieren auf clkSDI IF clkSDI = '1' THEN StateDA12 <= 41; --3, warten auf clkSDI = 0 ELSE StateDA12 <= 42;--4 END IF; --------------------------------------------------- WHEN 42 => --4 IF clkSDI = '0' THEN -- warten auf steigende Flanke von clk Syn12 <= '0';-- iput Data Aktiv StateDA12 <= 42;--4 ELSE -- jetzt steigende Flanke von clk DA12 <= ShiftReg(BitNr);-- Daten zuschalten StateDA12 <= 43;--5 END IF; ------ loop-------------------- WHEN 43 => --wie 5 IF clkSDI = '1' THEN --warten auf fallende Flanke StateDA12 <= 43;-- 6,jetzt werden Daten eingelesen ELSE --DA12 <= ShiftReg(BitNr);-- Daten zuschalten StateDA12 <= 44;-- 5,warten solang clk =1 END IF; WHEN 44 => -- 6,jetz ist clk=0 IF clkSDI = '0' THEN --warten auf steigende Flanke StateDA12 <= 44;--6 warten ELSE -- jetzt steigende Flanke IF BitNr > 0 THEN BitNr := BitNr - 1; DA12 <= ShiftReg(BitNr);-- nächste Daten zuschalten StateDA12 <= 43;-- 5,und repeat für alle bits ELSE -- alle bits abgearbeitet Syn12 <= '1';--inaktiv StateDA12 <= 45;--7 END IF; END IF; --- loop ende ------------------------------------------------ WHEN 45 => --7 und speichern LDAC12 <= '0';-- Laden in Output reg i:= 100;--10 ns min dauer, 1us StateDA12 <= 46; --8 WHEN 46 => -- und speichern daten für A & B mit LDAC IF i > 0 THEN i := i - 1; StateDA12 <= 46;--8 ELSE LDAC12 <= '1';--Laden in Output reg fertig StateDA12 <= 47;--9 END IF; WHEN 47 => --9 ------ Kanal B fertig, SDIok12 <= '1'; StateDA12 <= 0;--9, und warten auf nächste IST Impuls --============================================= WHEN OTHERS => StateDA12 <= 0; END CASE; END IF;-- Ende Nrst/ Else END IF; -- Ende If CLK END PROCESS;-- Ende DA12 --================================================================ --===================================================================== --================ Achsen A3, A4 ==================================== -- Quelle : DAXY(5..0) 16 bit --TYPE T_Eb16 IS ARRAY(0 to 1) OF STD_LOGIC_VECTOR(15 DOWNTO 0);--2 X 16 bit reg für D/A -- 11001 = DAXY, 2x16 output für D/A A3,4 SDIDA34 :PROCESS(clk) CONSTANT A :std_logic_vector(2 DOWNTO 0):= "000"; -- SEL A TEIL CONSTANT B :std_logic_vector(2 DOWNTO 0):= "001"; -- SEL B TEIL VARIABLE i :INTEGER:= 0; VARIABLE BitNR :INTEGER RANGE 0 TO 31; --SIGNAL StateDA34 :INTEGER RANGE 0 to 23:= 0; VARIABLE ShiftReg :std_logic_vector(23 downto 0):= X"008000"; --SIG init34 :std_logic:= '0'; -- DAS nicht initialisiert BEGIN IF rising_edge(clk) THEN -- auf fallene Flanke Daten Einlesen IF nrst = '0' THEN StateDA34 <= 0; Syn34 <= '1';-- Chip select DAC 0 ruhe zustand ShiftReg := X"008000"; LDAC34 <= '1'; -- Ldac in Ruhe Zustand, update mit LDAC Signal DA34 <= '1'; SDIok34 <= '0'; init34 <= '0'; -- DA Nicht initialisiert ELSE CASE StateDA34 IS WHEN 0 => IF init34 = '0' THEN -- noch nicht initialisiert LDAC34 <= '1'; -- Ldac in Ruhe Zustand, asynchrone modus --CLRDA <= '0';****nur für SDIDA12************ i:= 100; StateDA34 <= 1; ELSE -- init fertig wenn init12 = '1' --init ctrl Reg fertig , normal Ablauf beginn--warten auf IST Imopulse--- IF (IstImp(5)= '0') OR (IstImp(7)='0')OR (sordAX = '0') THEN -- Wenn Impulse Achse A3,A4 sDIok34 <= '0';-- init LDAC34 <= '1'; -- Ldac in Ruhe Zustand, asynchrone modus StateDA34 <= 30;-- bereits initialisiert , dan starten Update A &B ELSE StateDA34 <= 0; END IF; END IF; --======================================================== -----------initialisierunh- ctrl Register------------------------- WHEN 1 => --- CLRDA aktivieren IF i > 0 THEN i:= i - 1; StateDA34 <= 1;--100 ms Warten ELSE StateDA34 <= 2; -- init Powerup END IF; ------------------------------------------ --=============zuerst reset all register=============== WHEN 2 => --init BitNr := 23; ShiftReg(15 DOWNTO 0) := X"0001";-- ShiftReg(21 DOWNTO 16) := "101000";-- reset allregister StateDA34 <= 3; ---------------------------------------- WHEN 3 => -- aufsynchronisieren auf clkSDI IF clkSDI = '1' THEN StateDA34 <= 3; -- warten auf clkSDI = 0 ELSE LDAC34 <= '1'; --Asynchr Mode, StateDA34 <= 4;-- END IF; --------------------------------------------------- WHEN 4 => IF clkSDI = '0' THEN -- warten auf steigende Flanke von clk Syn34 <= '0';-- Inputdata aktiv StateDA34 <= 4; ELSE -- jetzt steigende Flanke von clk DA34 <= ShiftReg(BitNr);-- Daten zuschalten StateDA34 <= 5; END IF; ------ loop begin-------------------- WHEN 5 => IF clkSDI = '1' THEN --warten auf fallende Flanke StateDA34 <= 5;-- warten ELSE --fallende Flanke jetzt, daten werden eingelesen --DA34 <= ShiftReg(BitNr);-- Daten zuschalten StateDA34 <= 6;-- warten solang clk =1 END IF; WHEN 6 => -- jetz ist clk=0 IF clkSDI = '0' THEN --warten auf steigende Flanke StateDA34 <= 6; ELSE -- jetzt steigende Flanke IF BitNr > 0 THEN BitNr := BitNr - 1; DA34 <= ShiftReg(BitNr);-- nächste Daten zuschalten StateDA34 <= 5;-- und repeat für alle bits ELSE -- alle bits abgearbeitet Syn34 <= '1';-- Inputdata inaktiv StateDA34 <= 9; END IF; END IF; --- loop ende --=================LDAC Aktiv============================= WHEN 9 => LDAC34 <= '1';-- BitNr := 23; ShiftReg(15 DOWNTO 0) := X"0000";-- -- ShiftReg(21 DOWNTO 16) := "110000";-- pwr up command StateDA34 <= 10; --- loop reset ------- WHEN 10 => -- 3,aufsynchronisieren auf clkSDI IF clkSDI = '1' THEN StateDA34 <= 10; -- warten auf clkSDI = 0 ELSE LDAC34 <= '1'; --Asynchr Mode, StateDA34 <= 11;-- END IF; --------------------------------------------------- WHEN 11 => -- wie 4 IF clkSDI = '0' THEN -- warten auf steigende Flanke von clk Syn34 <= '0';-- Inputdata aktiv StateDA34 <= 11; ELSE -- jetzt steigende Flanke von clk DA34 <= ShiftReg(BitNr);-- Daten zuschalten StateDA34 <= 12; END IF; ------ loop-------------------- WHEN 12 => --wie 5 IF clkSDI = '1' THEN --warten auf fallende Flanke StateDA34 <= 12;--warten ELSE--fallende Flanke jetzt, daten werden eingelesen --DA34 <= ShiftReg(BitNr);-- Daten zuschalten StateDA34 <= 13;-- 5 warten solang clk =1 END IF; --------------------------------------- WHEN 13 => -- wie6,jetz ist clk=0 IF clkSDI = '0' THEN --warten auf steigende Flanke StateDA34 <= 13;--6 ELSE -- jetzt steigende Flanke IF BitNr > 0 THEN BitNr := BitNr - 1; DA34 <= ShiftReg(BitNr);-- nächse Daten zuschalten StateDA34 <= 12;--5 und repeat für alle bits ELSE -- alle bits abgearbeitet Syn34 <= '1';-- Inputdata inaktiv StateDA34 <= 16;---7 END IF; END IF; --- loop ende --================ Enable internal Reference ======================== WHEN 16 => --9 BitNr := 23; ShiftReg(15 DOWNTO 0) := X"0001";-- Enable internal Reference ShiftReg(21 DOWNTO 16) := "111000";-- comm Enable Ref StateDA34 <= 17;--10 --- loop reset ------- WHEN 17 => -- wie 3,10,aufsynchronisieren auf clkSDI IF clkSDI = '1' THEN StateDA34 <= 17; -- 10,warten auf clkSDI = 0 ELSE StateDA34 <= 18;--11 END IF; --------------------------------------------------- WHEN 18 => --wie 4,11 IF clkSDI = '0' THEN -- warten auf steigende Flanke von clk Syn34 <= '0';-- Inputdata aktiv StateDA34 <= 18;--11 ELSE -- jetzt steigende Flanke von clk DA34 <= ShiftReg(BitNr);-- Daten zuschalten StateDA34 <= 19; --12 END IF; ------ loop-------------------- WHEN 19 => --wie 5,12 IF clkSDI = '1' THEN --warten auf fallende Flanke StateDA34 <= 19;--warten ELSE --DA34 <= ShiftReg(BitNr);-- Daten zuschalten StateDA34 <= 20;-- und weiter END IF; WHEN 20 => -- 6,jetz ist clk=0 IF clkSDI = '0' THEN --warten auf steigende Flanke StateDA34 <= 20;--6 ELSE -- jetzt steigende Flanke IF BitNr > 0 THEN BitNr := BitNr - 1; DA34 <= ShiftReg(BitNr);-- nächste Daten zuschalten StateDA34 <= 19;--5 und repeat für alle bits ELSE -- alle bits abgearbeitet Syn34 <= '0';-- Inputdata inaktiv StateDA34 <= 21;---7 END IF; END IF; --- loop ende --- und speichern--------------------------- WHEN 21 => --wie 7 LDAC34 <= '0';-- ldac aktiv, laden output mit Input daten i:= 100;--10 ns min dauer,1us wg adum laufzeit StateDA34 <= 22;--8 WHEN 22 => -- wie 8 IF i > 0 THEN i := i - 1; StateDA34 <= 22;--8 ELSE LDAC34 <= '1';--ldac inaktiv StateDA34 <=23; --9 END IF; WHEN 23 => --9 init34 <= '1'; -- DAC initialisiert StateDA34 <= 30;-- und warten auf Ist imp ---------------initialisation fertig---------------------------------- --====================================================================== --========Normal ablauf ================================================= --- D/A teil A -------------------------------------- WHEN 30 => --init,2 BitNr := 23; ShiftReg(15 DOWNTO 0) := sDAX32(15 DOWNTO 0);-- A3 Solwert laden ShiftReg(21 DOWNTO 16) := "000000";-- comm + Adr A StateDA34 <= 31;--3 ---------------------------------------- WHEN 31 => -- wie 3,aufsynchronisieren auf clkSDI IF clkSDI = '1' THEN StateDA34 <= 31; --3, warten auf clkSDI = 0 ELSE StateDA34 <= 32;--4 END IF; --------------------------------------------------- WHEN 32 => --wie 4 IF clkSDI = '0' THEN -- warten auf steigende Flanke von clk Syn34 <= '0';-- Inputdata aktiv StateDA34 <= 32;--4 ELSE -- jetzt steigende Flanke von clk DA34 <= ShiftReg(BitNr);-- Daten zuschalten StateDA34 <= 33;--5 END IF; ------ loop-Beginn------------------- WHEN 33 => --wie 5 IF clkSDI = '1' THEN --warten auf fallende Flanke StateDA34 <= 33;-- warten ELSE --DA34 <= ShiftReg(BitNr);-- Daten zuschalten StateDA34 <= 34;-- 5,warten solang clk =1 END IF; WHEN 34 => -- 6,jetz ist clk=0 IF clkSDI = '0' THEN --warten auf steigende Flanke StateDA34 <= 34;--6 ELSE -- jetzt steigende Flanke IF BitNr > 0 THEN BitNr := BitNr - 1; DA34 <= ShiftReg(BitNr);-- nächste Daten zuschalten StateDA34 <= 33;-- 5,und repeat für alle bits ELSE -- alle bits abgearbeitet Syn34 <= '1';--inaktiv StateDA34 <= 40;--7 END IF; END IF; --- loop ende --=================================================== ------ Kanal A fertig, D/A jetzt start B laden --- D/A teil B -------------------------------------- WHEN 40 => --init,2 BitNr := 23; ShiftReg(15 DOWNTO 0) := sDAX32(31 DOWNTO 16);-- A4 Solwert laden ShiftReg(21 DOWNTO 16) := "000001";-- comm + Adr B StateDA34 <= 41;--3 ---------------------------------------- WHEN 41 => -- 3,aufsynchronisieren auf clkSDI IF clkSDI = '1' THEN StateDA34 <= 41; --3, warten auf clkSDI = 0 ELSE StateDA34 <= 42;--4 END IF; --------------------------------------------------- WHEN 42 => --4 IF clkSDI = '0' THEN -- warten auf steigende Flanke von clk Syn34 <= '0';-- iput Data Aktiv StateDA34 <= 42;--4 ELSE -- jetzt steigende Flanke von clk DA34 <= ShiftReg(BitNr);-- Daten zuschalten StateDA34 <= 43;--5 END IF; ------ loop-------------------- WHEN 43 => --wie 5 IF clkSDI = '1' THEN --warten auf fallende Flanke StateDA34 <= 43;-- 6,jetzt werden Daten eingelesen ELSE --DA34 <= ShiftReg(BitNr);-- Daten zuschalten StateDA34 <= 44;-- 5,warten solang clk =1 END IF; WHEN 44 => -- 6,jetz ist clk=0 IF clkSDI = '0' THEN --warten auf steigende Flanke StateDA34 <= 44;--6 warten ELSE -- jetzt steigende Flanke IF BitNr > 0 THEN BitNr := BitNr - 1; DA34 <= ShiftReg(BitNr);-- nächste Daten zuschalten StateDA34 <= 43;-- 5,und repeat für alle bits ELSE -- alle bits abgearbeitet Syn34 <= '1';--inaktiv StateDA34 <= 45;--7 END IF; END IF; --- loop ende -------------------------------------------------- WHEN 45 => --7 und update mit LDAC LDAC34 <= '0';-- Laden in Output reg i:= 100;--10 ns min dauer 1us wg laufzeit von adum StateDA34 <= 46; --8 WHEN 46 => --8 IF i > 0 THEN i := i - 1; StateDA34 <= 46;--8 ELSE LDAC34 <= '1';--Laden in Output reg fertig StateDA34 <= 47;--9 END IF; WHEN 47 => --9 ------ Kanal B fertig, sDIok34 <= '1';--sdi fertig StateDA34 <= 0;--9, und warten auf nächste IST Impuls --============================================= WHEN OTHERS => StateDA34 <= 0; END CASE; END IF;-- Ende Nrst/ Else END IF; -- Ende If CLK END PROCESS;-- Ende DA34 --==================Achsen A5 A6====================================== -- Quelle : DAXY(5..0) 16 bit --TYPE T_Eb16 IS ARRAY(0 to 1) OF STD_LOGIC_VECTOR(15 DOWNTO 0);--2 X 16 bit reg für D/A -- 11010 = DAXY, 2x16 output für D/A A5,6 ------------------------------------------------------- SDIDA56 :PROCESS(clk) CONSTANT A :std_logic_vector(2 DOWNTO 0):= "000"; -- SEL A TEIL CONSTANT B :std_logic_vector(2 DOWNTO 0):= "001"; -- SEL B TEIL VARIABLE i :INTEGER:= 0; VARIABLE BitNR :INTEGER RANGE 0 TO 31; --SIGNAL StateDA56 :INTEGER RANGE 0 to 63:= 0; VARIABLE ShiftReg :std_logic_vector(23 downto 0):= X"008000"; --SIG init56 :std_logic:= '0'; -- DAS nicht initialisiert BEGIN IF rising_edge(clk) THEN -- auf fallene Flanke Daten Einlesen IF nrst = '0' THEN StateDA56 <= 0; Syn56 <= '1';-- Chip select DAC 0 ruhe zustand ShiftReg := X"008000"; LDAC56 <= '1'; -- Ldac in Ruhe Zustand, update mit LDAC Signal ---CLRDA <= '1';--CLR inaktiv, nur in da12 DA56 <= '1'; sDIok56 <= '0';-- init56 <= '0'; -- nicht Nicht initialisiert ELSE CASE StateDA56 IS WHEN 0 => IF init56 = '0' THEN -- noch nicht initialisiert LDAC56 <= '1'; -- Ldac in Ruhe Zustand, asynchrone modus --CLRDA <= '0';******************************************* i:= 100; StateDA56 <= 1; ELSE -- init fertig wenn init12 = '1' --init ctrl Reg fertig , normal Ablauf beginn--warten auf IST Imopulse--- IF (IstImp(9)= '0') OR (IstImp(11)='0') OR (sordAX = '0') THEN -- Wenn Impulse Achse A5,A6 sDIok56 <= '0';-- init LDAC56 <= '1'; -- Ldac in Ruhe Zustand, asynchrone modus StateDA56 <= 30;-- bereits initialisiert , dan starten Update A &B ELSE StateDA56 <= 0; END IF; END IF; --======================================================== -----------initialisierunh- ctrl Register-------------------------------------------- --==================================================== WHEN 1 => --- CLRDA aktivieren IF i > 0 THEN i:= i - 1; StateDA56 <= 1;--100 ms Warten ELSE StateDA56 <= 2; -- init Powerup END IF; ------------reset alle register----------------------------------- WHEN 2 => --init BitNr := 23; ShiftReg(15 DOWNTO 0) := X"0001";-- ShiftReg(21 DOWNTO 16) := "101000";-- reset alle register StateDA56 <= 3; ---------------------------------------- WHEN 3 => -- aufsynchronisieren auf clkSDI IF clkSDI = '1' THEN StateDA56 <= 3; -- warten auf clkSDI = 0 ELSE LDAC56 <= '1'; --Asynchr Mode, StateDA56 <= 4;-- END IF; --------------------------------------------------- WHEN 4 => IF clkSDI = '0' THEN -- warten auf steigende Flanke von clk Syn56 <= '0';-- Inputdata aktiv StateDA56 <= 4; ELSE -- jetzt steigende Flanke von clk DA56 <= ShiftReg(BitNr);-- Daten zuschalten StateDA56 <= 5; END IF; ------ loop-begin------------------- WHEN 5 =>-- IF clkSDI = '1' THEN --warten auf fallende Flanke StateDA56 <= 5;-- warten ELSE --fallende Flanke jetzt, daten werden eingelesen --DA56 <= ShiftReg(BitNr);-- Daten zuschalten StateDA56 <= 6;--und weiter END IF; WHEN 6 => -- jetz ist clk=0 IF clkSDI = '0' THEN --warten auf steigende Flanke StateDA56 <= 6;-- warten ELSE -- jetzt steigende Flanke, clksdi ist jetzt 1 IF BitNr > 0 THEN BitNr := BitNr - 1; DA56 <= ShiftReg(BitNr);-- nächste Daten zuschalten StateDA56 <= 5;-- und repeat für alle bits ELSE -- alle bits abgearbeitet Syn56 <= '1';-- Inputdata inaktiv StateDA56 <= 9; END IF; END IF; --- loop ende --==================LDAC Pin Aktive -------------- WHEN 9 => BitNr := 23; ShiftReg(15 DOWNTO 0) := X"0000";-- -- ShiftReg(21 DOWNTO 16) := "110000";-- pwr up command StateDA56 <= 10; --- loop reset ------- WHEN 10 => -- 3,aufsynchronisieren auf clkSDI IF clkSDI = '1' THEN StateDA56 <= 10; -- warten auf clkSDI = 0 ELSE StateDA56 <= 11;-- END IF; --------------------------------------------------- WHEN 11 => IF clkSDI = '0' THEN -- warten auf steigende Flanke von clk Syn56 <= '0';--Inputdata aktiv StateDA56 <= 11; ELSE -- jetzt steigende Flanke von clk DA56 <= ShiftReg(BitNr); --Daten zuschalten StateDA56 <= 12; END IF; ------ loop-------------------- WHEN 12 => --wie 5 IF clkSDI = '1' THEN --warten auf fallende Flanke StateDA56 <= 12;--warten ELSE--fallende Flanke jetzt, daten werden eingelesen --DA56 <= ShiftReg(BitNr);-- Daten zuschalten StateDA56 <= 13;-- 5 warten solang clk =1 END IF; WHEN 13 => -- wie6,jetz ist clk=0 IF clkSDI = '0' THEN --warten auf steigende Flanke StateDA56 <= 13;--6 ELSE -- jetzt steigende Flanke IF BitNr > 0 THEN BitNr := BitNr - 1; DA56 <= ShiftReg(BitNr);-- nächse Daten zuschalten StateDA56 <= 12;--5 und repeat für alle bits ELSE -- alle bits abgearbeitet Syn56 <= '1';--Inputdata inaktiv StateDA56 <= 16;---7 END IF; END IF; --- loop ende --============Enable internal Reference ======== WHEN 16 => --9 LDAC56 <= '1';-- BitNr := 23; ShiftReg(15 DOWNTO 0) := X"0001";-- Enable internal Reference ShiftReg(21 DOWNTO 16) := "111000";-- comm Enable Ref StateDA56 <= 17;--10 --- loop reset ------- WHEN 17 => -- wie 3,10,aufsynchronisieren auf clkSDI IF clkSDI = '1' THEN StateDA56 <= 17; -- 10,warten auf clkSDI = 0 ELSE StateDA56 <= 18;--11 END IF; --------------------------------------------------- WHEN 18 => --wie 4,11 IF clkSDI = '0' THEN -- warten auf steigende Flanke von clk Syn56 <= '0';-- Inputdata aktiv StateDA56 <= 18;--11 ELSE -- jetzt steigende Flanke von clk DA56 <= ShiftReg(BitNr);-- Daten zuschalten StateDA56 <= 19; --12 END IF; ------ loop-------------------- WHEN 19 => --wie 5,12 IF clkSDI = '1' THEN --warten auf fallende Flanke StateDA56 <= 19;--warten ELSE --DA56 <= ShiftReg(BitNr);-- Daten zuschalten StateDA56 <= 20;-- und weiter END IF; WHEN 20 => -- 6,jetz ist clk=0 IF clkSDI = '0' THEN --warten auf steigende Flanke StateDA56 <= 20;--6 ELSE -- jetzt steigende Flanke IF BitNr > 0 THEN BitNr := BitNr - 1; DA56 <= ShiftReg(BitNr);-- nächste Daten zuschalten StateDA56 <= 19;--5 und repeat für alle bits ELSE -- alle bits abgearbeitet Syn56 <= '1';-- Inputdata inaktiv StateDA56 <= 21;---7 END IF; END IF; --- loop ende --------- und speichern mit LDAC------------- WHEN 21 => --wie 7 Syn56 <= '1';--inaktiv LDAC56 <= '0';-- ldac aktiv, laden output mit Input daten i:= 100;--10 ns min dauer, = 1 uS StateDA56 <= 22;--8 WHEN 22 => -- wie 8 IF i > 0 THEN i := i - 1; StateDA56 <= 22;--8 ELSE LDAC56 <= '1';--ldac inaktiv StateDA56 <=23; --9 END IF; WHEN 23 => --9 init56 <= '1'; -- DAC initialisiert StateDA56 <= 30;-- und zu normal ablauf --------------Initialisierung fertig------------------------- --====================================================================== --=============Normal Ablauf============================ --- D/A teil A -------------------------------------- WHEN 30 => --init,2 BitNr := 23; ShiftReg(15 DOWNTO 0) := sDAX54(15 DOWNTO 0);-- A4 Solwert laden ShiftReg(21 DOWNTO 16) := "000000";-- comm + Adr A StateDA56 <= 31;--3 ---------------------------------------- WHEN 31 => -- wie 3,aufsynchronisieren auf clkSDI IF clkSDI = '1' THEN StateDA56 <= 31; --3, warten auf clkSDI = 0 ELSE StateDA56 <= 32;--4 END IF; --------------------------------------------------- WHEN 32 => --wie 4 IF clkSDI = '0' THEN -- warten auf steigende Flanke von clk Syn56 <= '0';-- Inputdata aktiv StateDA56 <= 32;--4 ELSE -- jetzt steigende Flanke von clk DA56 <= ShiftReg(BitNr);-- Daten zuschalten StateDA56 <= 33;--5 END IF; ------ loop-Beginn------------------- WHEN 33 => --wie 5 IF clkSDI = '1' THEN --warten auf fallende Flanke StateDA56 <= 33;-- warten ELSE --DA56 <= ShiftReg(BitNr);-- Daten zuschalten StateDA56 <= 34;-- 5,warten solang clk =1 END IF; WHEN 34 => -- 6,jetz ist clk=0 IF clkSDI = '0' THEN --warten auf steigende Flanke StateDA56 <= 34;--6 ELSE -- jetzt steigende Flanke IF BitNr > 0 THEN BitNr := BitNr - 1; DA56 <= ShiftReg(BitNr);-- nächste Daten zuschalten StateDA56 <= 33;-- 5,und repeat für alle bits ELSE -- alle bits abgearbeitet Syn56 <= '1';-- Inputdata inaktiv StateDA56 <= 40;--7 END IF; END IF; --- loop ende --=================================================== ------ Kanal A fertig, D/A jetzt start B laden --- D/A teil B -------------------------------------- WHEN 40 => --init,2 BitNr := 23; ShiftReg(15 DOWNTO 0) := sDAX54(31 DOWNTO 16);-- A5 Solwert laden ShiftReg(21 DOWNTO 16) := "000001";-- comm + Adr B StateDA56 <= 41;--3 ---------------------------------------- WHEN 41 => -- 3,aufsynchronisieren auf clkSDI IF clkSDI = '1' THEN StateDA56 <= 41; --3, warten auf clkSDI = 0 ELSE StateDA56 <= 42;--4 END IF; --------------------------------------------------- WHEN 42 => --4 IF clkSDI = '0' THEN -- warten auf steigende Flanke von clk Syn56 <= '0';-- iput Data Aktiv StateDA56 <= 42;--4 ELSE -- jetzt steigende Flanke von clk DA56 <= ShiftReg(BitNr);-- Daten zuschalten StateDA56 <= 43;--5 END IF; ------ loop-------------------- WHEN 43 => --wie 5 IF clkSDI = '1' THEN --warten auf fallende Flanke StateDA56 <= 43;-- 6,jetzt werden Daten eingelesen ELSE --DA56 <= ShiftReg(BitNr);-- Daten zuschalten StateDA56 <= 44;-- 5,warten solang clk =1 END IF; WHEN 44 => -- 6,jetz ist clk=0 IF clkSDI = '0' THEN --warten auf steigende Flanke StateDA56 <= 44;--6 warten ELSE -- jetzt steigende Flanke IF BitNr > 0 THEN BitNr := BitNr - 1; DA56 <= ShiftReg(BitNr);-- nächste Daten zuschalten StateDA56 <= 43;-- 5,und repeat für alle bits ELSE -- alle bits abgearbeitet Syn56 <= '1';-- iput Data Aktiv StateDA56 <= 45;--7 END IF; END IF; --- loop ende ------------- und speichern -------------------- WHEN 45 => --7 LDAC56 <= '0';-- Laden in Output reg i:= 100;--10 ns min dauer, 1us StateDA56 <= 46; --8 WHEN 46 => --8 IF i > 0 THEN i := i - 1; StateDA56 <= 46;--8 ELSE LDAC56 <= '1';--Laden in Output reg fertig StateDA56 <= 47;--9 END IF; WHEN 47 => --9 ------ Kanal B fertig, sDIok56 <= '1';-- StateDA56 <= 0;--9, und warten auf nächste IST Impuls --============================================= WHEN OTHERS => StateDA56 <= 0; END CASE; END IF;-- Ende Nrst/ Else END IF; -- Ende If CLK END PROCESS;-- Ende DA56 ----=============================================================== --==================================================================== -- Read 4 Analoge Inputs von AD7923 (KIN), Kraftsensor 12 bit --CSAD Output FPGA --DINAD Input FPGA --KIN INPUT FPGA, Output von A/D von 3 Kräfte sensoren zustand --ADINP IS ARRAY(0 to 3) OF STD_LOGIC_VECTOR(11 DOWNTO 0);--Daten Kraftsensoren:12 bit 2er compl) -- Register sind 12 bit, eingelesen mit 16 bit (nur 12 fallende Flanke von clk werden wirksam) SDIAD :PROCESS(clk) VARIABLE BitNR :INTEGER RANGE 0 TO 31; VARIABLE DataReg :std_logic_vector(15 downto 0):= (OTHERS => '0'); VARIABLE Ctrlreg :std_logic_vector(15 downto 0):= X"8300"; VARIABLE chanelNr :integer RANGE 0 TO 4; VARIABLE CLKADalt :std_logic:= '0'; BEGIN IF rising_edge(clk) THEN -- auf fallene Flanke Daten Einlesen IF nrst = '0' THEN StateAD <= 0; Ctrlreg := X"8300"; chanelNr := 0; SDIADOK <= '0'; DataReg := (OTHERS => '0'); FOR i IN 0 TO 3 LOOP ADINP(i) <= X"000"; END LOOP; ELSE CASE StateAD IS WHEN 0 => IF ImpIST = '1' THEN --wenn Istwert Impuls BitNR := 15; DataReg := (OTHERS => '0'); chanelNr := 0; Ctrlreg := X"8300";--Chanel Nr 0,PM1,0=11,no sequenz SDIADOK <= '0'; CSAD <= '0';-- cs aktiv,Start Impuls für TestBench ***** StateAD <= 1;-- dann zuerst ctrl laden ELSE StateAD <= 0;-- dann warten END IF; WHEN 1 => --Init write to Controllregister, IF CLKAD = '0' THEN StateAD <= 1; ELSE StateAD <= 2;--und warten auf neg Flanke CLKAD END IF; WHEN 2 => -- Loop Ctrl Einlesen --------------------------- IF CLKAD = '0' THEN -- auf falende Flanke bits schreiben DINAD <= CtrlReg(BitNr);--MSB bit CTRL reg, chanel0 StateAD <= 3; ELSE StateAD <= 2;-- warte so lange CLKAD =1 END IF; WHEN 3 => IF CLKAD = '0' THEN --warten so lang CLKAD =0 StateAD <= 3; ELSE --ab jetzt ist clkAD =1 IF BitNr > 0 THEN BitNr := BitNr - 1; StateAD <= 2;-- und nächste Bit Einlesen (loop)---- ELSE --init ctrl fertig CSAD <= '1';-- cs inaktiv ************************ BitNr := 10;-- Anzahl clk für Tquiet StateAD <= 4;-- und zu Chanel Daten Einlesen END IF; END IF; WHEN 4 => -- Warten Tquiet = 50ns = 10clk IF BitNr > 0 THEN BitNr := BitNr - 1; StateAD <= 4; ELSE BitNr := 15;-- -- nachste ChanelNr in Ctrl Reg Add1,2= chanelNr CtrlReg(11 DOWNTO 10) :=conv_std_logic_vector((ChanelNr +1),2); --CtrlReg:= X"8700";-- Chanel NR 1,nächste ChanelNr := 0;--ChanelNr init CSAD <= '0';-- cs aktiv ***************************** StateAD <= 5; END IF; ----Loop Input Daten Einlesen und Ctrl Reg Schreiben WHEN 5 => -- loop chanel daten & ctrl einlesen ----------- IF CLKAD = '0' THEN -- auf falende Flanke bits einlesen vom DataReg(BitNr) := KIN;--Bit einlesen vorherige channel DINAD <= CtrlReg(BitNr);--bit CTRL reg, nächste channel StateAD <= 6; ELSE StateAD <= 5; END IF; WHEN 6 => IF CLKAD = '0' THEN --warten bis CLKAD =0 StateAD <= 6; ELSE IF BitNr > 0 THEN BitNr := BitNr - 1; StateAD <= 5;-- und nächste Bit Einlesen ELSE --Daten und ctrl fertig eingelesen für ein chanel ADINP(ChanelNr)<= DataReg(11 DOWNTO 0);-- Aktuelle chanel speichern CSAD <= '1';-- cs inaktiv ************************************ BitNr := 10;-- Anzahl clk für Tquiet StateAD <= 7;-- und zu Warten Tquiet END IF; END IF; WHEN 7 => -- Warten Tquiet = 50ns = 10clk IF BitNr > 0 THEN BitNr := BitNr - 1; StateAD <= 7; ELSE IF ChanelNr < 2 THEN -- nur chanel 0,1,2 = XYZ CSAD <= '0';-- cs aktiv BitNr := 15; ChanelNr := ChanelNr + 1;-- und nächste chanelNR CtrlReg(11 DOWNTO 10):= CtrlReg(11 DOWNTO 10) + 1;-- inkr Chanel StateAD <= 5; -- und nächste chanel ELSE CSAD <= '1';-- cs inaktiv SDIADOK <= '1';-- Neue Daten OK StateAD <= 0;-- und warten auf nächste ImpLK END IF; END IF; WHEN OTHERS => StateAD <= 0; END CASE; END IF;-- Ende Nrst/ Else END IF; -- Ende If CLK END PROCESS;-- Ende SDIAD --==================================================================== -- Empfang KonfigDaten(KonfigDat) von uP und ablegen in KonfigTab -- bei neuladen der geäderte Roboterdaten wird über ncs=0 angezeigt -- das die FPGA soll neue Daten von up übernehmen. --nach der daten uebernahme soll die AS21 umbedingt neu gestartet werden! --------------------------------------------- -- ASkonfig data werde ausschliesslich von Procedure RECEIV von CPU16.1 -- übernohmen worden könenn auch auch am PC editiert werden -- Adr Bereich 0..191 ----------------------------------------------------------------- --nach der daten uebernahme soll die AS21 umbedingt neu gestartet werden! --TYPE T_KonfigTab is array(0 to 191) of Std_logic_vector(31 DOWNTO 0); RdKonfigTab: PROCESS(clk) VARIABLE i :INTEGER RANGE 0 TO 100:= 0; VARIABLE j :INTEGER RANGE 0 TO 100:= 0; VARIABLE Wert :std_logic_vector(31 DOWNTO 0):= X"00000000"; BEGIN IF rising_edge(clk) THEN IF nrst = '0' THEN -- init werte für ITP Modul---- ----------------------- FOR i IN 0 TO 47 LOOP KonfigTab(i) <= (OTHERS => '0'); END LOOP; StateRDuP <= 0; sKonRegOK <= '0'; --------- j := 0; i := 0; Axdata <= X"00";--init für Zwischenspeicher Axadr <= X"00"; Axwr <= '0'; AllTabOK <= '0'; -- tabellen noch nicht gersendet ELSE CASE StateRDuP IS WHEN 0 => -- begin Empfang Konfiguration von uP IF ncs = '0' AND nwr = '0' THEN i := 0; -- integer zähler j := 0; -- Byte Zähler StateRDuP <= 2;-- start konfigTAB RD ELSE StateRDuP <= 0;-- warten auf wr aktiv END IF; ----------------konfigTAB transfer UP to FPGA---- WHEN 2 => IF nwr = '0' THEN Wert(j+7 DOWNTO j):= dbus;-- Byte0 ****""" StateRDuP <= 2;-- warten bis nwr fertig ELSE j:= j + 8; StateRDuP <= 3;-- dann warten WR=1 fertig END IF; WHEN 3 => IF nwr = '1' THEN StateRDuP <= 3; --dann warten ELSE -- neue WR StateRDuP <= 4;-- dann nächste WR END IF; WHEN 4 => IF nwr = '0' THEN Wert(j+7 DOWNTO j):= dbus;-- Byte1 ****""" StateRDuP <= 4;-- warten bis nwr fertig ELSE j:= j + 8; StateRDuP <= 5;-- dann warten WR=1 fertig END IF; WHEN 5 => IF nwr = '1' THEN StateRDuP <= 5; --dann warten ELSE -- neue wr StateRDuP <= 6;-- dann nächste WR END IF; WHEN 6 => IF nwr = '0' THEN Wert(j+7 DOWNTO j):= dbus;-- Byte2 ****""" StateRDuP <= 6;-- warten bis nwr fertig ELSE j:= j + 8; StateRDuP <= 7;-- dann warten bis WR=1 fertig END IF; WHEN 7 => IF nwr = '1' THEN StateRDuP <= 7; --dann warten ELSE -- neue WR StateRDuP <= 8;-- dann nächste WR END IF; WHEN 8 => IF nwr = '0' THEN Wert(j+7 DOWNTO j):= dbus;-- Byte3 ****""" StateRDuP <= 8;-- warten bis nwr fertig ELSE j:= 0;-- init für nächste integer KonfigTab(i) <= wert; StateRDuP <= 9;-- dann warten bis WR=1 fertig END IF; WHEN 9 => IF nwr = '1' THEN StateRDuP <= 9;-- dan warten bis WR01 fertig ELSE IF i < 47 THEN Wert := X"00000000"; i := i + 1; -- nächste Integer StateRDuP <= 2; -- dan repeat ELSE StateRDuP <= 10; END IF; END IF; WHEN 10=> --SkonRegOK <= '0'; IF ncs = '0' THEN StateRDuP <= 10;-- warten bis NCS fertig ELSE i := 0; -- byte zähler StateRDuP <= 20;-- warten auf nächste Tabellen END IF; --====== empfang von ASkonREG ==================== -- ASkonREG reg wird beschrieben von RECEIV, deshalb -- werden die Daten über ein Zwischenspeicher --in axKomREG im RECEIV geschrieben WHEN 20 =>--lesen AXKonTAB vom Up8051 IF ncs = '0' AND nwr = '0' THEN Axwr <= '1'; Axdata <= dbus; Axadr <= conv_std_logic_vector(i,8); StateRDuP <= 21; ELSE StateRDuP <= 20; END IF; WHEN 21 => IF nwr = '0' THEN Axdata <= dbus; Axwr <= '1'; StateRDuP <= 21;-- warten bis nwr fertig ELSE IF i < 71 THEN i := i + 1; Axwr <= '0'; StateRDuP <= 20; --uud repeat ELSE -- Empfang fertig StateRDuP <= 22; END IF; END IF; WHEN 22 => --SkonRegOK <= '0'; IF ncs = '0' THEN StateRDuP <= 22;-- warten bis NCS fertig ELSE Axwr <= '0'; Axdata <= X"00"; AXadr <= X"00"; SkonRegOK <= '0'; StateRDuP <= 0;-- und fertig AllTabOK <= '1'; --tabellen wurden von uP empfangen END IF; WHEN OTHERS => StateRDuP <= 0; END CASE; END IF; --end IF/ELSE NRST END IF;-- END IF CLK END PROCESS;--RdKonfigTab --====Processe für berechnung der Achsen deformation in Abhängigkeit von Kraft======== --================================================================================== -- Berechnen der Achsen Istwinkel in rad:(AxDrad(i) FP aus der istposition(IST) bei DxDradOK=1 ---AxDrad[rad] = Ist[incr] * RresAxrad[rad/incr] ------------------------------------------------------- --TYPE T_FP IS ARRAY(0 to 5) OF STD_LOGIC_VECTOR(31 DOWNTO 0);--FP Berechnung Einzel Achse AxDcalc :PROCESS (clk) VARIABLE cntrclk : INTEGER RANGE 0 TO 1023:= 0; VARIABLE stateAxD :INTEGER RANGE 0 TO 15:= 0; VARIABLE i :INTEGER RANGE 0 TO 7 := 0; BEGIN IF rising_edge(clk) THEN IF nrst = '0' THEN stateAxD := 0; cntrclk := 0; FOR i IN 0 TO 5 LOOP ISTD_FP(i) <= X"00000000"; ResAxRad(i) <= X"00000000"; AxDrad(i) <= X"00000000"; ResAxrad(i) <= X"00000000"; END LOOP; ELSE CASE stateAxD IS WHEN 0 => IF ImpIst = '1' THEN --wenn Ist Impulse AxDradOK <= '0';-- i := 0; ResAxrad(0) <= KonfigTAB(29);--C_radA0;--37ce375b:0.00002458289 rad/inkr ResAxrad(1) <= KonfigTAB(30);--C_radA1;--37d4f591:0.00002538672 rad/inkr ResAxrad(2) <= KonfigTAB(31);--C_radA2;--3858f514:0.00005172666 rad/inkr ResAxrad(3) <= KonfigTAB(32);--C_radA3;--38532aa9:0.00005034605 rad/inkr ResAxrad(4) <= KonfigTAB(33);--C_radA4;--3a548ef2:0.00081084587 rad/inkr ResAxrad(5) <= KonfigTAB(34);--C_radA5;--38b847d6:0.00008787184 rad/inkr stateAxD := 1; ELSE stateAxD := 0; END IF; WHEN 1 => -- ausführen IstD(i) => FP ceIstFP <= '1';--ce IntToFP aktiv InpFP1 <= IST(i); stateAxD := 2; WHEN 2 => ceIstFP <= '0';--reset ce stateAxD := 3; WHEN 3 => --und repeat für alle 6 Achsen IF i < 5 THEN IstD_FP(i) <= OutFP1; i := i + 1; stateAxD := 1;-- und repeat für alle Achsen ELSE IstD_FP(i) <= OutFP1; i := 0; --reset i stateAxD := 4;-- alle Achsen konvertiert zu FP END IF; ------- WHEN 4 => -- Achsen Winkel berechnen InpFP1 <= IstD_FP(i); InpFP2 <= ResAxRad(i); cntrclk:= 4; ceIstAxD <= '1'; -- Start IstD * ResAdrad stateAxD := 5;-- und warten WHEN 5 => ceIstAxD <= '0';--ce IstAxD reset IF cntrclk > 0 THEN cntrclk := cntrclk - 1; stateAxD := 5;-- und warten ELSE stateAxD := 6; END IF; WHEN 6 => --winkel Berechnen ausführen IF i < 5 THEN AxDrad(i) <= OutFP2; i := i + 1; stateAxD := 4;-- und repeat ELSE AxDrad(i) <= OutFP2; i := 0; --reset i stateAxD := 7;-- alle Achsenwinkel berechnet END IF; WHEN 7 => -- Tabelle Ax TO AxD AxDradOK <= '1';-- daten ok StateAxD := 0;-- und daten neu einlesen WHEN OTHERS => StateAxD := 0; END CASE; END IF;-- Ende nrst/else END IF; -- Ende clk END PROCESS;--Ende AxDcalc --========================================================= --Xdef : Rechnet Deformation in Anzahl Increment in Richtung X in Abhängigkeit von Winkel ----------------------------------------------- --TYPE T_ADINP IS ARRAY(0 to 3) OF STD_LOGIC_VECTOR(11 DOWNTO 0);--Daten Kraftsensoren --TYPE T_Dx IS ARRAY(0 TO 2) OF INTEGER;-- Kraftberechnung in der XYZ --TYPE T_Ax IS ARRAY(0 to 2) OF STD_LOGIC_VECTOR(31 DOWNTO 0); -- auch fü FP --Tabelle: TAxrad :T_Ax; --------------------------- -- SIGNAL IstAx :T_Ax; -- SIGNAL CosAx :T_Ax; -- SIGNAL DAxdef :T_Ax;-- deformation Daten für A1,A,A4 -- SIGNAL FSX :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- SIGNAL FSX_FP :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- SIGNAL Fx_FP :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- SIGNAL DaxFP :T_Ax; -- SIGNAL DacFP :T_Ax; -- SIGNAL Axdef :T_Ax; -- SIGNAL IncrAx :T_Ax; -- SIGNAL inpX1 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- zwischen Speicher für Input FD Fkt -- SIGNAL inpX2 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- SIGNAL outX :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; ------------------------------------------- cXdef :PROCESS(clk) VARIABLE StateXdef :INTEGER RANGE 0 TO 31 := 0; VARIABLE cntrclk :INTEGER RANGE 0 TO 50:= 0; VARIABLE i :INTEGER RANGE 0 TO 15; BEGIN IF rising_edge(clk) THEN IF nrst = '0' THEN StateXdef := 0; cntrclk := 0; i := 0; FOR i IN 0 TO 2 LOOP TAxrad(i) <= X"00000000"; END LOOP; ELSE CASE stateXdef IS WHEN 0 => IF AxDradOK = '1' AND SDIADOK = '1' THEN -----Konsatnten Tabellen für Deformation Richtun X--, ----relevante Achsen: A1,A2,A4 DaXdef(0) <= KonfigTAB(42);--C_DA1;--spez. Deformation ( Def/ 22.25) [mm/N] DaXdef(1) <= KonfigTAB(43);--C_DA2; DaXdef(2) <= KonfigTAB(45);--c_DA4; --- TAxrad(0) <= AxDrad(1); --Winkel A1 TAxrad(1) <= AxDrad(2); --Winkel A2 TAxrad(2) <= AxDrad(4); --Winkel A4 --. D_LAx(0) <= KonfigTAB(36);--C_L1;--mm, armlänge D_LAx(1) <= KonfigTAB(37);--C_L2; D_LAx(2) <= KonfigTAB(39);--C_L4; --- RsAx(0) <= KonfigTAB(24);--C_A1rad;--incr/rad RsAx(1) <= KonfigTAB(25);--C_A2rad; RsAx(2) <= KonfigTAB(27);--C_A4rad; --------------------------------------- stateXdef := 1; ELSE stateXdef := 0;-- dann warten END IF; WHEN 1 => --- korrektur für DEf Tabelle ceXD0 <= '1'; -- Start für SubFP : Axdrad <=AxDrad(2) - PiDiv InpX1 <= TAxrad(1); stateXdef := 2; WHEN 2 => -- ausführen SubFFP ceXD0 <= '0';-- reset CE stateXdef := 3; WHEN 3 => TAxrad(1) <= outX1;-- resultat : AxDrad(2) - Pidiv2 stateXdef := 4; WHEN 4 => i := 0; stateXdef := 5; WHEN 5 => -- start cosFP,loop InpX1 <= TAxrad(i); cexD1 <= '1';-- start für cosFP cntrclk := clkTocos;-- wartezeit stateXdef := 6; WHEN 6 => -- wartezeit für cosFP, ausführen cexD1 <= '0';--reset ce IF cntrclk > 0 THEN cntrclk := cntrclk - 1; stateXdef := 6; ELSE -- zeit abgelaufen IF i < 2 THEN cosAx(i) <= outX2;-- resultat speichern i := i + 1; stateXdef := 5; -- und repeat ELSE cosAx(i) <= outX2;-- resultat speichern stateXdef := 7;-- cos fertig berechnet END IF; END IF; WHEN 7 =>-- input Extension auf 32 bits IF ADINP(0)(11) = '0' THEN --wert Positiv FSX <= X"00000" & ADINP(0); ELSE FSX <= X"FFFFF" & ADINP(0); END IF; ceXD2 <= '1';-- Int To FP aktiv stateXdef := 8; ---- WHEN 8 => --IntToFP ausführen ceXD2 <= '0';-- ce reset ceXD6 <= '1';-- Mul start Int To N stateXdef := 9; ---- WHEN 9 =>-- mul ausführen:FS_FPN[N]=FS_Fp[int] * C_IntToN ceXD6 <= '0';-- reset Ce ceXD3 <= '1'; --mul starten stateXdef := 10; ---- WHEN 10 => --Div ausführen :Fx_FP[N]=Fs_FPN / UXFP ceXD3 <= '0';--ce reset i := 0; stateXdef := 11; -------------------------- WHEN 11 => stateXdef := 12; WHEN 12 => -- mul loop: DAxFP[mm]=FxFP[N] * DAxFP(i)[mm/N] cexd4 <= '1';-- mulFP aktiv InpX1 <= Fx_FP; InpX2 <= DaXdef(i); stateXdef := 13; WHEN 13 => cexd4 <= '0';-- ce reset stateXdef := 14; WHEN 14 => -- mul: DAxFP(i) * Fx_FP ausführen IF i < 2 THEN DAxFP(i) <= OutX3; i := i + 1; stateXdef := 12; ELSE DAxFP(i) <= OutX3; i:= 0; stateXdef := 15; END IF;--DaxFP(i) fertig ----------------------- WHEN 15 => -- mulFP: loop:DAcFP[mm]= DaxFP[mm] * cosAx InpX1 <= DAxFP(i); InpX2 <= cosAx(i); cexD5 <= '1'; stateXdef := 16; WHEN 16 => cexD5 <= '0';-- reset ce stateXdef := 17; WHEN 17 => -- MulFp: DAcFp= DaxFP * cosAx ausführen IF i < 2 THEN DAXcFP(i) <= OutX4; i := i + 1; stateXdef := 15; ELSE DAXcFP(i) <= OutX4; i:= 0; stateXdef := 18; END IF; ------------------------- WHEN 18 => -- AXdef=arctang(DaXcFP,D_LAx), deformations winkel[rad] InpX2 <= DAXcFP(i); InpX1 <= D_LAx(i); cexD7 <= '1'; cntrclk := clkAtan; stateXdef := 19; WHEN 19 => -- ausführen arctang cexD7 <= '0';-- reset ce IF cntrclk > 0 THEN cntrclk := cntrclk - 1; stateXdef := 19;-- warten ELSE stateXdef := 20; END IF; WHEN 20 => IF i < 2 THEN AXdef(i) <= OutX5; i := i + 1; stateXdef := 18;-- und repeat ELSE AXdef(i) <= OutX5; i:= 0; stateXdef := 21; END IF; -------------------- WHEN 21 => -- IncrAX = Axdef * ResAxrad InpX1 <= AXdef(i); InpX2 <= RsAX(i); cexD8 <= '1'; stateXdef := 22; WHEN 22 => cexD8 <= '0';-- reset ce stateXdef := 23; WHEN 23 => IF i < 2 THEN IncrAX(i) <= OutX6; i := i + 1; stateXdef := 21;-- und repeat ELSE IncrAX(i) <= OutX6; stateXdef := 24; END IF; WHEN 24 => -- Korrektur Werte Richtung X fertig Berechnet IF AxDradOK = '1' AND SDIADOK = '1' THEN stateXdef := 24;-- warten bis istwert zyklus fertig ist ELSE stateXdef := 0;--neue Istwert Zyklus END IF; WHEN OTHERS => StateXdef := 0; END CASE; END IF;-- Ende nrst/else END IF; -- Ende clk END PROCESS;--Ende cXDef --*********************************************************** --========================================================= --Ydef : Rechnet Deformation in Anzahl Increment in Richtung Y ----------------------------------------------- --TYPE T_ADINP IS ARRAY(0 to 3) OF STD_LOGIC_VECTOR(11 DOWNTO 0);--Daten Kraftsensoren --TYPE T_Dx IS ARRAY(0 TO 2) OF INTEGER;-- Kraftberechnung in der XYZ --TYPE T_Ax IS ARRAY(0 to 2) OF STD_LOGIC_VECTOR(31 DOWNTO 0); -- auch fü FP --Tabelle: TAxrad :T_Ax; --------------------------- -- SIGNAL IstAy :T_Ax; -- SIGNAL CosAy :T_Ax; -- SIGNAL DAydef :T_Ax;-- deformation Daten für A1,A,A4 -- SIGNAL FS :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- SIGNAL FS_FP :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- SIGNAL Fx_FP :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- SIGNAL DayFP :T_Ax; -- SIGNAL DacFP :T_Ax; -- SIGNAL Aydef :T_Ax; -- SIGNAL IncrAy :T_Ax; -- SIGNAL inpY1 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- zwischen Speicher für Input FD Fkt -- SIGNAL inpY2 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- SIGNAL outY :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; ------------------------------------------- cYdef :PROCESS(clk) VARIABLE StateYdef :INTEGER RANGE 0 TO 31 := 0; VARIABLE cntrclk :INTEGER RANGE 0 TO 50:= 0; VARIABLE i :INTEGER RANGE 0 TO 15; BEGIN IF rising_edge(clk) THEN IF nrst = '0' THEN StateYdef := 0; cntrclk := 0; i := 0; FOR i IN 0 TO 2 LOOP TAYrad(i) <= X"00000000"; END LOOP; ELSE CASE stateYdef IS WHEN 0 => IF AxDradOK = '1' AND SDIADOK = '1' THEN -----Konsatnten Tabellen für Deformation Richtun X--, ----relevante Achsen: A0,A3,Pidiv2 DaYdef(0) <= KonfigTAB(41);--C_DA0;--spez. Deformation : Def/ 22.25 [mm/N] DaYdef(1) <= KonfigTAB(44);--C_DA3; DaYdef(2) <= PIdiv2;--90Grd , cos90 =0,keine Auswirkung --- TAyrad(0) <= AxDrad(0); --Winkel A1:0.01mm/22.25=0.000449438 TAyrad(1) <= AxDrad(3); --Winkel A2:0.1mm/22.25=0.00449438 TAyrad(2) <= PIdiv2;--90Grd , cos90 =0, keine Auswirkung --. D_LAy(0) <= KonfigTAB(35);--C_L0;--mm, armlänge nach ref.Anfahren D_LAy(1) <= KonfigTAB(38);--C_L3; D_LAy(2) <= KonfigTAB(35);--C_L0;-- X länge nach ref anfahren --- RsAy(0) <= KonfigTAB(23);--C_A0rad;--incr/rad RsAy(1) <= KonfigTAB(26);--C_A3rad; RsAy(2) <= KonfigTAB(23);--C_A0rad; --------------------------------------- stateYdef := 1; ELSE stateYdef := 0;-- dann warten END IF; WHEN 1 => --- keine korrektur für DEf Tabelle stateYdef := 5; WHEN 5 => -- start cosFP,loop InpY1 <= TAyrad(i); ceyD1 <= '1';-- start für cosFP cntrclk := clkTocos;-- wartezeit stateYdef := 6; WHEN 6 => -- wartezeit für cosFP, ausführen ceyD1 <= '0';--reset ce IF cntrclk > 0 THEN cntrclk := cntrclk - 1; stateYdef := 6; ELSE -- zeit abgelaufen IF i < 2 THEN cosAy(i) <= outY2;-- resultat speichern i := i + 1; stateYdef := 5; -- und repeat ELSE cosAy(i) <= outY2;-- resultat speichern stateYdef := 7;-- cos fertig berechnet END IF; END IF; WHEN 7 =>-- input Kraftsensor Y Richtung Extension auf 32 bits IF ADINP(1)(11) = '0' THEN --wert Positiv FSY <= X"00000" & ADINP(1); ELSE FSY <= X"FFFFF" & ADINP(1); END IF; ceYD2 <= '1';-- Int To FP aktiv stateYdef := 8; ---- WHEN 8 => --IntToFP ausführen ceYD2 <= '0';-- ce reset ceYD6 <= '1';-- Mul start Int To N stateYdef := 9; ---- WHEN 9 =>-- mul ausführen:FS_FPN[N]=FS_Fp[int] * C_IntToN ceYD6 <= '0';-- reset Ce ceYD3 <= '1'; --mul starten stateYdef := 10; ---- WHEN 10 => --Div ausführen :Fx_FP[N]=Fs_FPN / UXFP ceYD3 <= '0';--ce reset i := 0; stateYdef := 11; -------------------------- WHEN 11 => stateYdef := 12; WHEN 12 => -- mul loop: DAyFP[mm]=FyFP[N] * DAyFP(i)[mm/N] ceyd4 <= '1';-- mulFP aktiv InpY1 <= Fy_FP; InpY2 <= DaYdef(i); stateYdef := 13; WHEN 13 => ceyd4 <= '0';-- ce reset stateYdef := 14; WHEN 14 => -- mul: DAyFP(i) * Fy_FP ausführen IF i < 2 THEN DAyFP(i) <= OutY3; i := i + 1; stateYdef := 12; ELSE DAyFP(i) <= OutY3; i:= 0; stateYdef := 15; END IF;--DayFP(i) fertig ----------------------- WHEN 15 => -- mulFP: loop:DAcFP[mm]= DayFP[mm] * cosAy InpY1 <= DAyFP(i); InpY2 <= cosAy(i); ceyD5 <= '1'; stateYdef := 16; WHEN 16 => ceyD5 <= '0';-- reset ce stateYdef := 17; WHEN 17 => -- MulFp: DAcFp= DayFP * cosAy ausführen IF i < 2 THEN DAYcFP(i) <= OutY4; i := i + 1; stateYdef := 15; ELSE DAYcFP(i) <= OutY4; i:= 0; stateYdef := 18; END IF; ------------------------- WHEN 18 => -- AYdef=arctang(DaYcFP,D_LAy), deformations winkel[rad] InpY2 <= DAYcFP(i); InpY1 <= D_LAy(i); ceyD7 <= '1'; cntrclk := clkAtan; stateYdef := 19; WHEN 19 => -- ausführen arctang ceyD7 <= '0';-- reset ce IF cntrclk > 0 THEN cntrclk := cntrclk - 1; stateYdef := 19;-- warten ELSE stateYdef := 20; END IF; WHEN 20 => IF i < 2 THEN AYdef(i) <= OutY5; i := i + 1; stateYdef := 18;-- und repeat ELSE AYdef(i) <= OutY5; i:= 0; stateYdef := 21; END IF; -------------------- WHEN 21 => -- IncrAY = Aydef * ResAyrad InpY1 <= AYdef(i); InpY2 <= RsAY(i); ceyD8 <= '1'; stateYdef := 22; WHEN 22 => ceyD8 <= '0';-- reset ce stateYdef := 23; WHEN 23 => IF i < 2 THEN IncrAY(i) <= OutY6; i := i + 1; stateYdef := 21;-- und repeat ELSE IncrAY(i) <= OutY6; stateYdef := 24; END IF; WHEN 24 => -- Korrektur Werte Richtung Y fertig Berechnet IF AxDradOK = '1' AND SDIADOK = '1' THEN stateYdef := 24;-- warten bis istwert zyklus fertig ist ELSE stateYdef := 0;--neue Istwert Zyklus END IF; WHEN OTHERS => StateYdef := 0; END CASE; END IF;-- Ende nrst/else END IF; -- Ende clk END PROCESS;--Ende YDef --========================================================= --===================================================================== --Zdef : Rechnet Deformation in Anzahl Increment in Richtung Z ----------------------------------------------- --TYPE T_ADINP IS ARRAY(0 to 3) OF STD_LOGIC_VECTOR(11 DOWNTO 0);--Daten Kraftsensoren --TYPE T_Dx IS ARRAY(0 TO 2) OF INTEGER;-- Kraftberechnung in der XYZ --TYPE T_Ax IS ARRAY(0 to 2) OF STD_LOGIC_VECTOR(31 DOWNTO 0); -- auch fü FP --Tabelle: TAzrad :T_Ax; --------------------------- -- SIGNAL IstAz :T_Ax; -- SIGNAL CosAz :T_Ax; -- SIGNAL DAzdef :T_Ax;-- deformation Daten für A1,A,A4 -- SIGNAL FSZ :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- SIGNAL FSZ_FP :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- SIGNAL FSZ_FP :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- SIGNAL DaZFP :T_Ax; -- SIGNAL DaZcFP :T_Ax; -- SIGNAL Azdef :T_Ax; -- SIGNAL IncrAz :T_Ax; -- SIGNAL inpZ1 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- zwischen Speicher für Input FD Fkt -- SIGNAL inpZ2 :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; -- SIGNAL outZ :STD_LOGIC_VECTOR(31 DOWNTO 0):=X"00000000"; ------------------------------------------- cZdef :PROCESS(clk) VARIABLE StateZdef :INTEGER RANGE 0 TO 31 := 0; VARIABLE cntrclk :INTEGER RANGE 0 TO 50:= 0; VARIABLE i :INTEGER RANGE 0 TO 15; BEGIN IF rising_edge(clk) THEN IF nrst = '0' THEN StateZdef := 0; cntrclk := 0; i := 0; FOR i IN 0 TO 2 LOOP TAZrad(i) <= X"00000000"; END LOOP; ELSE CASE stateZdef IS WHEN 0 => IF AxDradOK = '1' AND SDIADOK = '1' THEN -----Konsatnten Tabellen für Deformation Richtun X--, ----relevante Achsen: A1,A2,A4 DaZdef(0) <= KonfigTAB(42);--C_DA1;--spez. Deformation ( Def/ 22.25) [mm/N] DaZdef(1) <= KonfigTAB(43);--C_DA2; DaZdef(2) <= KonfigTAB(45);--C_DA4; --- TAzrad(0) <= AxDrad(1); --Winkel A1-Pidiv2 TAzrad(1) <= AxDrad(2); --Winkel A2: TAzrad(2) <= AxDrad(4); --Winkel A4-Pidiv2 --. D_LAz(0) <= KonfigTAB(36);--C_L1;--mm, armlänge D_LAz(1) <= KonfigTAB(37);--C_L2; D_LAz(2) <= KonfigTAB(39);--C_L4; --- RsAz(0) <= KonfigTAB(24);--C_A1rad;--incr/rad RsAz(1) <= KonfigTAB(25);--C_A2rad; RsAz(2) <= KonfigTAB(27);--C_A4rad; --------------------------------------- stateZdef := 1; ELSE stateZdef := 0;-- dann warten END IF; WHEN 1 => --- korrektur für DEf Tabelle ceZD0 <= '1'; -- Start für SubFP : Aydrad <=AyDrad(2) - PiDiv InpZ1 <= TAZrad(0);-- für SubFP1 InpZ3 <= TAZrad(2);-- subFP2 stateZdef := 2; WHEN 2 => -- ausführen SubFP Für A1 und A4 ceZD0 <= '0';-- reset CE stateZdef := 3; WHEN 3 => TAZrad(0) <= outZ1;-- resultat subFP1 : AZDrad(0) - Pidiv2 TAZrad(2) <= outZ7;-- resultat subFP2: AZDrad(2) - Pidiv2 stateZdef := 4; WHEN 4 => i := 0; stateZdef := 5; WHEN 5 => -- start cosFP,loop InpZ1 <= TAZrad(i); ceZD1 <= '1';-- start für cosFP cntrclk := clkTocos;-- wartezeit stateZdef := 6; WHEN 6 => -- wartezeit für cosFP, ausführen ceZD1 <= '0';--reset ce IF cntrclk > 0 THEN cntrclk := cntrclk - 1; stateZdef := 6; ELSE -- zeit abgelaufen IF i < 2 THEN cosAz(i) <= outZ2;-- resultat speichern i := i + 1; stateZdef := 5; -- und repeat ELSE cosAz(i) <= outZ2;-- resultat speichern stateZdef := 7;-- cos fertig berechnet END IF; END IF; WHEN 7 =>-- input Extension auf 32 bits IF ADINP(2)(11) = '0' THEN --wert Positiv FSZ <= X"00000" & ADINP(2); ELSE FSZ <= X"FFFFF" & ADINP(2); END IF; ceZD2 <= '1';-- Int To FP aktiv stateZdef := 8; ---- WHEN 8 => --IntZToFP ausführen ceZD2 <= '0';-- ce reset ceZD6 <= '1';-- Mul start Int To N stateZdef := 9; ---- WHEN 9 =>-- mul ausführen:FSZ_FPN[N]=FSZ_Fp[int] * C_ZIntToN ceZD6 <= '0';-- reset Ce ceZD3 <= '1'; --mul starten stateZdef := 10; ---- WHEN 10 => --Div ausführen :FzZ_FP[N]=FsZ_FPN / UZFP ceZD3 <= '0';--ce reset i := 0; stateZdef := 11; -------------------------- WHEN 11 => stateZdef := 12; WHEN 12 => -- mul loop: DAzFP[mm]=FzFP[N] * DAzFP(i)[mm/N] ceZd4 <= '1';-- mulFP aktiv InpZ1 <= Fz_FP; InpZ2 <= DaZdef(i); stateZdef := 13; WHEN 13 => ceZd4 <= '0';-- ce reset stateZdef := 14; WHEN 14 => -- mul: DAzFP(i) * Fz_FP ausführen IF i < 2 THEN DAZFP(i) <= OutZ3; i := i + 1; stateZdef := 12; ELSE DAZFP(i) <= OutZ3; i:= 0; stateZdef := 15; END IF;--DazFP(i) fertig ----------------------- WHEN 15 => -- mulFP: loop:DAcFP[mm]= DaZFP[mm] * cosAy InpZ1 <= DAzFP(i); InpZ2 <= cosAz(i); ceZD5 <= '1'; stateZdef := 16; WHEN 16 => ceZD5 <= '0';-- reset ce stateZdef := 17; WHEN 17 => -- MulFp: DAZcFp= DazFP * cosAz ausführen IF i < 2 THEN DAZcFP(i) <= OutZ4; i := i + 1; stateZdef := 15; ELSE DAZcFP(i) <= OutZ4; i:= 0; stateZdef := 18; END IF; ------------------------- WHEN 18 => -- AZdef=arctang(DaZcFP,D_LAZ), deformations winkel[rad] InpZ2 <= DAZcFP(i); InpZ1 <= D_LAZ(i); ceZD7 <= '1'; cntrclk := clkAtan; stateZdef := 19; WHEN 19 => -- ausführen arctang ceZD7 <= '0';-- reset ce IF cntrclk > 0 THEN cntrclk := cntrclk - 1; stateZdef := 19;-- warten ELSE stateZdef := 20; END IF; WHEN 20 => IF i < 2 THEN AZdef(i) <= OutZ5; i := i + 1; stateZdef := 18;-- und repeat ELSE AZdef(i) <= OutZ5; i:= 0; stateZdef := 21; END IF; -------------------- WHEN 21 => -- IncrAZ = Azdef * ResAzrad InpZ1 <= AZdef(i); InpZ2 <= RsAZ(i); ceZD8 <= '1'; stateZdef := 22; WHEN 22 => ceZD8 <= '0';-- reset ce stateZdef := 23; WHEN 23 => IF i < 2 THEN IncrAZ(i) <= OutZ6; i := i + 1; stateZdef := 21;-- und repeat ELSE IncrAZ(i) <= OutZ6; stateZdef := 24; END IF; WHEN 24 => -- Korrektur Werte Richtung Y fertig Berechnet IF AxDradOK = '1' AND SDIADOK = '1' THEN stateZdef := 24;-- warten bis istwert zyklus fertig ist ELSE stateZdef := 0;--neue Istwert Zyklus END IF; WHEN OTHERS => StateZdef := 0; END CASE; END IF;-- Ende nrst/else END IF; -- Ende clk END PROCESS;--Ende ZDef --==========LrkReg Processe=========================================== ---------------Kopieren Konfig Daten inDiv register------------------- --Konfig Daten--T_EbReg:ARRAY(0 to 2) OF STD_LOGIC_VECTOR(31 DOWNTO 0)----- --======================================================================= -- Espd :Extended speed auf 32 bit -- Eacc :Extended acc auf 32 bit -- generieren => svorskX & svorskY wrKorr: PROCESS(clk) BEGIN IF rising_edge(clk) THEN ---------------------------------- IF (nrst = '0')THEN for i in 0 to 5 LOOP svorsk(i) <= (OTHERS => '0');--svorsk(5..0) END LOOP; ELSE ------------------------------------------------- for i in 0 to 5 LOOP svorsk(i) <= Eacc(i) + Espd(i); END LOOP; END IF;--if/else nrst END IF; -- end if clk END PROCESS; --============================================================================ --================================================================== --Ladet Werte von AXinc(Sollwerte Winkel der Achsen von Inv.Trans.) in SOLL -- beim SetIstSoll setzt Soll auf Anfangswinkel der Achsen bercnet aus -- der XYZ Start Position der Bewegung (XS,YS,ZS) SollInc:PROCESS(clk) VARIABLE i :integer := 0; VARIABLE setup :std_logic:='0';-- sollwerte gesetzt bei RMPrun = 0 VARIABLE solldif :T_AXreg; BEGIN IF rising_edge(clk) THEN ----------------------------------- IF (nrst = '0') THEN for i in 0 to 5 LOOP SOLL(i) <= (OTHERS => '0'); solldif(i) := (OTHERS => '0'); END LOOP; --sollstate <= 0; setup := '0'; ELSE IF SetIstSoll = '0' THEN -- normal ablauf IF sRampRun = '1' THEN -- wenn Rampe Läuft, dann SOLL setzen gemäss Achsenwinkel IF sordAX = '0' THEN FOR i IN 0 TO 5 LOOP IF soutdif(i*16+ 15) = '1' THEN solldif(i) := X"FFFF" & soutdif(i*16+15 DOWNTO i*16); SOLL(i) <= SOLL(i) + solldif(i); ELSE solldif(i) := X"0000" & soutdif(i*16+15 DOWNTO i*16); SOLL(i) <= SOLL(i) + solldif(i); END IF; END LOOP; END IF; END IF;-- Ende IF sRampRun ELSE --- setzen auf C_A0 bis C_A5, wenn setIstSoll Impuls = '1', wird gesetzt bei ref anfahren SOLL(0) <= C_A0; SOLL(1) <= C_A1; SOLL(2) <= C_A2; SOLL(3) <= C_A3; SOLL(4) <= C_A4; SOLL(5) <= C_A5; END IF;-- ende If/else SetIsiSoll END IF; -- ende if/else nrst END IF;-- ende if clk END PROCESS; --==================================================================== --Inkr/dekr IST Register gemäss der Impulse IstImp ------------------------------------------------------------ IstREG: PROCESS(clk) BEGIN IF rising_edge(clk) THEN ----------------------------------- IF (nrst = '0') THEN-- OR (clrAx = '1') THEN for j in 0 to 5 LOOP IST(j) <= (OTHERS => '0'); END LOOP; ELSE IF SetIstSoll = '0' THEN -- normal ablauf FOR i IN 0 TO 5 LOOP IF (IstImp(i*2+1) = '0') THEN -- If Impuls aktiv IF IstImp(i*2) = '1' THEN --if Vorw=1 thn inkrem,else dekrem IST(i) <= IST(i) + 1; ELSE IST(i) <= IST(i) - 1; END IF; END IF; END LOOP; ELSE --- setzen auf C_A0 bis C_A5 IST(0) <= C_A0; IST(1) <= C_A1; IST(2) <= C_A2; IST(3) <= C_A3; IST(4) <= C_A4; IST(5) <= C_A5; END IF; END IF; -- ende if/else nrst END IF;-- ende if clk END PROCESS; --============= /////// D/A Input Werte /////////////-------------- --DA_AX : folgende Register werden Berechnet, als vorbereitunf für DiffAX ---Type T_AxReg IS ARRAY(0 to 5) OF STD_LOGIC_VECTOR(31 DOWNTO 0); ---TYPE T_iAXReg IS ARRAY(0 TO 5) OF INTEGER; ------------------------------------------------- -- SIDiff :T_AxReg:=; --Differenz Soll/Ist für 6 Achsen ---SIABS :T_AxReg; --Abs.Wert von SIDif für 6 Achsen -- Diff : T_AxReg;--abs(Soll+vors-Ist), 6 Achsen mit Schleppkorr,aktuelle Wert ---iDiff : T_iAXReg; wie Diff jedoch Integer -------------------------------------------------------------------------- DA_AX: PROCESS(clk) --DAdifAX VARIABLE vDiff : T_Axreg; VARIABLE vSIDiff :T_AxReg; BEGIN IF rising_edge(clk) THEN --------------------------------- IF (nrst = '0') OR (sclrAx = '1') THEN for i in 0 to 5 LOOP vDiff(i) := (OTHERS => '0'); --iDiff(i) <= 0; vSIDiff(i) := (OTHERS => '0'); SIDiff(i) <= (OTHERS => '0'); SIAbs(i) <= (OTHERS => '0'); Diff(i) <= (OTHERS => '0'); END LOOP; ELSE for i in 0 to 5 LOOP vSIDiff(i) := Soll(i) - Ist(i); IF vSIdiff(i)(31) = '0' THEN SIAbs(i) <= vSIDiff(i);-- für limitüberwachung Soll/Ist im LimTst ELSE SIAbs(i) <= (vSIDiff(i) XOR X"FFFFFFFF") + 1; END IF; ---------------------------------------------------- IF refrun = '1' THEN -- bei ref anfahren keine schleppfehler korrektur vDiff(i) := Soll(i) - Ist(i); IF vDiff(i)(31) = '1' THEN -- if negativ vDiff(i) := (vDiff(i) XOR X"FFFFFFFF") + 1; fnegAx(i) <= '1'; ELSE fnegAx(i) <= '0'; END IF; ELSE --Bei Interpolatorpulsen schleppfehler korrektur vDiff(i) := Soll(i) - Ist(i) + svorsk(i);-- Soll - Ist + svorsk IF vDiff(i)(31) = '1' THEN -- if negativ vDiff(i) := (vDiff(i) XOR X"FFFFFFFF") + 1; fnegAx(i) <= '1'; ELSE fnegAx(i) <= '0'; END IF; END IF; SIDiff(i) <= vSidiff(i);--Soll- Ist (+/-)für Schleppfehler anzeige Diff(i) <= vDiff(i);--Abs Wert für DA wert Berechnung in cDAwXY END LOOP; END IF;-- if nrst,else END IF; -- ende if clk END PROCESS;-- ende DA_AX --==================================================== --=====/////////////////////////// ==================== ---------------------------------------------------- --SIGNAL Diff :T_AxReg:=((others=> (others=>'0'))); --abs(Soll + vors - Ist)für 6 Achsen --SIGNAL DAXY :T_Ax16:=((others=> (others=>'0')));-- Output Reg für D/A Wandler, Wert für D/A(15..0) -------------------------------------------------------------------- --SIGNAL fnegAX :STD_LOGIC_VECTOR(5 DOWNTO 0):= "000000";-- vorzeichen für alle Achsen -------- DA Werte Berechnung ---T_AxReg: ARRAY(0 to 5) OF STD_LOGIC_VECTOR(31 DOWNTO 0)----- --SIGNAL DAWertAX :T_Ax16:=((others=> (others=>'0')));----Abs. DA Integer Outputwert --SIGNAL KPtAX :T_AxReg:=((others=> (others=>'0')));-- Resultat KNPKTX * K2X -------- DA-Werte ---TYPE T_Ax16:IS ARRAY(0 to 5) OF STD_LOGIC_VECTOR(15 DOWNTO 0); --SIGNAL InpA :STD_LOGIC_VECTOR(15 DOWNTO 0):=X"0000";-- Input multipl --SIGNAL InpB :STD_LOGIC_VECTOR(7 DOWNTO 0):=X"00"; --SIGNAL OutpP :STD_LOGIC_VECTOR(23 DOWNTO 0):=X"000000";--Resultatt Multipl. ----------------------------------------------------------------- --T_AxReg IS ARRAY(0 to 5) OF STD_LOGIC_VECTOR(31 DOWNTO 0); -- T_Ax16 IS ARRAY(0 to 5) OF STD_LOGIC_VECTOR(15 DOWNTO 0);-- Register für D/A Berechnungen -- Berechnung DA Wert A1..A6 mit Knickpunkt ---SIG DADiff :T_AxReg:=((others=> (others=>'0')));--abs(Soll+vors-Ist)für 6 Achsen mit Schleppkorr --vDADiff zwischenspeicher für DADiff(5..0) -- KNPx :T_EbReg;--Knickpunkt konfig KNPKTY | KNPKTX -- KX :T_EbReg;---- Kreisverstärkung K2Y,K1Y | K2X,K1X -- KNPx(5..0) --===================================================================== --=========läuft====================================== -- implementiert: Achsen Invert siehe z11,12 ************************ cDAwXY :PROCESS(clk) VARIABLE clkcount :INTEGER RANGE 0 TO 500 := 0; VARIABLE zwsp : std_logic_vector(23 DOWNTO 0):= X"000000"; VARIABLE zwsp2 :std_logic_vector(15 DOWNTO 0):= X"0000"; VARIABLE vDADiff :std_logic_vector(31 DOWNTO 0):= X"00000000"; VARIABLE iDADiff :integer; VARIABLE iZWSP :integer;-- zwischenspeicher VARIABLE i :INTEGER RANGE 0 TO 7:= 0; BEGIN IF rising_edge(clk) THEN IF (nrst = '0') OR (sclrAX = '1')THEN stateX <= z0; vDADiff := (OTHERS => '0');-- 32 bit iDADiff := 0; iZWSP := 0; sDAX10 <= X"80008000"; sDAX32 <= X"80008000"; sDAX54 <= X"80008000"; for i in 0 to 5 LOOP DAXY(i) <= X"8000"; DAWertAX(i) <= X"0000"; kptAX(i) <= (OTHERS => '0'); END LOOP; finvAX <= "000000"; --alle Invertierung = 0 InpA <= X"0000";-- Inputs für MULx : 16 * 8 bit InpB <= X"00"; zwsp := (OTHERS => '0');--24 bit zwsp2 := (OTHERS => '0');--16 bit i := 0; clkcount := 0; ELSE --for i in 0 to 5 LOOP CASE stateX IS WHEN z0 => --IF (ImpIst = '1') OR (impsoll ='1') THEN -- start IF (ImpIst = '0') OR (sordAX ='0') THEN -- start wenn aenderung soll oder ist i:= 0; stateX <= z1; ELSE stateX <= z0; END IF; ----- Loop------------------------------ WHEN Z1 => vDADiff := Diff(i); --DADiff(während der Berechnung muss es gleich bleiben iDADiff := conv_integer(Diff(i));--Diff=abs(Soll + vors - Ist) IF iDADiff >= 32768 THEN DAWertAX(i) <= X"7FFF"; stateX <= z10; -- wenn grösser +/-7FFF dann berechnung fertig --ELSIF vDADiff(15 DOWNTO 0) > KNPTXY(0)(31 DOWNTO 16) THEN ELSIF vDADiff(15 DOWNTO 0) > KNPTXY(i/2)(((i mod 2)*16+15) DOWNTO (i mod 2)*16) THEN stateX <= z5;-- oberhalb Knickpunkt ELSE stateX <= z2; -- unterhalb Knickpunkt END IF; ----------------------------------------------- WHEN z2 => -- start unterhalb Knickpunkt Berechnung InpA <= vDADiff(15 DOWNTO 0); --InpB <= KXY(0)(23 DOWNTO 16);-- K1Y:xxxxxxx.x InpB <= KXY(i/2)((i mod 2)*16+7 DOWNTO (i mod 2)*16);-- K1Y,K1X:xxxxxxx.x ce1608 <= '1'; -- mul aktiv clkcount := clkmul; stateX <= z3; WHEN z3 => -- wartn auf Berechnung IF clkcount = 0 THEN ce1608 <= '0'; -- mul inaktiv stateX <= z4; ELSE clkcount:= clkcount - 1; stateX <= z3; END IF; WHEN z4 =>-- resultat ausgabe, 2 kommastellen --outP(23..0):23..20,19..16,15..12,11..8,7..4,3,2,1|0 iZWSP := conv_integer(outpP(23 DOWNTO 17)); IF iZWSP > 0 THEN --IF outpP(23 DOWNTO 17) > "0000000" THEN DAWertAX(i) <= X"7FFF"; ELSE DAWertAX(i) <= outpP(16 DOWNTO 1); END IF; stateX <= z11;-- berechnung für Achse i fertig ------------Wert unterhalb Knickpunkt fertig berechnet ------------------- ----------------------------------------------------------------- WHEN z5 => -- start oberhalb Knickpunkt Berechnung,KNPTX * K1X -- zuerst der Knickpunkt berechnen :KNPTy * K1y --inpA <= KNPTXY(0)(31 DOWNTO 16); --inpB <= KXY(0)(23 DOWNTO 16);-- K1Y inpA <= KNPTXY(i/2)((i mod 2)*16+15 DOWNTO (i mod 2)*16); inpB <= KXY(i/2)((i mod 2)*16+7 DOWNTO (i mod 2)*16);-- K1Y,K1X ce1608 <= '1'; -- mul aktiv clkcount := clkmul; stateX <= z6; WHEN z6 => IF clkcount = 0 THEN ce1608 <= '0'; -- mul inaktiv stateX <= z7; ELSE clkcount:= clkcount - 1; stateX <= z6; END IF; WHEN z7 => --kptX <= KNPTX * K1X, KIX:xxxxxxx.x --outP(23..0):23..20,19..16,15..12,11..8,7..4,3,2,1|0 kptAX(i) <= X"0000" & outpP(16 DOWNTO 1);-- knickpunkt position --zwsp2 := KNPTXY(0)(31 DOWNTO 16); zwsp2 := KNPTXY(i/2)((i mod 2)*16+15 DOWNTO (i mod 2)*16); stateX <= z8; --Knickpunkt fertig berschnet in kptAX(i) WHEN z8 => -- Berechng oberhalb Knpkt --InpA <= vDADiff(15 DOWNTO 0) - zwsp2; --InpB <= KXY(0)(31 DOWNTO 24);-- K2X,xxx.xxxxx InpA <= vDADiff(15 DOWNTO 0) - zwsp2; InpB <= KXY(i/2)((i mod 2)*16 +15 DOWNTO (i mod 2)*16+8);-- K2X,xxx.xxxxx ce1608 <= '1'; -- mul aktiv clkcount := clkmul; stateX <= z9; WHEN z9 => -- Zusatz wert oberhalbknickpunkt berechnen IF clkcount = 0 THEN --DAWertAX :T_AxReg: ARRAY(0 to 5) --outpP(23..0):23..20,19..16,15..12,11..8,7.5|4,3..0 zwsp := ("00000" & outpP(23 DOWNTO 5)) + kptAX(i)(23 DOWNTO 0); ce1608 <= '0'; -- mul inaktiv stateX <= z10; ELSE clkcount:= clkcount - 1; stateX <= z9; END IF; WHEN z10 => IF zwsp > X"007FFF" THEN DAWertAX(i) <= X"7FFF";--32767 = max Wert ELSE DAWertAX(i) <= zwsp(15 DOWNTO 0);-- nicht grösser als 32767 END IF; stateX <= z11;-- und weiter ---------------------------------------------------------------- WHEN z11 =>-- finvAX : flag invert Achsen aktualisieren finvAX(0) <= AxKonREG(1)(3); finvAX(1) <= AxKonREG(1)(7); finvAX(2) <= AxKonREG(25)(3); finvAX(3) <= AxKonREG(25)(7); finvAX(4) <= AxKonREG(49)(3); finvAX(5) <= AxKonREG(49)(7); stateX <= z12; WHEN z12 => -- umwandeln in EXCESS-16 code gem. fneg und finv IF finvAx(i) = '0' THEN IF fnegAx(i) = '0' THEN DAXY(i) <= X"8000" + DAWertAX(i);--then Postiv ELSE -- negativ => binär umwandeln DAXY(i) <= X"8000" - DAWertAX(i); END IF; ELSE -- Achse Invertieren IF fnegAx(i) = '0' THEN DAXY(i) <= X"8000" - DAWertAX(i);--then Postiv ELSE -- negativ => binär umwandeln DAXY(i) <= X"8000" + DAWertAX(i); END IF; END IF; stateX <= z13;--z12; WHEN Z13 => IF i < 5 THEN i := i + 1; stateX <= z1; ELSE stateX <= z14;-- und loop verlassen END IF; WHEN Z14 => sDAX10 <= DAXY(1) & DAXY(0); sDAX32 <= DAXY(3) & DAXY(2); sDAX54 <= DAXY(5) & DAXY(4); stateX <= Z15; WHEN Z15 => stateX <= Z0; WHEN OTHERS => stateX <= z0;-- und zurück END CASE; END IF;-- if nrst / else END IF; -- if clk END PROCESS;-- dawxy ----================================================ --Anzahl Achseninkremene : --A1:255'592 Inkr/U bei 20 Grd = 14'197 =3775h --A2:247'499 13'749 =35B8h --A3:121'469 6'748 =1A5C --A4:124'800 6'933 =1B15h --A5:7'749 430.5 =1AFh --A6:71'504 3'972 =FB4h ------------------------------------------------- ----------- PoserX,Y und LRK Limit setzen --------- ----- sLimXY(5..0),ist Ausgang, limit a5..a1 =1 -- sPoser(5..0) ist Ausgang, poeer A5..A1 =0 --**LrkLimit(31..16) & PoserLimit(7..0) ist Register Adr 11100,ungültug --RES: 31..24=X"00*, -- 23..16 =AxKonREG(0B):Dis6,Rchtg(6),RESY,RESY,Dis5,Rchtg5,RESX,RESX -- 15..8 =AxKonREG(23):Dis4,Rchtg(4),RESY,RESY,Dis3,Rchtg3,RESX,RESX -- 7..0 =AxKonREG(3B):Dis2,Rchtg(2),RESY,RESY,Dis1,Rchtg1,RESX,RESX LimTst : PROCESS(clk) --Abs.Wert von SIDifY BEGIN IF rising_edge(clk) THEN IF (nrst = '0') THEN sPoser <= "111111";-- Poser inaktiv sLimXY <= "000000";-- Lim A1..A6 init ELSE -----------LRK Limit setzen---für alle achsen--------------- ---------------------Achse A1 -------37FF = 14335d----------------------- IF (SIAbs(0) > (X"0000" & AxKonREG(2) & X"FF") ) THEN sLimXY(0) <= '1' ;--Achsen A1 limit erreicht ELSE sLimXY(0) <= '0' ; END IF; --------------------Achse A2---------35FF= 13823d------------------------- IF (SIAbs(1) > (X"0000" & AxKonREG(3) & X"FF") ) THEN sLimXY(1) <= '1' ;--Achsen A2 limit erreicht ELSE sLimXY(1) <= '0' ; END IF; --------------------Achse A3--------FFFF = 65535d-------------------------- IF (SIAbs(2) > (X"0000" & AxKonREG(26) & X"FF") ) THEN sLimXY(2) <= '1' ;--Achsen A3 limit erreicht ELSE sLimXY(2) <= '0' ; END IF; --------------------Achse A4--------28FF = 10495-------------------------- IF (SIAbs(3) > (X"0000" & AxKonREG(27) & X"FF") ) THEN sLimXY(3) <= '1' ;--Achsen A4 limit erreicht ELSE sLimXY(3) <= '0' ; END IF; --------------------Achse A5-------02FF = 767d--------------------------- IF (SIAbs(4) > (X"0000" & AxKonREG(50) & X"FF") ) THEN sLimXY(4) <= '1' ;--Achsen A3 limit erreicht ELSE sLimXY(4) <= '0' ; END IF; --------------------Achse A6--------17FF = 6143d-------------------------- IF (SIAbs(5) > (X"0000" & AxKonREG(51) & X"FF") ) THEN sLimXY(5) <= '1' ;--Achsen A4 limit erreicht ELSE sLimXY(5) <= '0' ; END IF; ------------------------------------------------------ --------------Poser setzen----AxkonREG(4,1C,34):Y:7..4 & 11, X:3..0 & 11 -------------- Achse A1------------------------------ IF SIAbs(0) < (X"000000" & "00" & AxKonREG(4)(3 DOWNTO 0) & "11") THEN sPoser(0) <= '0'; -- POSER aktiv für Achse 1(pos.Erreicht) ELSE sPoser(0) <= '1'; -- POSER inaktiv für Achse 1 END IF; -------------- Achse A2------------------------------ IF SIAbs(1) < (X"000000" & "00" & AxKonREG(4)(7 DOWNTO 4) & "11") THEN sPoser(1) <= '0'; -- POSER aktiv für Achse 2 ELSE sPoser(1) <= '1'; -- POSER inaktiv für Achse 2 END IF; -------------- Achse A3------------------------------ IF SIAbs(2) < (X"000000" & "00" & AxKonREG(28)(3 DOWNTO 0) & "11") THEN sPoser(2) <= '0'; -- POSER aktiv für Achse 3 ELSE sPoser(2) <= '1'; -- POSER inaktiv für Achse 3 END IF; -------------- Achse A4------------------------------ IF SIAbs(3) < (X"000000" & "00" & AxKonREG(28)(7 DOWNTO 4) & "11") THEN sPoser(3) <= '0'; -- POSER aktiv für Achse 4 ELSE sPoser(3) <= '1'; -- POSER inaktiv für Achse 4 END IF; -------------- Achse A5------------------------------ IF SIAbs(4) < (X"000000" & "00" & AxKonREG(52)(3 DOWNTO 0) & "11") THEN sPoser(4) <= '0'; -- POSER aktiv für Achse 3 ELSE sPoser(4) <= '1'; -- POSER inaktiv für Achse 3 END IF; -------------- Achse A6------------------------------ IF SIAbs(5) < (X"000000" & "00" & AxKonREG(52)(7 DOWNTO 4) & "11") THEN sPoser(5) <= '0'; -- POSER aktiv für Achse 4 ELSE sPoser(5) <= '1'; -- POSER inaktiv für Achse 4 END IF; -------------------------------------------------------------- END IF; -- ende if/else nrst END IF; -- ende if clk END PROCESS; --========================================================= --use LUT's, Create LPM,PortA=16 bit signed,PortB= 8 Bit,unsigned --Output svkX: 24 bit signed Registered -- Berechnung der Schleppfehlerkorrektur : +/-svkX = +/-speedX * +skorrX SpeedKorAX: mulkorr PORT MAP( clk => clk, a => spd, b => korrS, p => svk ); --=============================================== AccKorAX: mulkorr PORT MAP( clk => clk, a => acc, b => korrA, p => sacc ); ------=====Berechnung Knickpunkt=============== -- Inputs : 16 & 11 Bit, --Output Registered,23 downto 0= 24 bit MulAx: mul1608 PORT MAP( clk => clk, a => InpA, b => InpB, ce => ce1608, p => OutpP ); --===================================================================== --------------Speed Berechnung für alle 6 Achsen----------------------------------------- -------------"1010";--Pulse :nimpY,vorwY,nimpX,vorwX --SIGNAL SollImp :STD_LOGIC_VECTOR(11 DOWNTO 0):= X"AAA"; -- jeweilige nimp = SollImp(i+2), vor = SollImp(i*2) --FVConvert: PROCESS(clk) -- frequenz Vorschub converter -- --variable outwert :INTEGER RANGE 0 TO 4294967297:= 0;--4294967297--2147483647 -- variable outwert :STD_LOGIC_VECTOR(39 DOWNTO 0):=(OTHERS => '0'); -- variable step :STD_LOGIC_VECTOR(39 DOWNTO 0):= (OTHERS => '0'); -- variable clkcount :integer range 0 to 255:= 0; -- variable fstrt :std_logic:='0'; -- variable outmin :STD_LOGIC_VECTOR(39 DOWNTO 0):=(OTHERS => '0'); --BEGIN -- IF rising_edge(clk) THEN -- IF nrst = '0' THEN -- outwert := (OTHERS => '0'); -- outmin := (OTHERS => '0'); -- step := (OTHERS => '0'); -- fstrt := '0'; -- for i in 0 to 5 LOOP -- speed(i) <= X"0000";END LOOP; -- spdOut <= '0'; -- ELSE -- for i in 0 to 5 LOOP -- --IF SollImp((i*2)+ 1) = '0' THEN --if Imp Ax aktiv -- IF IstImp((i*2)+ 1) = '0' THEN --if Imp Ax aktiv -- IF fstrt = '0' THEN -- outmin := outwert; -- fstrt := '1'; -- --40bit =1.099511*10^12 - 24 bit=16777216 = FFFF000000 -- IF outwert < X"FFFF000000" THEN -- outwert := outwert + X"FFFFFF";-- = schritt beim Impuls -- END IF; -- END IF; -- spdOut <= '0';-- Daten noch inaktiv -- ELSE -- fstrt := '0';-- für nächste imp vorbereiten -- -- step = outwert / 16777216 (24bit), 0000 xx xxxx -- IF srampzu = "11" THEN -- wenn Rampe fertig & -- --step := step - X"0000000001"; -- IF outwert > step THEN -- outwert := outwert - step; -- outmin := outwert; -- ELSE -- outwert := X"0000000000"; -- outmin := outwert; -- END IF; -- ELSE -- so lange Rampe nicht fertig -- step := X"0000" & outwert(39 DOWNTO 16); -- IF outwert > step THEN -- outwert := outwert - step; -- END IF; -- END IF; -- ----------------------------------- -- -- VFspeed <= outwert / 65536 (16 bit) -- IF skorron = '0' THEN -- wenn Schleppfehler inaktiv. alles init -- fstrt := '0'; spdOut <= '0'; -- step := (OTHERS => '0'); -- outwert := X"0000000000"; -- outmin := X"0000000000"; -- speed(i) <= X"0000"; -- spped := 0 -- ELSE --schleppfehler aktiv -- --IF SollImp(i*2)= '1' THEN --if Vor = 1 für jeweilige Achse -- IF IstImp(i*2)= '1' THEN --if Vor = 1 für jeweilige Achse -- speed(i) <= outmin(34 DOWNTO 19); -- ELSE -- speed(i) <= (outmin(34 DOWNTO 19) XOR X"FFFF") + 1; -- END IF; -- END IF; -- spdOut <= '1'; --daten aktiv, neue Speed ist berechnet für alle Achsen -- END IF;--If/Else SollImp (nimp = o) -- END LOOP; -- END IF; --if nrst/else -- END IF; -- if clk --END PROCESS;--FVConvert ------------------------------------------------------------------- --SIGNAL korrXY :T_EbReg;--31..24:KaccY,23..16:KorrY | 15..8:KaccX, 7..0:KorrX ---inputs mulkorr ------------------- -- speed :speed InputA,errechnet im FVConvert, aktiv wenn spdOut <= '1'; -- KorrS :STD_LOGIC_VECTOR(7 DOWNTO 0):=X"00";--InputB SpeedKorAX( mulkorr):8bit unsig -- svk :STD_LOGIC_VECTOR(23 DOWNTO 0):=X"000000";-- SpeedX korrig: Multkorr outputP --------------------------- -- Schleppfehlerkorrektur berechnen aus speed(i) --speedout: PROCESS(clk) --VARIABLE mulcntr :integer range 0 to 7:= 0; --BEGIN -- IF rising_edge(clk) THEN -- IF nrst = '0' OR (refrun='1') THEN -- mulcntr := 0;--mul Berechnung -- KorrS <= (OTHERS => '0'); -- spd <= (OTHERS => '0'); -- for i in 0 to 5 LOOP -- Espd(i) <= (OTHERS => '0');END LOOP; -- stateSpd <= 0; -- ELSE -- for i in 0 to 5 LOOP -- --wenn keine korrektur dann svorsXY abschalten -- IF korrXY(i/2)(7 DOWNTO 0) = X"00" THEN -- wenn keine korrektur -- Espd(i) <= (OTHERS => '0'); -- dann Extended Speed =0 -- ELSE -- wenn korrektur dann berechnen -- CASE stateSpd IS -- WHEN 0 => -- IF spdOut = '1' THEN -- mulcntr := clkmul; -- spd <= speed(i); -- KorrS <= KorrXY(i/2)(7 DOWNTO 0);-- SpeedkorrAx(mulkor) input B setzen -- stateSpd <= 1;-- und start mulkor -- ELSE -- stateSpd <= 0; -- END IF; -- WHEN 1 => ------Berechnung SpeedX * KorrX = svkX ------ -- IF mulcntr = 0 THEN --svkx ist fertig berechnet -- ------------Sign Extension svkX To svorskX------------------------ -- IF svk(23) = '1' THEN -- negativ -- Espd(i) <= X"FFFF" & svk(23 DOWNTO 8); --skorr mit 8 Kommastellen -- ELSE Espd(i) <= X"0000" & svk(23 DOWNTO 8);--erweiterung auf 32 bit -- END IF; -- ------------- -- stateSpd <= 0; -- ELSE -- warten auf SpeedKorX mulkorX -- mulcntr := mulcntr - 1; -- warten bis multiplier fertig ist -- stateSpd <= 1; -- END IF; -- WHEN OTHERS => stateSpd <= 0; -- END CASE; -- END IF;--IF skorrXY(7 DOWNTO 0) -- END LOOP; -- END IF; -- inrst/else -- END IF; -- if clk --END PROCESS;--speedout ----------------------------------------------------------------------- --=========Beschleunigung A1..A6 ============================================ ------------------------------------------------------- --Abtastspeed:PROCESS(clk) --1te Ableitung von speed = Beschleunigung mit durschnitt -----inputs mulkorr ------------------- ---- accel : inputA für AccKorAX(mulkorr): 16 bit sig ( wird hier berechnet) ---- KorrA :STD_LOGIC_VECTOR(7 DOWNTO 0):=X"00";-- InputB AccKorAX(mulkorr):8bit unsig ---- sacc :STD_LOGIC_VECTOR(23 DOWNTO 0):=X"000000";-- AccelX korrig: Multkorr outputP ----TYPE T_BUFF IS ARRAY(0 to 4) OF STD_LOGIC_VECTOR(31 DOWNTO 0); ----TYPE T_BUFF2 IS ARRAY(0 to 4) OF STD_LOGIC_VECTOR(15 DOWNTO 0); --VARIABLE summ :STD_LOGIC_VECTOR(15 DOWNTO 0):= X"0000"; --VARIABLE j :INTEGER RANGE 0 TO 7:= 0; --VARIABLE BUFF : T_BUFF1; --VARIABLE SpeedAlt :STD_LOGIC_VECTOR(15 DOWNTO 0):= X"0000"; --VARIABLE cntr :integer range 0 to 262143:= 0; --VARIABLE mulcntr :integer range 0 to 7:= 0; --BEGIN -- IF rising_edge(clk) THEN -- IF (nrst = '0') OR (refrun='1') THEN -- SpeedAlt := (OTHERS => '0'); -- summ := (OTHERS => '0'); -- FOR i IN 0 TO 7 LOOP -- BUFF(i):= X"0000"; -- END LOOP; -- for i in 0 to 5 LOOP -- accel(i) <= (OTHERS => '0'); -- Eacc(i) <= (OTHERS => '0'); -- END LOOP; -- j:= 0; -- acc <= (OTHERS => '0');--inputA Multiplikator -- KorrA <= (OTHERS => '0');--inputB Multiplikator -- stateAcc <= 0; -- cntr:= 0;-- scaninterval -- mulcntr := 0; -- ELSE -- for i in 0 to 5 LOOP -- ---wenn keine korrektur dann svorsXY abschalten---------- -- IF korrXY(i/2)(15 DOWNTO 8) = X"00" THEN -- Eacc(i) <= (OTHERS => '0'); -- ELSE -- korrektur acc aktiv -- CASE stateAcc IS -- WHEN 0 => -- KorrA <= korrXY(i/2)(15 DOWNTO 8);-- Acc Korrekturwert für Input B AccKorAX(mulkorr) -- IF cntr = 20000 THEN --interval abgelaufen -- j := 7; -- FOR i IN 0 TO 6 LOOP -- neue wert in buffer einlesen -- BUFF(j):= BUFF(j - 1); -- shift BUFF( platz machen) -- j := j - 1; -- END LOOP; -- BUFF(0) := Speed(i) - SpeedAlt; -- aktuell acceleration speichern -- SpeedAlt := speed(i); -- stateAcc <= 1; -- ELSE -- cntr := cntr + 1; -- stateAcc <= 0; -- END IF; -- WHEN 1 => -- summ := X"0000"; -- summ := BUFF(0) + BUFF(1) + BUFF(2) + BUFF(3) + BUFF(4) + BUFF(5) + BUFF(6) + BUFF(7); -- --0 mod 2=0,1mod2=1,2mod2=0.... -- CASE i IS -- WHEN 0 => -- IF AxKonREG(9)= X"00" THEN -- accel(0) <= X"0000";--wenn Scchleppfehler korr abgeschaltet -- ELSE accel(0) <= summ(15 DOWNTO 0); --durschnittdifferenz -- END IF; -- WHEN 1 => -- IF AxKonREG(10)= X"00" THEN -- accel(1) <= X"0000";--wenn Scchleppfehler korr abgeschaltet -- ELSE accel(1) <= summ(15 DOWNTO 0); --durschnittdifferenz -- END IF; -- WHEN 2 => -- IF AxKonREG(33)= X"00" THEN -- accel(2) <= X"0000";--wenn Scchleppfehler korr abgeschaltet -- ELSE accel(2) <= summ(15 DOWNTO 0); --durschnittdifferenz -- END IF; -- WHEN 3 => -- IF AxKonREG(34)= X"00" THEN -- accel(3) <= X"0000";--wenn Scchleppfehler korr abgeschaltet -- ELSE accel(3) <= summ(15 DOWNTO 0); --durschnittdifferenz -- END IF; -- WHEN 4 => -- IF AxKonREG(57)= X"00" THEN -- accel(4) <= X"0000";--wenn Scchleppfehler korr abgeschaltet -- ELSE accel(4) <= summ(15 DOWNTO 0); --durschnittdifferenz -- END IF; -- WHEN 5 => -- IF AxKonREG(58)= X"00" THEN -- accel(5) <= X"0000";--wenn Scchleppfehler korr abgeschaltet -- ELSE accel(5) <= summ(15 DOWNTO 0); --durschnittdifferenz -- END IF; -- END CASE; ---- IF Lim(10) = '0' THEN -- wenn Scchleppfehler korr abgeschaltet ---- accel(i) <= X"0000"; ---- ELSE -- Schleppfehler korr Eingeschaltet ---- accel(i) <= summ(15 DOWNTO 0); --durschnittdifferenz von letzten 8 werten ausgebwen ---- END IF; -- acc <= accel(i); -- KorrA <= korrXY(i/2)(15 DOWNTO 8);-- Acc Korrektur wert für Input B AccKorAX(mulkorr) -- mulcntr := clkmul; -- stateAcc <= 2; -- WHEN 2 => --------------Berechnung accelX * KaccX = saccX --- -- IF mulcntr = 0 THEN --SaccX ist fertig berechnet -- ------------Sign Extension saccX To EEaccX------------------------ -- IF sacc(23) = '1' THEN -- negativ -- Eacc(i) <= X"FFFF" & sacc(23 DOWNTO 8); -- 8 bit nach komma -- ELSE Eacc(i) <= X"0000" & sacc(23 DOWNTO 8); -- END IF; -- ------------- -- cntr := 0; -- stateAcc <= 0; -- ELSE -- mulcntr := mulcntr - 1; -- stateAcc <= 2; -- END IF; -- WHEN OTHERS => stateAcc <= 0; -- END CASE; -- END IF;--IF skorrXY(15 DOWNTO 8) -- END LOOP; -- -- END IF;-- if nrst/else -- END IF; -- if clk --END PROCESS;--Abtastspeed --===================================================================== --=========pfrq SLV(17..0): Anzahl clk /Periode (frq) arith durschnitt========= -- Interpolator eingangsfrequenz "frq" wird gemessen und -- und in Anzahl clk in vorscntr gespeichert ---TYPE T_BUFF6 IS ARRAY(0 to 7) OF STD_LOGIC_VECTOR(26 DOWNTO 0);-- 27 bit --CONSTANT maxper :integer range 0 to 16777215:= 16000000;--160mS = 6.25 Hz --CONSTANT minper :integer range 0 to 16777215:= 600;--6us =>166 kHz --TYPE T_BUFF IS ARRAY(0 to 3) OF STD_LOGIC_VECTOR(15 DOWNTO 0); --TYPE T_BUFF1 IS ARRAY(0 to 7) OF STD_LOGIC_VECTOR(15 DOWNTO 0); --TYPE T_BUFF2 IS ARRAY(0 to 4) OF STD_LOGIC_VECTOR(15 DOWNTO 0); ------------------------------------------------------------------- --TYPE T_ZWSP IS ARRAY(0 TO 5) OF STD_LOGIC_VECTOR(23 DOWNTO 0); --TYPE T_BUFF3 IS ARRAY(0 to 4) OF STD_LOGIC_VECTOR(31 DOWNTO 0); --TYPE T_BUFF4 IS ARRAY(0 to 6) OF STD_LOGIC_VECTOR(31 DOWNTO 0); --TYPE T_BUFF5 IS ARRAY(0 to 8) OF STD_LOGIC_VECTOR(31 DOWNTO 0); --TYPE T_BUFF6 IS ARRAY(0 to 7) OF STD_LOGIC_VECTOR(26 DOWNTO 0);-- 27 bit -------------------------------------------------------------------------------------------- frqperiod: PROCESS(clk) --SIGNAL periode :integer range 0 to 16777215;-- 2 ^24 -- 16000000 = F42400 Hex --pfrq :std_logic_vector(23 downto 0);--Bahn-Periode in anzahl CLK VARIABLE cntr :integer;-- VARIABLE summ :STD_LOGIC_VECTOR(26 DOWNTO 0):= "000" & X"000000";-- 27 bit (24 + 3) VARIABLE j :INTEGER RANGE 0 TO 7:= 0; VARIABLE BUFF : T_BUFF6;--0 to 7) OF SLV(26 DOWNTO 0);-- 27 bit BEGIN IF rising_edge(clk) THEN ------------------------------------- IF nrst = '0' THEN cntr := 0;-- clk Zähler statePer <= 0; -------------------- summ := (OTHERS => '0'); FOR i IN 0 TO 7 LOOP BUFF(i):= "000" & X"000000";-- 27 bit END LOOP; j:= 0; ELSE CASE statePer IS WHEN 0 => IF frq = '0' THEN --wenn kein impuls warten statePer <= 0; ELSE statePer <= 1;-- impuls END IF; WHEN 1 => IF frq = '1' THEN -- warten bis Impuls fertig cntr := cntr + 1;--Impuls länge mitzählen statePer <= 1; ELSE -- fallende flanke cntr := cntr + 1; statePer <= 2;-- impuls fertig END IF; WHEN 2 => IF frq = '0' THEN --warten so lang pause cntr := cntr + 1;-- Pause clk dazu j := 7; statePer <= 2; ELSE FOR i IN 0 TO 6 LOOP -- neue wert in buffer einlesen BUFF(j):= BUFF(j - 1); -- shift BUFF( platz machen) j := j - 1; END LOOP; BUFF(0) := conv_std_logic_vector(cntr,27); --aktuelle Interval speichern ( auf 27 bit begränzt) summ := BUFF(0) + BUFF(1) + BUFF(2) + BUFF(3) + BUFF(4) + BUFF(5) + BUFF(6) + BUFF(7); summ(26 DOWNTO 0) := "000" & summ(26 DOWNTO 3);-- summ := summ / 8 , Durschnitt berechnen periode <= conv_integer(summ);--interval länge speichern cntr := 0; statePer <= 0;-- und repeat END IF; WHEN OTHERS => statePer <= 0; END CASE; IF periode > maxper THEN pfrq <= X"F42400";--16'000'000 = F42400 Hex ELSE pfrq <= conv_std_logic_vector(periode,24); END IF; END IF;--nrst,else END IF;-- clk END PROCESS; --=====================Ende LRK Processen================================================ --============================================================== ctimer:PROCESS(clk) VARIABLE i :integer:= 0; BEGIN IF rising_edge(clk) THEN IF nrst = '0' THEN TIMER <= '0'; i := 60000000; ELSE IF i < 60000000 THEN i := i + 1; TIMER <= '0'; ELSE TIMER <= '1'; i:= 0; END IF; END IF; END IF;--if clk END PROCESS; --*********************************************************** -- clk abhängige Signals setdiv :PROCESS(clk) BEGIN IF rising_edge(clk) THEN LDAC <= LDAC12 AND LDAC34 AND LDAC56;-- LDAC signal END IF; END PROCESS; --======================================================================= --*****IMPLEMENTATION ***************************** --=========Implementation FP funktionen fü Deformation Berechnung ======= ---Axdcalc cIntFPAx : IntToFP port map(a=>InpFP1,clk=>clk,ce=>ceIstFP,result=>OutFP1); cistToAx : mulFP port map(a=>InpFP1,b=>InpFp2,clk=>clk,ce=>ceIstAxD,result=>OutFp2); -----Xdef----- csubXD : subFP port map(a=>InpX1,b=>PIdiv2,clk=>clk,ce=>ceXD0,result=>OutX1); ccosXD : cosFP port map(nrst=>nrst,clk=>clk,cecos=>ceXD1,ainp=>InpX1,cos=>outX2); cXIntFP : IntToFP port map(a=>FSX,clk=>clk,ce=>ceXD2,result=>FSX_FP); cmulFsXToN : mulFP port map(a=>FSX_FP,b=>C_XIntToN,clk=>clk,ce=>ceXD6,result=>FSX_FPN); cdivXD : divFP port map(a=>FSX_FPN,b=>UXFP,clk=>clk,ce=>ceXD3,result=>Fx_FP); cmulXD : mulFP port map(a=>InpX1,b=>InpX2,clk=>clk,ce=>ceXD4,result=>OutX3); cmulXC : mulFP port map(a=>InpX1,b=>InpX2,clk=>clk,ce=>ceXD5,result=>OutX4); catanAX : atanFP port map(nrst=>nrst,clk=>clk,ceatan=>ceXD7,Xinp=>InpX1,Yinp=>InpX2,atanFP=>OutX5); cmulXResInc : mulFP port map(a=>InpX1,b=>InpX2,clk=>clk,ce=>ceXD8,result=>OutX6); -----Ydef----- csubYD : subFP port map(a=>InpY1,b=>PIdiv2,clk=>clk,ce=>ceYD0,result=>OutY1); ccosYD : cosFP port map(nrst=>nrst,clk=>clk,cecos=>ceYD1,ainp=>InpY1,cos=>outY2); cYIntFP : IntToFP port map(a=>FSY,clk=>clk,ce=>ceYD2,result=>FSY_FP); cmulFsYToN : mulFP port map(a=>FSY_FP,b=>C_YIntToN,clk=>clk,ce=>ceYD6,result=>FSY_FPN); cdivYD : divFP port map(a=>FSY_FPN,b=>UYFP,clk=>clk,ce=>ceYD3,result=>Fy_FP); cmulYD : mulFP port map(a=>InpY1,b=>InpY2,clk=>clk,ce=>ceYD4,result=>OutY3); cmulYC : mulFP port map(a=>InpY1,b=>InpY2,clk=>clk,ce=>ceYD5,result=>OutY4); catanAY : atanFP port map(nrst=>nrst,clk=>clk,ceatan=>ceYD7,Xinp=>InpY1,Yinp=>InpY2,atanFP=>OutY5); cmulYResInc : mulFP port map(a=>InpY1,b=>InpY2,clk=>clk,ce=>ceYD8,result=>OutY6); -----Zdef----- csubZD1 : subFP port map(a=>InpZ1,b=>PIdiv2,clk=>clk,ce=>ceZD0,result=>OutZ1); csubZD2 : subFP port map(a=>InpZ3,b=>PIdiv2,clk=>clk,ce=>ceZD0,result=>OutZ7); ccosZD : cosFP port map(nrst=>nrst,clk=>clk,cecos=>ceZD1,ainp=>InpZ1,cos=>outZ2); cZIntFP : IntToFP port map(a=>FSZ,clk=>clk,ce=>ceZD2,result=>FSZ_FP); cmulFsZToN : mulFP port map(a=>FSZ_FP,b=>C_ZIntToN,clk=>clk,ce=>ceZD6,result=>FSZ_FPN); cdivZD : divFP port map(a=>FSZ_FPN,b=>UZFP,clk=>clk,ce=>ceZD3,result=>Fz_FP); cmulZD : mulFP port map(a=>InpZ1,b=>InpZ2,clk=>clk,ce=>ceZD4,result=>OutZ3); cmulZC : mulFP port map(a=>InpZ1,b=>InpZ2,clk=>clk,ce=>ceZD5,result=>OutZ4); catanAZ : atanFP port map(nrst=>nrst,clk=>clk,ceatan=>ceZD7,Xinp=>InpZ1,Yinp=>InpZ2,atanFP=>OutZ5); cmulZResInc : mulFP port map(a=>InpZ1,b=>InpZ2,clk=>clk,ce=>ceZD8,result=>OutZ6); --=================================================================================== --********************************************************************************* --------------------------------------------------------------------------------- cclkgen : clk_gen PORT MAP (-- Clock in ports CLK_IN1_P => SYSCLK_P, -- vom Clk Generator CLK_IN1_N => SYSCLK_N, -- -- Clock out ports CLK_OUT1 => clk, --100 Mhz System CLK CLK_OUT2 => clkREC, --25 Mhz Receiv CLK CLK_OUT3 => clk5, --10 MHz für Debounce -- Status and control signals RESET => RESET_IN, LOCKED => LOCKED_OUT ); ----------------------------------------- Clkdivider :PROCESS(clk) VARIABLE countAD :INTEGER RANGE 0 TO 20:= 0;--A/D:0.2uS,5 Mhz VARIABLE countSDI :INTEGER RANGE 0 TO 80:= 0;--SDI:0.8uS,1.25 MHz BEGIN IF rising_edge(clk) THEN IF nrst = '0' THEN clkAD <= '0'; clkSDI <= '0'; ELSE IF countAD > 0 THEN countAD := countAD - 1; ELSE countAD := 9; clkAD <= NOT clkAD; END IF; ---------------------- IF countSDI > 0 THEN countSDI := countSDI - 1; ELSE countSDI := 39; clkSDI <= NOT clkSDI; END IF; END IF;--nrst,else END IF;--clk END PROCESS; ---============Interpolatin Modul=========================================== --sAXdif(95..0),--Achsen Sollwertdif output(16Bit/achse) von inv.Transfer ITP/lin stz itpexec: ItpMOdul PORT MAP(nrst,clk, XS,YS,ZS,-- Startpunkt Koordinaten XS,YS,ZS XT,YT,ZT,-- Koordinate X,Y,Z relativ (End-Start:XE-XS....) pfrq=>pfrq, L1 => KonfigTab(0)(15 DOWNTO 0),-- aus konfig tabelle 16 bits L2 => KonfigTab(1)(15 DOWNTO 0),-- 16 bits L3 => KonfigTab(2)(15 DOWNTO 0),-- 16 bits --------------------- Xlin => Xlin,-- koord aus linstz Ylin => Ylin, ebene => Iebene, Xactiv => Xactiv, Yactiv => Yactiv, celin => celin,-- Start LinStz Run --------------------------------- stopp => stopin,-- stop interpolation, nach Endlage,STOPP+ RampRun => sRampRun, strimp => sstrimp, -- start interpolation ce => ce, -- start interpolation von kreis oder XYZ Satz : InversTransf ----------------------- calcok => scalcok,-- signalisiert alle berechnungen sind fertig XAout => XA, --virtuelle aktuelle koordinate YAout => YA, ZAout => ZA, ITPmod => ITPmod,-- itp von itpmodul oAXdif => sAXdif,--Sollwerte output von inv.Transfer oImpLk => sImpLk, ----impulse von xyz itp enditp => enditp, -- ende von Kontur:=0 (enditp-) itprun => itprun, ---- =1:interpolator läuft,aktuelle Sollwerte in AXIS(5..0) testdata => stestdata --- test daten ); --==============RAMP Modul ==================================== cramp: Ramp GENERIC MAP(adrbit, 20) PORT MAP ( clk, -- IN gesamt clk, 200Mhz, output vom DCM nrst => nrst, -- IN reset enditp => enditp, --IN enditp-:Interpolator läuft kontur itprun => itprun, --IN itprun+ :Interpolator läuft prgrun => sprgrun, --IN aktivelow=rampe aktiv,sonst outpulse=itppulse, von CPU ------------Steilheit----------------------------- Steilheit => Steilheit,-- wert aus axKonREG pfrq => pfrq, --Bahn-Periode in anzahl CLK --------------------------------------------- calcok => scalcok, XYimp => itprun, --IN signalisiert das Impulse kommen strimp => sstrimp, --IN Start für neue satz, von CPU stopp => stopin, -- stop Rampe AXdif => sAXdif, --inkrement input von inv.Trans (143..0) outdif => soutdif, --Inkr output Rampe (95..0) ----- radrDR=>adrDR, --OUT Adr.SRAM rncsDR=>ncsDR, --OUT SRAM CS Enable rnweDR=>nweDR, --OUT SRAM Write Enable rnoeDR=>noeDR, --OUT SRAM Output Enable rnadvDR=>nadvDR,--**PSRAM nADV rcreDR =>creDR, --**PSRAM CRE rdataDR=>dataDR, --INOUT SRAM Inp/Outp ordAX => sordAX,---- allle 6 Achsen eingelesen ormpzu=> srmpzu --OUT );--impl RAMP --============Enkoder Inputs===================================== --deb_frq :debounce PORT MAP(frq_in,clk,frq); -------------------------------------------------------------- -- -- Inkremental Geber Interface,clk5,5.469Mhz für Debounce --RESAxx :Bits[7..0]AchseY,Bits[3..0]AchseX:((Dis)Achs,Richtg(Dir),Res1,Res0) :Auflösungen /Ebene --diskr(clk,nrst,sph1,sph0,dir,res1,res0,nimp,vorw) ----------------Encoder Eingänge Entprellen un Synschrnisieren--------------- debA1 :debounce PORT MAP(Encod(0),clk5,Encods(0));--A1:PhaseA,Encod(0) debB1 :debounce PORT MAP(Encod(1),clk5,Encods(1));--A1:PhaseB,Encod(1) debI1 :debounce PORT MAP(Encod(2),clk5,Encods(2));--A1:Index,Encod(2) diskrA1 :R_Diskr PORT MAP(clk=>clk,nrst=>nrst,sph1=>Encods(1),sph0=>Encods(0), dir=>ResA21(2),res1=>ResA21(1),res0=>ResA21(0),nimp=>IstImp(1),vorw=>IstImp(0)); ------------------------------------------------------------------------------ debA2 :debounce PORT MAP(Encod(3),clk5,Encods(3));--A2:PhaseA,Encod(3) debB2 :debounce PORT MAP(Encod(4),clk5,Encods(4));--A2:PhaseA,Encod(4) debI2 :debounce PORT MAP(Encod(5),clk5,Encods(5));--A2:Index,Encod(5) diskrA2 :R_Diskr PORT MAP(clk=>clk,nrst=>nrst,sph1=>Encods(4),sph0=>Encods(3), dir=>ResA21(6),res1=>ResA21(5),res0=>ResA21(4),nimp=>IstImp(3),vorw=>IstImp(2)); -------------------------------------------------------------------------------- debA3 :debounce PORT MAP(Encod(6),clk5,Encods(6));--A3:PhaseA,Encod(6) debB3 :debounce PORT MAP(Encod(7),clk5,Encods(7));--A3:PhaseB,Encod(7) debI3 :debounce PORT MAP(Encod(8),clk5,Encods(8));--A3:Index,Encod(8) diskrA3 :R_Diskr PORT MAP(clk=>clk,nrst=>nrst,sph1=>Encods(7),sph0=>Encods(6), dir=>ResA43(2),res1=>ResA43(1),res0=>ResA43(0),nimp=>IstImp(5),vorw=>IstImp(4)); ---------------------------------------------------------------------------------- debA4 :debounce PORT MAP(Encod(9),clk5, Encods(9)); debB4 :debounce PORT MAP(Encod(10),clk5,Encods(10)); debI4 :debounce PORT MAP(Encod(11),clk5,Encods(11));--A4:Index,Encod(11) diskrA4 :R_Diskr PORT MAP(clk=>clk,nrst=>nrst,sph1=>Encods(10),sph0=>Encods(9), dir=>ResA43(6),res1=>ResA43(5),res0=>ResA43(4),nimp=>IstImp(7),vorw=>IstImp(6)); --------------------------------------------------------------------------------- debA5 :debounce PORT MAP(Encod(12),clk5,Encods(12));--A5:PhaseA,Encod(12) debB5 :debounce PORT MAP(Encod(13),clk5,Encods(13));--A5:PhaseB,Encod(13) debI5 :debounce PORT MAP(Encod(14),clk5,Encods(14));--A5:Index,Encod(14) diskrA5 :R_Diskr PORT MAP(clk=>clk,nrst=>nrst,sph1=>Encods(13),sph0=>Encods(12), dir=>ResA65(2),res1=>ResA65(1),res0=>ResA65(0),nimp=>IstImp(9),vorw=>IstImp(8)); ---------------------------------------------------------------------------------- debA6 :debounce PORT MAP(Encod(15),clk5,Encods(15)); debB6 :debounce PORT MAP(Encod(16),clk5,Encods(16)); debI6 :debounce PORT MAP(Encod(17),clk5,Encods(17));--A6:Index,Encod(17) diskrA6 :R_Diskr PORT MAP(clk=>clk,nrst=>nrst,sph1=>Encods(16),sph0=>Encods(15), dir=>ResA65(6),res1=>ResA65(5),res0=>ResA65(4),nimp=>IstImp(11),vorw=>IstImp(10)); ---------------------------------------------------------------------------------- -------------- Endlage entprellen und synchronisieren -------------------- debE1R :debounce PORT MAP(invZuEnd(0),clk5,ZuEnds(0)); debE1L :debounce PORT MAP(invZuEnd(1),clk5,ZuEnds(1)); debE2R :debounce PORT MAP(invZuEnd(2),clk5,ZuEnds(2)); debE2L :debounce PORT MAP(invZuEnd(3),clk5,ZuEnds(3)); ----- debE3R :debounce PORT MAP(invZuEnd(4),clk5,ZuEnds(4)); debE3L :debounce PORT MAP(invZuEnd(5),clk5,ZuEnds(5)); debE4R :debounce PORT MAP(invZuEnd(6),clk5,ZuEnds(6)); debE4L :debounce PORT MAP(invZuEnd(7),clk5,ZuEnds(7)); ----- debE5R :debounce PORT MAP(invZuEnd(8),clk5,ZuEnds(8)); debE5L :debounce PORT MAP(invZuEnd(9),clk5,ZuEnds(9)); debE6R :debounce PORT MAP(invZuEnd(10),clk5,ZuEnds(10)); debE6L :debounce PORT MAP(invZuEnd(11),clk5,ZuEnds(11)); --============================================================== -- Eingänge Synchronisation -- ************ nrst <= Locked_out; --synnrst :synch PORT MAP(nrst_in,clk,nrst); syn_frq :synch PORT MAP(frq_in,clk,frq); --============================================================= --===========SIGNALE MASTER CPU16 =========================== --synmadr0 :synch PORT MAP(m_adr_in(0),clk,m_adr(0)); --synmadr1 :synch PORT MAP(m_adr_in(1),clk,m_adr(1)); ------------------------------------------------------------- synmnrd :synch PORT MAP(m_nrd_in,clk,m_nrd); synmnwr :synch PORT MAP(m_nwr_in,clk,m_nwr); synmncs :synch PORT MAP(m_ncs_in,clk,m_ncs); ------------Flanken detektor----------------------------------------- fd_m_nwr :fdnegneg PORT MAP(clk,nrst, m_nwr, fm_nwr); fd_m_nrd :fdnegneg PORT MAP(clk,nrst, m_nrd, fm_nrd); ---- Master CPU16 Signale Fertig ---------------------- --==========***********************===================== --=========== Signale uControler Silab================= synnwr :synch PORT MAP(nwr_in,clk,nwr); synnrd :synch PORT MAP(nrd_in,clk,nrd); synncs :synch PORT MAP(ncs_in,clk,ncs); -------------Flanken Detektor------------------------------------- --fd_nwr :fdnegneg PORT MAP(clk,nrst, nwr, fsnwr); --fd_nrd :fdnegneg PORT MAP(clk,nrst, nrd, fsnrd); --fd_uc_nwr :fdnegneg PORT MAP(clk,nrst, nwr, fnwr);--flanke wr von Silab uC --=========================================================================== --**************************************************************************************** --========== NC Satz ausführung, ITP steuern------- --SIGNAL ITP :std_logic_vector(2 DOWNTO 0):="000";--Itp bits für Status gemäss Ebenen --SIGNAL IEbene :STD_LOGIC_VECTOR(3 DOWNTO 0):= "0000";-- Ebene von LinSatz -- mit itp =0 (Bit im Status Saz)wird dem Master signalisiert das der Master neue Satz senden kann. SatzExec: PROCESS(clk) VARIABLE cntclk :INTEGER RANGE 0 TO 1023:= 0; VARIABLE ITPalt :std_logic_vector(2 DOWNTO 0) := "000"; BEGIN IF rising_edge(clk) THEN IF (nrst = '0')THEN cntclk := 0; StateSatz <= 0; ITP <= "000"; ITPalt := "000"; updatSkor <= '0'; ELSE CASE StateSatz IS WHEN 0 => IF celin = '1' THEN ITP <= ITPmod; StateSatz <= 1;-- itp Lin oder XYZ läuft ELSIF ce = '1' THEN -- Kreis oder XYZ Satz StateSatz <= 1; ELSE StateSatz <= 0;--warten END IF; ---------------------------------- WHEN 1 => -- warten auf itp lin init ITP <= ITPmod; IF ITPrun = '0' THEN StateSatz <= 1;-- warten ELSE -- irprun = 1 ITPalt := ITPmod; StateSatz <= 2;-- dann weiter END IF; ------------------------------------ WHEN 2 => --- IF ITPrun = '1' THEN ITP <= ITPalt; StateSatz <= 2;-- warten ELSE -- irprun = 1 ITP <= ITPalt; StateSatz <= 3;-- dann weiter END IF; WHEN 3 => --- IF sramprun = '1' THEN ITP <= ITPalt;--itp immer noch aktiv StateSatz <= 3;-- warten bis RAMPE fertig ist ELSE ITP <= "000";-- ITPalt := "000";-- reset StateSatz <= 4;-- dann RAMPE fertig END IF; WHEN 4 => --- sposerbits werden in Status übermittelt cntclk := 0; ITP <= "000";-- ITPalt := "000"; StateSatz <= 5; updatSkor <= '1';--S(start) koordinaten nachführen WHEN 5 => IF resetUpdat = '1' THEN updatSkor <= '0';--update S Koord ist ausgeführt StateSatz <= 0; -- und warten auf neue Satz ELSE StateSatz <= 5;-- warten auf Skord update END IF; WHEN OTHERS => StateSatz <= 0; END CASE; END IF;-- if nrst END IF;-- if clk END PROCESS; --================================================================================ -------------------Impulse vorhanden ?------------------------------------------------ --==========Komb Process================================================ impout: PROCESS(nrst,srmpzu,ClkSDI,prgrun,IstImp,scalcOK,sordAX,sLIMXY, strimp,itprun,sTestData, Init12,init34,init56,AllTabOK,Stat,ITP) BEGIN steilheit <= AxKonREG(23) & AxKonREG(22); --------------------------------- -- If refrun = '0' THEN -- SollImp <= sISollImp; -- ELSE SollImp <= sZRefImp; -- END IF; --------------------------------------- sstrImp <= strImp;--strimp,strimp -------------------------------------------------------------- SERVOEN <= Init12 AND Init34 AND Init56 AND AllTabOK;--SollwerteD/a ok & Tabellen ok -------------------------------------------- intReq <= itprun; ramprun <= NOT(srmpzu(1) AND srmpzu(0));-- Entityoutput:ramprun =1 wenn sramzu=11(output) sramprun <= NOT(srmpzu(1) AND srmpzu(0));-- sramprun =1 wenn sramzu=11(output) ----------------------------------------- TestOut(0) <= stestdata(0);--A0 TestOut(1) <= stestdata(1); TestOut(2) <= stestdata(2);--A1 TestOut(3) <= stestdata(3); ------------------------------- TestOut(4) <= stestdata(4);--A2 TestOut(5) <= stestdata(5); TestOut(6) <= stestdata(6);--A3 TestOut(7) <= stestdata(7); ----------------------------- TestOut(8) <= stestdata(8);--A4 TestOut(9) <= stestdata(9); TestOut(10) <= stestdata(10);--Fxw TestOut(11) <= stestdata(11); --------------------------- TestOut(12) <= stestdata(12);--Fyw TestOut(13) <= stestdata(13); TestOut(14) <= stestdata(14);--Fzw TestOut(15) <= stestdata(15); -------------------------------------------------- END PROCESS; --============================================================= --===========Div Signal init ========================= --nrst <= nrst_in; rst <= NOT nrst; m_adr <= m_adr_in; sprgrun <= prgrun; REFRUN <= REFRUN0 OR REFRUN1 OR REFRUN2 OR REFRUN3 OR REFRUN4 OR REFRUN5; ImpIst <= NOT(IstImp(1)) OR NOT(IstImp(3)) OR NOT(IstImp(5)) OR NOT(IstImp(7)) OR NOT(IstImp(9)) OR NOT(IstImp(11));-- --szRefImp <= RefImp(5) & RefImp(4) & RefImp(3) & RefImp(2) & RefImp(1) & RefImp(0);--Ref Impulse invZuEnd <= NOT ZuEND; CLKDA <= ClkSDI; CLK_AD <=CLKAD; RESET_IN <= '0'; SetIniPos <= SetIniPos0 OR SetIniPos1 OR SetIniPos2 OR SetIniPos3 OR SetIniPos4 OR SetIniPos5; SetIstSoll <= SetIstSoll0 AND SetIstSoll1 AND SetIstSoll2;--ref Anfahren mit BCODE=40 = (kein Ref), Achsen setzen --------------------------------------------------- --nrst <= nrst_in AND LOCKED_OUT; --CLK_OUT3=>CLKAD,--25 MHz clk für A/D Converter --sstrImp <= strImp;--strimp,strimp -------------------------------------------------------- ---------------------------------------------------------------------- --/////////Impuls Umschaltung zwischen Rampe oder Ref.Controller//// -------------"1010";--Pulse :nimpY,vorwY,nimpX,vorwX --SIGNAL ITPpulse,SollImp,Rampout,RefImp :STD_LOGIC_VECTOR(11 DOWNTO 0):= X"AAA"; --setSollImp :PROCESS(clk) --BEGIN -- IF rising_edge(clk) THEN -- IF (nrst = '0')THEN -- SollImp <= X"AAA"; -- ELSE -- If refrun = '0' THEN -- SollImp <= sISollImp; -- ELSE SollImp <= sZRefImp; -- END IF; -- END IF;-- ende if/else nrst -- END IF;-- end if clk --END PROCESS; --=================================================================================== -----================================================================== END Behavioral;