2012-11-27 81 views
1

我想用P控制器(以及稍後的PID)控制電機。 這裏是我使用P控制器的VHDL代碼:執行P控制器

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
USE ieee.numeric_std.ALL; 
USE ieee.STD_LOGIC_ARITH.ALL; 
USE ieee.std_logic_signed.ALL; 

entity P is 
    Port (e : in STD_LOGIC_VECTOR (8 downto 0); 
      PWM : out STD_LOGIC_VECTOR (8 downto 0)); 
end P; 

architecture Behavioral of P is 

signal eInt : integer := 0; 
signal PWMInt : integer := 0; 

--min/max 
signal borne : integer := 255; 

--Gain 
signal Ku : integer := 1; 

--saturation 
component saturation is 
    Port (entier : in integer; 
      borne : in integer; 
      sotie : out STD_LOGIC_VECTOR (8 downto 0)); 
end component; 

begin 

    eInt <= conv_integer(e); 
    PWMInt <= Ku*eInt; 

    sat : saturation port map(PWMInt, borne, PWM); 

end Behavioral; 

其中飽和限量PWM爲「得緊」(使得PWM是在二進制最多255個),e是誤差(命令 - 測量)。

該塊的輸出是一個直接連接到電機的PWM(這是在另一個文件中完成的)。開環工作得很好,閉環很糟糕。我強烈懷疑我處理整數的方式有問題,因爲測試平臺工作正常,但物理實現完全不正確。

回答

2

只要您使用所有這些算術庫,就幾乎不可能知道發生了什麼。

最好的辦法:擺脫std_logic_signed,std_logic_arith,並從numeric_std將端口設置爲signedunsignedconv_integer被來自numeric_std庫的to_integer取代。

如果您不能更改端口,請在整個內部使用(例如)signed,並且只能在輸入/輸出端口上從/到std_logic_vector轉換。

我認爲你正在模擬這個循環?

+0

謝謝!是的,我正在模擬它,爲什麼? –

+0

我正在使用numeric_std。代碼非常簡單,我將錯誤固定到「PWInt <= Ku * eInt」。原來,你是用1代替Ku,然後一切正常。任何猜測? –

+0

現在開始使用類型系統對你有利...... eint和pwmint不只是整數;他們有一個明確的範圍,由E,PWM的大小決定。爲它們定義一個子類型...子類型pwm是整數範圍-256..255;信號eint:pwm;等等...當你看到這些範圍時,你會發現Ku的唯一合理值是1;除非e的範圍在0附近,否則Ku的任何其他值都會使PWM飽和並失去環路控制。在這一點上,我們需要開始思考定點算術,以便更好地控制增益...下一條消息 –