www.mikrocontroller.net

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


Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 --

Autor: Rick Dangerus (Gast)
Datum:

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

Rick

Autor: Jörg (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: lkmiller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
:
:
clk    : in std_logic;
cmpval : in integer;
pwm    : out std_logic;
:
:
constant time20ms: integer := 20000; -- z.B. bei clk = 1MHz
signal cnt: integer := 0;
:
:
process (clk)
begin
   if rising_edge(clk) then          -- ZÄHLER
      if (cnt < time20ms) then
         cnt <= cnt+1;
      else
         cnt <= 0;
      end if;
   end if;
end process;

pwm <= '1' when cmpval<cnt else '0'; -- KOMPARATOR
:
:

Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi  lkmiller

Ja ist richtig. Das ist natürlich viel einfacher. Ich werde das mal so 
ausprobieren. Danke schön. Ciao

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.