Hi Leute. Bin total am verzweifeln. Versuchen seit Tagen ein Programm zu schreiben, womit ich mit einem Tastendruck die Pulsbreite eines PWM-Signals vergrößern bzw verkleinern kann bei gleich bleibender Periodendauer. Das PWM Signal ist kein Problem, das funks. Nur soblad ich was programmieren womit ich es ändern möchte, bricht es zusammen. wenn ich es mir am Oszi anschaue. Vielleicht kann mir jemand einen Tip gehen. Wäre super. Quelltext von meiner Realisierung PWM(Puls 1,2ms Periode 20ms) hänge ich dran. Danke -- STANDARD LIBRARIES -- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; -- BEGIN OF ENTITY -- ENTITY PWM_TEST IS -- GLOBAL VARIABLE MAX-COUNT (Periodendauer 20 ms) -- GENERIC (period : INTEGER := 2000); PORT ( -- GLOBAL CLOCK OF MAX II ALTERA -- glb_clk: IN BIT; -- CLOCK FOR DISTANCE MEASUREMENT 100 KHz -- en: IN STD_LOGIC; -- GLOBAL RESET USER PUSH BUTTON S1 -- nReset: IN BIT; -- CLOCK FOR PWM-MODULATOR 50 Hz -- pwm_clk: OUT STD_LOGIC ); END PWM_TEST; -- END OF ENTITY -- -- BEGIN OF ARCHITECTURE -- ARCHITECTURE SCALER OF PWM_TEST IS TYPE STATE_TYPE IS (START, MOTOR_ON, MOTOR_OFF); SIGNAL state : STATE_TYPE; BEGIN PROCESS (glb_clk, en, nReset) -- TEMPORARY VARIABLE FOR TIMING -- VARIABLE cnt : INTEGER := 0; -- GLOBAL RESET -- BEGIN IF (nReset = '0') THEN cnt := 0; state <= START; -- GENERATING NEW CLOCK -- ELSIF (glb_clk'EVENT AND glb_clk='1') THEN IF en = '1' THEN IF cnt < period THEN cnt := cnt + 1; ELSE cnt := 0; END IF; CASE state IS WHEN START => IF cnt = 1 THEN state <= MOTOR_ON; ELSE state <= state; END IF; WHEN MOTOR_ON => IF cnt = 122 THEN state <= MOTOR_OFF; ELSE state <= state; END IF; WHEN MOTOR_OFF => state <= START; END CASE; END IF; END IF; END PROCESS; pwm_clk <= '1' WHEN state = MOTOR_ON ELSE '0'; END SCALER; -- END OF ARCHITECTURE --
Bitte liefere doch eine Testbench dazu, damit man sich das Ganze mal im Simulator anschauen kann. Rick
Hm, Du willst die Pulsbreite ändern, hast aber die Zeile .. IF cnt = 122 THEN .. was ja wohl die von Dir gewünschte Pulspreite definiert. Wenn Du also die Pulsbreite ändern willst, darf 122 wohl nicht als Konstante im Code stehen sondern als Port definiert sein??? Nebenbei bemerkt, formatiere mal Deinen Code, verwende statt BIT lieber std_logic und trenne sequentielle von kombinatorischer Logik, verwende keine Variablen als Zähler sondern SIGNALs, "unsigned" oder "integer range 0 to n" zum Zählen/Rechnen uvm ... Gruss
Hi Jörg. Danke für deine Antwort. Ja habe das funktionierende File mit dem konstanten PWM-Signal (122 Pulsbreite) reingestellt. Will das natürlich mit einem weiteren Programm von außen dann über einen Port beeinflussen. Habe das auch schon alles probiert. Weis nur nicht wie. Wenn ich es nämlich verändern möchte, bekomm ich vom Bord nur ein pulsierendes PWM Signal angezeigt auf dem Oszi. Was meinst du mit trennen der kombinatorischen und sequentiellen Logik. Welchen Vorteil bringt es mir wenn ich, für den Zähler ein Signal statt einer Variable nutze. Ciao
Hi Rick. Der Simulator ist nicht das Problem. Da macht es alles so wie es das soll. Sowohl das PWM Signal fest als auch das veränderbare. Nur wenn ich es über die Hardware laufen lass und es mir mit einem Oszi anschaue pulsiert es unkontrolliert. Und ich habe keine Ahnung weshalb. Ciao
@Andy: Also, das ist mir irgendwie zu kompliziert, die State-Machine ist wie sich mit dem Seil durch die Brust ins Auge zu schiessen... Ein PWM-Signal ist doch nichts anderes als ein Zähler und ein Komparator. Also z.B.
1 | :
|
2 | :
|
3 | clk : in std_logic; |
4 | cmpval : in integer; |
5 | pwm : out std_logic; |
6 | :
|
7 | :
|
8 | constant time20ms: integer := 20000; -- z.B. bei clk = 1MHz |
9 | signal cnt: integer := 0; |
10 | :
|
11 | :
|
12 | process (clk) |
13 | begin
|
14 | if rising_edge(clk) then -- ZÄHLER |
15 | if (cnt < time20ms) then |
16 | cnt <= cnt+1; |
17 | else
|
18 | cnt <= 0; |
19 | end if; |
20 | end if; |
21 | end process; |
22 | |
23 | pwm <= '1' when cmpval<cnt else '0'; -- KOMPARATOR |
24 | :
|
25 | :
|
Hi lkmiller Ja ist richtig. Das ist natürlich viel einfacher. Ich werde das mal so ausprobieren. Danke schön. Ciao
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.