Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial programming >> VHDL

Een PWM-controller maken in VHDL

Pulsbreedtemodulatie (PWM) is een efficiënte manier om analoge elektronica te besturen vanaf puur digitale FPGA-pinnen. In plaats van te proberen de analoge spanning te regelen, schakelt PWM snel de voedingsstroom op vol vermogen naar het analoge apparaat in en uit. Deze methode geeft ons nauwkeurige controle over het voortschrijdend gemiddelde van de energie die aan het consumentenapparaat wordt geleverd.

Voorbeelden van use cases die goede kandidaten zijn voor PWM zijn audiomodulatie (luidsprekers), lichtintensiteitsregeling (lampen of LED's) en inductiemotoren. De laatste omvat servomotoren, computerventilatoren, pompen, borstelloze gelijkstroommotoren voor elektrische auto's, en de lijst gaat maar door.

Zie ook:
RC-servocontroller die PWM gebruikt vanaf een FPGA-pin

Hoe PWM werkt

Door de voeding van een apparaat met een hoge frequentie in en uit te schakelen, kunnen we de gemiddelde stroom die er doorheen gaat nauwkeurig regelen. De onderstaande afbeelding toont de basis van hoe PWM werkt. De PWM-uitgang bestuurt een binaire schakelaar die het vermogen op 100% of 0% kan instellen. Door snel af te wisselen tussen de twee uitersten, is het gemiddelde van het glijdende venster een functie van de tijd die in elk van de staten wordt doorgebracht.

Inschakelduur

De duty-cycle is de sleutel tot het regelen van het vermogen dat in PWM aan het analoge apparaat wordt gegeven. De term duty cycle betekent hoeveel tijd de PWM-uitgang in de AAN-positie doorbrengt. Het is gebruikelijk om de duty cycle als een percentage te beschrijven, zoals weergegeven in de onderstaande afbeelding. In mijn VHDL-voorbeeld zal ik later in dit artikel echter een niet-ondertekend binair getal gebruiken. Het is logischer voor ons om een ​​binair getal te gebruiken, dat de volledige resolutie van de duty cycle in onze VHDL-implementatie kan vertegenwoordigen.

Met een duty cycle van 0 zou de PWM-uitgang continu in de UIT-positie blijven, terwijl deze bij 100% non-stop in de AAN-positie zou zijn. De mate van nauwkeurigheid die de PWM-controller kan uitoefenen op het payload-effect is direct gerelateerd aan de lengte van de PWM-teller. We zullen zien hoe dit werkt in de VHDL-code wanneer we later in dit artikel een PWM-controller implementeren.

De formule om de binaire weergave van de duty cycle om te zetten in een percentage wordt hieronder weergegeven.

\mathit{duty\_cycle\_percentage} =\frac{\mathit{commanded\_duty\_cycle} * 100}{2^\mathit{pwm\_bits} - 1}

PWM-frequentie

Als we het hebben over PWM-schakelfrequentie, bedoelen we hoe vaak de PWM-uitgang wisselt tussen de AAN- en UIT-statussen, hoe lang het duurt voordat de PWM-teller is ingelopen. Zoals altijd is de frequentie het omgekeerde van de volledige PWM-periode:

\mathit{pwm\_freq} =\frac{1}{\mathit{pwm\_period}}

De ideale PWM-frequentie hangt af van het soort apparaat dat u bedient. Elk getal groter dan een paar honderd Hertz ziet er met het blote oog uit als een stabiele lichtbron als de consument een LED is. Voor een borstelloze gelijkstroommotor ligt de sweet spot in het bereik van tientallen kilohertz. Stel de frequentie te laag in en u kunt fysieke trillingen ervaren. Met een te snelle oscillatie verspil je energie.

Een probleem om in gedachten te houden is dat de analoge vermogenselektronica niet zo snel is als de digitale FPGA-pin. Een typische PWM-configuratie gebruikt vermogens-MOSFET's als schakelaars om de stroom die door het analoge apparaat vloeit te regelen.

Overweeg het schema in de afbeelding. Het maakt deel uit van het LED-drivercircuit dat wordt gebruikt in mijn geavanceerde Dot Matrix VHDL-cursus. De FPGA-pin bestuurt de poort van de MOSFET en fungeert als een stroomonderbreker voor de in-serie LED. Bij een hogere schakelfrequentie zal de transistor meer tijd besteden aan het niet volledig open of volledig gesloten zijn. Dat vertaalt zich in verspilde energie en overtollige warmteproductie in de MOSFET.

PWM-generatormodule

Laten we een standaard, generieke implementatie van een PWM-controller in VHDL maken. Wat ik bedoel met standaard is dat dit in de buurt komt van wat de meeste ervaren VHDL-ontwerpers zouden creëren als je hen zou vragen een PWM-controller in VHDL te schrijven. Het is algemeen in die zin dat de PWM-frequentie kan worden aangepast aan de meeste toepassingen.

Om onze PWM-generator op een echte FPGA te testen, hebben we naast de PWM-controller nog een paar modules nodig. Ik zal die later presenteren wanneer ik de PWM-module gebruik om de verlichting van een LED op het Lattice iCEstick FPGA-ontwikkelbord te regelen. Maar laten we het eerst hebben over de PWM-generatormodule.

PWM-module-entiteit

Om de module aanpasbaar te maken, heb ik een generieke poort toegevoegd waarmee je twee constanten kunt specificeren tijdens het instantiëren.

De eerste, genaamd pwm_bits , bepaalt de lengte van de interne PWM-teller. Deze constante stelt de bitlengte in, niet de maximale tellerwaarde. U kunt de PWM-frequentie niet specificeren als een specifiek aantal klokperioden. Maar meestal hoeven we de PWM-frequentie niet met 100% nauwkeurigheid in te stellen. De ideale PWM-frequentie is een bereik dat goed werkt in plaats van één exact getal.

De andere generieke constante heet clk_cnt_len . Het specificeert de lengte van een tweede teller die de PWM-frequentie effectief verlaagt. Het werkt als een klokdeler, maar zonder daadwerkelijk een afgeleid kloksignaal te creëren. Merk op dat er een standaardwaarde van 1 aan is toegewezen. Door deze constante in te stellen op 1 wordt de klokverdeler uitgeschakeld en wordt ook de extra logica verwijderd die ermee omgaat.

Ik zal dit uitleggen en de formule voor het berekenen van de exacte PWM-frequentie later in het artikel presenteren.

entity pwm is
  generic (
    pwm_bits : integer;
    clk_cnt_len : positive := 1
  );
  port (
    clk : in std_logic;
    rst : in std_logic;
    duty_cycle : in unsigned(pwm_bits - 1 downto 0);
    pwm_out : out std_logic
  );
end pwm;

Omdat dit een volledig synchrone module is, zijn de eerste twee signalen de klok en reset.

De derde invoer op de poortaangiftelijst is de duty cycle. Zoals je kunt zien aan de VHDL-code hierboven, is de lengte van de duty_cycle signaal volgt de pwm_bits generieke constante. Dit betekent dat de pwm_bits constante bepaalt hoe nauwkeurig u de stroom naar het analoge apparaat kunt regelen.

Het laatste signaal op de entiteit is pwm_out . Dat is het PWM-gemoduleerde stuursignaal, het signaal dat u naar een FPGA-pin leidt en verbindt met de gate van uw MOSFET.

Interne signalen PWM-module

De PWM-module bevat slechts twee interne signalen. De eerste is de PWM-teller, die identiek is aan de duty_cycle invoer. Net als de laatste, de pwm_bits constante bepaalt ook de lengte van dit signaal.

signal pwm_cnt : unsigned(pwm_bits - 1 downto 0);
signal clk_cnt : integer range 0 to clk_cnt_len - 1;

Het tweede interne signaal heet clk_cnt , en zoals de naam al aangeeft, is het voor het tellen van klokcycli. Het is van het type geheel getal, en als u clk_cnt_len . instelt tot 1, het telbereik wordt (0 tot 0) —alleen het cijfer 0.

PWM klokcyclustellerproces

Het proces dat de klokteller implementeert, is eenvoudig. Als de module niet is gereset, telt de logica continu klokcycli, terug naar nul bij de maximale waarde die de clk_cnt geheel getal kan vasthouden.

CLK_CNT_PROC : process(clk)
begin
  if rising_edge(clk) then
    if rst = '1' then
      clk_cnt <= 0;
      
    else
      if clk_cnt < clk_cnt_len - 1 then
        clk_cnt <= clk_cnt + 1;
      else
        clk_cnt <= 0;
      end if;
      
    end if;
  end if;
end process;

Merk op dat als je de standaardwaarde van 1 hebt gebruikt voor de clk_cnt_len generiek, dit proces zou tijdens de synthese moeten verdampen. Het interne if-statement zal altijd onwaar zijn omdat 0 < 1 - 1 is fout. De waarde van clk_cnt is dan altijd 0. De meeste synthesetools zullen dit herkennen en het hele proces optimaliseren.

PWM-uitvoerproces

Het proces dat het PWM-uitgangssignaal instelt, bestuurt ook de PWM-teller. Het verhoogt de PWM-teller wanneer de klokcyclusteller 0 is. Dat is hoe het PWM-frequentiebegrenzingsmechanisme werkt.

Aanvankelijk was ik van plan om alleen if clk_cnt = 0 then . te schrijven op regel 9, maar ik ontdekte dat de synthesetool niet alle logica met betrekking tot de klokteller verwijderde toen ik de standaard clk_cnt_len gebruikte waarde van 1. Echter, inclusief clk_cnt_len in de if-statement deed de truc. Het zou geen nadelige effecten moeten hebben op de synthese omdat clk_cnt_len is een constante. De synthesetool kan tijdens het compileren de waarde ervan bepalen en vervolgens beslissen of de inhoud van het proces overbodig is of niet.

PWM_PROC : process(clk)
begin
  if rising_edge(clk) then
    if rst = '1' then
      pwm_cnt <= (others => '0');
      pwm_out <= '0';

    else
      if clk_cnt_len = 1 or clk_cnt = 0 then

        pwm_cnt <= pwm_cnt + 1;
        pwm_out <= '0';

        if pwm_cnt = unsigned(to_signed(-2, pwm_cnt'length)) then
          pwm_cnt <= (others => '0');
        end if;

        if pwm_cnt < duty_cycle then
          pwm_out <= '1';
        end if;

      end if;
    end if;
  end if;
end process;

Wanneer clk_cnt_len groter is dan 1, de pwm_cnt signaal gedraagt ​​zich als een vrijlopende teller, die oploopt wanneer clk_cnt is 0. Het is een niet-ondertekend type, dat automatisch teruggaat naar 0 wanneer het overloopt. Maar we moeten ervoor zorgen dat het de hoogste waarde overslaat voordat het terugloopt naar nul.

Op regel 14 in de bovenstaande code controleer ik of de teller op de op een na hoogste waarde staat. Als dit het geval is, stellen we deze nu op 0 in. Ik gebruik een truc die werkt, ongeacht hoe lang de pwm_cnt signaal is. Door de to_signed . te gebruiken functie, maak ik een nieuwe ondertekende constante met dezelfde lengte als pwm_cnt , maar met de waarde -2.

Het ondertekende nummer -2 in VHDL, en computers in het algemeen, zal altijd een reeks van enen zijn en een 0 op de meest rechtse positie. Dat komt door de manier waarop tekenextensie werkt. Lees daar meer over in mijn eerdere tutorial:

Ondertekend en niet-ondertekend gebruiken in VHDL

Als we ten slotte het ondertekende type naar een niet-ondertekend type casten, krijgen we de op één na hoogste waarde die pwm_cnt kan houden.

Op regel 18 controleren we of de vrijlopende PWM-teller groter is dan de duty cycle-ingang. Als dat waar is, stellen we de PWM-uitgang in op '1' omdat we ons in de AAN-periode van de werkcyclus bevinden.

Daarom moesten we de PWM-teller terugbrengen naar 0 op de op één na hoogste waarde. Als de PWM-teller de hoogst mogelijke waarde zou kunnen bereiken die de duty-cycle kan hebben, zou het niet mogelijk zijn om de duty-cycle op 100% in te stellen. De pwm_cnt < duty_cycle regel zou altijd onwaar zijn als pwm_cnt was op zijn maximale waarde.

Het is logisch omdat we naast de tussenliggende duty cycle-stappen ook de volledig UIT- en AAN-statussen moeten weergeven. Stel je voor dat pwm_bits is ingesteld op 2, en doorloop de hele telreeks als een mentale oefening om te zien wat ik bedoel!

\mathit{pwm\_hz} =\frac{\mathit{clk\_hz}}{(2^\mathit{pwm\_bits} - 1) * \mathit{clk\_cnt\_len}}

Door met deze feiten rekening te houden, kunnen we de bovenstaande formule afleiden voor het berekenen van de precieze PWM-frequentie. Terwijl clk_hz is de frequentie van de FPGA-systeemklok, de andere twee variabelen zijn de generieke invoerconstanten.

Bovenste module

Om de PWM-module op echte hardware te testen, heb ik een implementatie gemaakt die de verlichting van de power-on-LED op de Lattice iCEstick regelt. Ik gebruik dit betaalbare FPGA-ontwikkelbord in zowel mijn VHDL Fast-Track beginnerscursus als voor mijn geavanceerde Dot Matrix FPGA-cursus.

De afbeelding hierboven toont de voorkant van de USB-pluggable iCEstick met de power-on LED aangegeven door de pijl. Er zijn vijf LED's op de iCEstick gerangschikt in een sterpatroon. De power-on LED is groen, terwijl de andere rood gekleurd licht uitstralen. Op de iCEstick is er een speciale FPGA-pin voor elk van de LED's. Raadpleeg de gebruikershandleiding van de iCEstick om de exacte pinnummers te zien om ze te bedienen.

Onderstaand schema laat zien hoe de submodules in de topmodule worden aangesloten. We hebben het al gehad over de PWM-module, en de teller- en resetmodules zal ik verderop in dit artikel kort beschrijven.

Top module entiteit

In plaats van de constanten in de bovenste module hard te coderen, verklaar ik ze als generiek op de entiteit op het hoogste niveau. Vervolgens wijs ik standaardwaarden toe die geschikt zijn voor de iCEstick. Een voordeel van deze aanpak is dat u deze waarden in de testbench kunt overschrijven om de simulatie te versnellen. Ik wijs niets toe aan de generieke geneesmiddelen wanneer ik het ontwerp synthetiseer. Zo komen de juiste standaardwaarden in het gerouteerde ontwerp terecht.

We geven pwm_bits door en clk_cnt_len naar de generieke geneesmiddelen op de PWM-module-entiteit met dezelfde namen. De klokfrequentie van de iCEstick-oscillator is 12 Mhz. Door de eerder gepresenteerde formule te gebruiken, kunnen we deze waarden invoegen om de PWM-frequentie te berekenen:\frac{12e6}{(2^8 - 1) * 47} \circa 1 \mathit{kHz}

entity pwm_led is
  generic (
    pwm_bits : integer := 8;
    cnt_bits : integer := 25;
    clk_cnt_len : positive := 47
  );
  port (
    clk : in std_logic;
    rst_n : in std_logic; -- Pullup

    led_1 : out std_logic;
    led_2 : out std_logic;
    led_3 : out std_logic;
    led_4 : out std_logic;
    led_5 : out std_logic
  );
end pwm_led;

Je hebt misschien gemerkt dat er een derde constante is, cnt_bits , in de declaratie van generieke geneesmiddelen in de bovenstaande code. Het regelt de lengte van een zelfwikkelende zaagtandteller. We gaan deze extra teller gebruiken om een ​​geleidelijke verlichting van de power-on-LED te creëren, zodat we de PWM-module in realtime kunnen zien werken.

We zullen de hoge bits van deze nieuwe teller aansluiten op de duty cycle-ingang van de PWM-module. Omdat deze teller klokcycli telt, zijn de cnt_bits generiek bepaalt de pulsfrequentie van de power-on LED. De formule, die een functie is van de klokfrequentie en de tellerlengte, wordt hieronder weergegeven.

\frac{2^{\mathit{cnt\_bits}}}{\mathit{clk\_hz}} =\frac{2^{25}}{12e6} \circa 2,8 \mathit{Hz}

In de poortaangifte heb ik de reset-invoer gefixeerd met _n , wat aangeeft dat de externe reset een negatieve polariteit heeft. We zullen de Lattice FPGA configureren om een ​​interne pull-up weerstand op deze pin te gebruiken.

Ten slotte kun je zien dat ik alle aanwezige LED's op de iCEstick heb vermeld in de poortdeclaratie. We gaan alleen LED nummer 5 gebruiken, maar we moeten de andere LED's actief aansturen. Als ze niet zijn aangesloten, lichten ze op in een vage rode kleur.

Als u de VHDL-code en de beperkingenbestanden van naderbij wilt bekijken, voert u uw e-mailadres in het onderstaande formulier in. U ontvangt een Zip-bestand met de volledige code met ModelSim en Lattice iCEcube2-projecten.

Bovenmodule interne signalen

Ik houd mijn topmodules graag vrij van RTL-logica. Het is een concept dat een structurele module wordt genoemd . Mijn ervaring is dat het gemakkelijker is om een ​​gestructureerd VHDL-project te onderhouden als je RTL-logica en interconnectie scheidt. De onderstaande code toont de signaaldeclaraties in de bovenste module en de gelijktijdige signaaltoewijzingen.

architecture str of pwm_led is

  signal rst : std_logic;
  signal cnt : unsigned(cnt_bits - 1 downto 0);
  signal pwm_out : std_logic;

  alias duty_cycle is cnt(cnt'high downto cnt'length - pwm_bits);

begin

  led_1 <= '0';
  led_2 <= '0';
  led_3 <= '0';
  led_4 <= '0';

  led_5 <= pwm_out;

Eerst declareren we een resetsignaal dat onze niet-geïnverteerde, synchrone versie van de externe reset zal zijn.

Het tweede gedeclareerde signaal, genaamd cnt , is de oneindig verpakkende klokcyclusteller. Het is een niet-ondertekend type dat op elk moment de status van onze zaagtandgolf met LED-intensiteit vasthoudt.

De volgende is de pwm_out signaal. We hadden de pwm_out . kunnen verbinden signaal van de PWM-module rechtstreeks naar de led_5 output, maar ik wilde pwm_out . observeren in de simulator. De synthesetool zal uitzoeken dat de twee signalen tot hetzelfde net behoren. Het kost geen extra middelen.

Eindelijk komt de verklaring van de duty_cycle vector - deze keer gebruikte ik de alias trefwoord in plaats van een nieuw signaal te creëren. VHDL-aliassen werken een beetje zoals macro's in C. Als we de duty_cycle gebruiken naam van nu af aan, zal de compiler deze vervangen door de hoge bits van de cnt vector.

Na het begin zoekwoord, wijzen we de pwm_out signaal naar de led_5 uitvoer. Alle andere LED's zijn vast bedraad op '0' om te voorkomen dat ze rood gekleurd licht oplichten.

Instantiaties

Voordat we externe signalen in de FPGA gebruiken, moeten we ze altijd synchroniseren met de interne systeemklok. Anders kunnen we metastabiliteitsproblemen ondervinden, problemen die moeilijk te debuggen zijn.

RESET : entity work.reset(rtl)
  port map (
    clk => clk,
    rst_n => rst_n,
    rst => rst
  );

De externe reset is geen uitzondering, maar omdat ik geen RTL-logica toesta in de structurele module op het hoogste niveau, implementeren we de reset-synchronizer als een zelfstandige module.

De volgende instantie is de PWM-module, zoals weergegeven in het onderstaande codefragment. In de instantie van de PWM-module gebruiken we de duty_cycle alias voor het toewijzen van de meest significante bits van de cnt vector naar de duty_cycle invoer. Dat zal de helderheid van de LED intensiveren totdat de teller zijn maximale waarde bereikt. Wanneer cnt keert terug naar nul, de LED gaat even uit en de cyclus herhaalt zich.

PWM : entity work.pwm(rtl)
  generic map (
    pwm_bits => pwm_bits,
    clk_cnt_len => clk_cnt_len
  )
  port map (
    clk => clk,
    rst => rst,
    duty_cycle => duty_cycle,
    pwm_out => pwm_out
  );

De derde en laatste instantie in de bovenste module is de klokcyclusteller, zoals hieronder weergegeven. Om deze module algemener te maken, heb ik een count_enable . toegevoegd signaal. Maar in dit ontwerp zullen we het op een constante '1' zetten omdat we elke klokcyclus willen tellen.

COUNTER : entity work.counter(rtl)
  generic map (
    counter_bits => cnt'length
  )
  port map (
    clk => clk,
    rst => rst,
    count_enable => '1',
    counter => cnt
  );

Laat je e-mailadres achter in het onderstaande formulier als je de volledige VHDL-code voor dit project nodig hebt.

Het simuleren van de pulserende PWM LED

Een belangrijk voordeel van het aanpasbaar maken van de tellerlengtes via generieke geneesmiddelen, is dat u de simulatie kunt versnellen. Meestal zijn we geïnteresseerd in het testen van de overgangen en gebeurtenissen in onze logica. We zijn niet zo happig op het doorlopen van een ultralange toonbank terwijl er verder niets gebeurt in het ontwerp.

Met generieke geneesmiddelen kunnen we deze dingen op een niet-invasieve manier veranderen vanaf de testbank. De onderstaande code toont de waarden die ik aan de generieke kaart heb toegewezen bij het instantiëren van de PWM-module in de testbench.

DUT : entity work.pwm_led(str)
  generic map (
    pwm_bits => 8,
    cnt_bits => 16,
    clk_cnt_len => 1
  )

Wanneer we het gebruik van deze constanten in ModelSim simuleren, is het voldoende om 1400 microseconden op 100 MHz te draaien om twee volledige PWM-cycli te onthullen. Als we de echte waarden hadden gebruikt, zouden we bijna 6 seconden moeten simuleren. Dat zijn 32 miljoen klokcycli van bijna niets anders dan tellen. Het zou een eeuwigheid duren in ModelSim.

De afbeelding hieronder toont de golfvorm van de PWM-simulatie in ModelSim. Ik heb het formaat van de duty_cycle gewijzigd signaal van het standaard nummertype naar een analoge golfpresentatie. U kunt dit in ModelSim doen door met de rechtermuisknop op het signaal in de golfvorm te klikken en Format->Analog (custom)… te selecteren , en stel de pixelhoogte en het gegevensbereik in om overeen te komen met de minimum- en maximumwaarden van uw signaal.

In de golfvorm kunnen we zien waarom het een zaagtandsignaal wordt genoemd. De vrijlopende wikkelteller lijkt op de tanden van een zaagblad.

Merk op hoe de duur van de hoge perioden van de PWM-uitgang (led_5 ) neemt toe naarmate de duty cycle groeit. We kunnen ook zien dat led_5 is een continue '1' heel kort aan het uiteinde van de zaagtand. Dat is wanneer de duty cycle 255 is, de maximale waarde.

Als we de extra if-instructie in de PWM-module niet hebben toegevoegd, degene die de pwm_cnt omhult signaal terug naar nul op de op een na hoogste waarde, zouden we dit niet zien. We zouden nooit het maximale vermogen kunnen bereiken. Het is een veelvoorkomende fout bij het implementeren van PWM-generatoren. Ik heb het ook een of twee keer gedaan.

De FPGA-implementatie

Ik implementeerde het ontwerp op de Lattice iCEstick met behulp van iCEcube2, de ontwerpsoftware van Lattice. De onderstaande lijst toont het resourcegebruik gerapporteerd na plaats en route. Hoewel de iCE40 FPGA klein is, gebruiken de PWM en ondersteunende modules slechts 5% van de beschikbare LUT's.

Resource Usage Report for pwm_led 

Mapping to part: ice40hx1ktq144
Cell usage:
GND             3 uses
SB_CARRY        31 uses
SB_DFF          5 uses
SB_DFFSR        39 uses
SB_GB           1 use
VCC             3 uses
SB_LUT4         64 uses

I/O ports: 7
I/O primitives: 7
SB_GB_IO       1 use
SB_IO          6 uses

I/O Register bits:                  0
Register bits not including I/Os:   44 (3%)
Total load per clock:
   pwm_led|clk: 1

@S |Mapping Summary:
Total  LUTs: 64 (5%)

Na het genereren van de programmeerbitstream in iCEcube2, heb ik de Lattice Diamond standalone programmer gebruikt om de FPGA via USB te configureren.

De onderstaande GIF-animatie laat zien hoe het zaagtandgolf-duty cycle-signaal ervoor zorgt dat de power-on-LED op de iCEstick zich gedraagt. Het licht op met toenemende intensiteit totdat de cnt tegen wraps. Dan wordt de duty cycle allemaal nullen en gaat de LED even uit. Daarna wordt de cyclus oneindig herhaald.

De iCEstick is een goedkoop en veelzijdig FPGA-ontwikkelbord. Het is goed voor beginners, maar het is ook geschikt voor geavanceerde embedded projecten. Bovendien is de Lattice-software ongecompliceerd en gemakkelijk te gebruiken. Daarom gebruik ik de iCEstick zowel in mijn beginnerscursus VHDL als in de gevorderden FPGA-cursus.

Als u al een iCEstick bezit, kunt u het onderstaande formulier gebruiken om het iCEcube2-project te downloaden.

Sinusgolf inschakelduur voor LED-ademhalingseffect

Nu weet je hoe je de verlichting van een LED kunt regelen met PWM.

De LED die pulseert in een zaagtandgolfpatroon is aantoonbaar cooler dan een simpele AAN/UIT-knipperende toepassing. Dat is een typische eerste taak voor VHDL-studenten, en ik weet zeker dat je ooit een LED hebt laten knipperen.

Het knipperen van de LED wordt echter nog indrukwekkender als u een sinusgolf gebruikt om de duty-cycle te regelen. De onderstaande GIF-animatie toont onze PWM-module die de LED pulseert met een sinusoïde intensiteitsvariatie in de tijd.

Ik weet zeker dat je dit soort "ademende" effect op LED's eerder hebt gezien. Dat is hoe de meldings-LED op mijn mobiele telefoon zich gedraagt, en ik denk dat het er natuurlijk uitziet omdat er geen abrupte veranderingen in de lichtintensiteit zijn.

In mijn volgende blogpost laat ik je zien hoe je een sinusgolfgenerator maakt door blok-RAM in FPGA's te gebruiken. En we zullen de pwm_led . aanpassen module om de LED op de iCEstick te pulseren met de intensiteit van de sinusgolf.

Klik hier om naar de volgende blogpost te gaan:
Hoe een ademend LED-effect te creëren met behulp van een sinusgolf die is opgeslagen in blok-RAM

Zie ook:
RC-servocontroller die PWM gebruikt vanaf een FPGA-pin


VHDL

  1. PWM-vermogenscontroller
  2. Een lijst met strings maken in VHDL
  3. Hoe maak je een Tcl-gestuurde testbench voor een VHDL-codeslotmodule?
  4. Simulatie stoppen in een VHDL-testbench
  5. Hoe willekeurige getallen te genereren in VHDL
  6. Hoe maak je een ringbuffer FIFO in VHDL
  7. Hoe maak je een zelfcontrolerende testbank aan
  8. Een gekoppelde lijst maken in VHDL
  9. Een procedure gebruiken in een proces in VHDL
  10. Een functie gebruiken in VHDL
  11. Hoe laad ik een condensator op?