Forum: FPGA, VHDL & Co. Veränderbares PWM Signal


von Andy (Gast)


Lesenswert?

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 --

von Rick Dangerus (Gast)


Lesenswert?

Bitte liefere doch eine Testbench dazu, damit man sich das Ganze mal im 
Simulator anschauen kann.

Rick

von Jörg (Gast)


Lesenswert?

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

von Andy (Gast)


Lesenswert?

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

von Andy (Gast)


Lesenswert?

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

von lkmiller (Gast)


Lesenswert?

@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
:

von Andy (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.