Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> VHDL

Comment créer un contrôleur PWM en VHDL

La modulation de largeur d'impulsion (PWM) est un moyen efficace de contrôler l'électronique analogique à partir de broches FPGA purement numériques. Au lieu d'essayer de réguler la tension analogique, PWM active et désactive rapidement le courant d'alimentation à pleine puissance de l'appareil analogique. Cette méthode nous donne un contrôle précis sur la moyenne mobile de l'énergie fournie à l'appareil consommateur.

Des exemples de cas d'utilisation qui sont de bons candidats pour PWM sont la modulation audio (haut-parleurs), le contrôle de l'intensité lumineuse (lampes ou LED) et les moteurs à induction. Ce dernier comprend les servomoteurs, les ventilateurs d'ordinateur, les pompes, les moteurs à courant continu sans balais pour les voitures électriques, et la liste est longue.

Voir aussi :
Contrôleur d'asservissement RC utilisant PWM à partir d'une broche FPGA

Fonctionnement PWM

En allumant et en éteignant l'alimentation d'un appareil à haute fréquence, nous pouvons contrôler avec précision le courant moyen qui le traverse. L'illustration ci-dessous montre les bases du fonctionnement de PWM. La sortie PWM contrôle un commutateur binaire qui peut régler la puissance à 100 % ou à 0 %. En alternant rapidement entre les deux extrêmes, la moyenne de la fenêtre glissante sera fonction du temps passé dans chacun des états.

Cycle de service

Le rapport cyclique est essentiel pour contrôler la puissance donnée à l'appareil analogique en PWM. Le terme cycle de service signifie combien de temps la sortie PWM passe en position ON. Il est courant de décrire le cycle de service en pourcentage, comme indiqué dans l'image ci-dessous. Cependant, dans mon exemple VHDL, j'utiliserai un nombre binaire non signé plus loin dans cet article. Il est plus logique pour nous d'utiliser un nombre binaire, qui peut représenter la résolution complète du cycle de service dans notre implémentation VHDL.

Avec un rapport cyclique de 0, la sortie PWM resterait en position OFF en permanence, tandis qu'à 100%, elle serait non-stop en position ON. Le degré de précision que le contrôleur PWM peut exercer sur l'effet de charge utile est directement lié à la longueur du compteur PWM. Nous verrons comment cela fonctionne dans le code VHDL lorsque nous implémenterons un contrôleur PWM plus loin dans cet article.

La formule pour convertir la représentation binaire du rapport cyclique en pourcentage est indiquée ci-dessous.

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

Fréquence PWM

Lorsque nous parlons de fréquence de commutation PWM, nous entendons la fréquence à laquelle la sortie PWM alterne entre les états ON et OFF, le temps qu'il faut au compteur PWM pour s'enrouler. Comme toujours, la fréquence est l'inverse de la période PWM complète :

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

La fréquence PWM idéale dépend du type d'appareil que vous contrôlez. Tout nombre supérieur à quelques centaines de Hertz ressemblera à une source de lumière stable à l'œil nu si le consommateur est une LED. Pour un moteur à courant continu sans balais, le point idéal se situe dans la plage des dizaines de kilohertz. Réglez la fréquence trop bas et vous risquez de ressentir des vibrations physiques. Avec une oscillation trop rapide, vous gaspillez de l'énergie.

Un problème à garder à l'esprit est que l'électronique de puissance analogique n'est pas aussi rapide que la broche FPGA numérique. Une configuration PWM typique utilise des MOSFET de puissance comme commutateurs pour contrôler le courant circulant dans l'appareil analogique.

Considérez le schéma montré dans l'image. Cela fait partie du circuit de pilote de LED utilisé dans mon cours avancé Dot Matrix VHDL. La broche FPGA contrôle la porte du MOSFET, agissant comme un disjoncteur pour la LED en série. Avec une fréquence de commutation plus élevée, le transistor passera plus de temps à ne pas être entièrement ouvert ni complètement fermé. Cela se traduit par un gaspillage d'énergie et une production de chaleur excessive dans le MOSFET.

Module générateur PWM

Créons une implémentation standard et générique d'un contrôleur PWM en VHDL. Ce que j'entends par standard est que cela est proche de ce que les concepteurs VHDL les plus expérimentés créeraient si vous leur demandiez d'écrire un contrôleur PWM en VHDL. C'est générique en ce sens que la fréquence PWM est personnalisable pour s'adapter à la plupart des applications.

Pour tester notre générateur PWM sur un vrai FPGA, nous allons avoir besoin de quelques modules supplémentaires en plus du contrôleur PWM. Je les présenterai plus tard lors de l'utilisation du module PWM pour contrôler l'éclairage d'une LED sur la carte de développement Lattice iCEstick FPGA. Mais d'abord, parlons du module générateur PWM.

Entité du module PWM

Pour rendre le module personnalisable, j'ai ajouté un port générique qui vous permet de spécifier deux constantes au moment de l'instanciation.

Le premier, nommé pwm_bits , détermine la longueur du compteur PWM interne. Cette constante définit la longueur en bits, pas la valeur maximale du compteur. Vous ne pourrez pas spécifier la fréquence PWM comme un nombre spécifique de périodes d'horloge. Mais généralement, nous n'avons pas besoin de régler la fréquence PWM avec une précision de 100 %. La fréquence PWM idéale est une plage qui fonctionne bien plutôt qu'un nombre exact.

L'autre constante générique est nommée clk_cnt_len . Il spécifie la longueur d'un deuxième compteur qui abaisse efficacement la fréquence PWM. Il agit comme un diviseur d'horloge, mais sans réellement créer de signal d'horloge dérivé. Notez qu'une valeur par défaut de 1 lui est attribuée. Définir cette constante sur 1 désactive le diviseur d'horloge et supprime également la logique supplémentaire qui le gère.

J'expliquerai cela et présenterai la formule de calcul de la fréquence PWM exacte plus loin dans l'article.

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;

Comme il s'agit d'un module entièrement synchrone, les deux premiers signaux sont l'horloge et la réinitialisation.

La troisième entrée sur la liste de déclaration de port est le rapport cyclique. Comme vous pouvez le voir dans le code VHDL ci-dessus, la longueur du duty_cycle le signal suit les pwm_bits constante générique. Cela signifie que les pwm_bits La constante régit la précision avec laquelle vous pouvez réguler l'alimentation de l'appareil analogique.

Le signal final sur l'entité est pwm_out . C'est le signal de contrôle modulé PWM, celui que vous acheminez vers une broche FPGA et que vous connectez à la porte de votre MOSFET.

Signaux internes du module PWM

Le module PWM ne contient que deux signaux internes. Le premier est le compteur PWM, qui est identique au duty_cycle saisir. Tout comme ce dernier, les pwm_bits constante détermine également la longueur de ce signal.

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

Le deuxième signal interne est nommé clk_cnt , et comme son nom l'indique, c'est pour compter les cycles d'horloge. Il est de type entier, et si vous définissez clk_cnt_len à 1, la plage de comptage sera évaluée à (0 à 0) —juste le chiffre 0.

Processus de compteur de cycle d'horloge PWM

Le processus qui implémente le compteur d'horloge est simple. Si le module n'est pas réinitialisé, la logique comptera les cycles d'horloge en continu, revenant à zéro à la valeur maximale que le clk_cnt nombre entier peut contenir.

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;

Notez que si vous avez utilisé la valeur par défaut de 1 pour le clk_cnt_len générique, ce processus devrait s'évaporer lors de la synthèse. L'instruction interne if sera toujours fausse car 0 < 1 - 1 c'est faux. La valeur de clk_cnt est alors toujours 0. La plupart des outils de synthèse le reconnaîtront et optimiseront l'ensemble du processus.

Processus de sortie PWM

Le processus qui définit le signal de sortie PWM contrôle également le compteur PWM. Il incrémente le compteur PWM lorsque le compteur de cycles d'horloge est à 0. C'est ainsi que fonctionne le mécanisme de limitation de fréquence PWM.

Au départ, je comptais n'écrire que if clk_cnt = 0 then à la ligne 9, mais j'ai découvert que l'outil de synthèse ne supprimait pas toute la logique liée au compteur d'horloge lorsque j'utilisais la valeur par défaut clk_cnt_len valeur de 1. Cependant, y compris clk_cnt_len dans l'instruction if a fait l'affaire. Cela ne devrait pas avoir d'effets néfastes sur la synthèse car clk_cnt_len est une constante. L'outil de synthèse peut déterminer sa valeur au moment de la compilation, puis décider si le contenu du processus est redondant ou non.

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;

Quand clk_cnt_len est supérieur à 1, le pwm_cnt le signal se comporte comme un compteur libre, s'incrémentant lorsque clk_cnt est 0. C'est un type non signé, qui reviendrait automatiquement à 0 lorsqu'il déborderait. Mais nous devons nous assurer qu'il ignore la valeur la plus élevée avant de revenir à zéro.

À la ligne 14 du code ci-dessus, je vérifie si le compteur est à sa deuxième valeur la plus élevée. Si c'est le cas, nous le mettons à 0 à ce stade. J'utilise une astuce qui fonctionnera, peu importe combien de temps le pwm_cnt le signal est. En utilisant le to_signed fonction, je crée une nouvelle constante signée avec la même longueur que pwm_cnt , mais avec la valeur -2.

Le nombre signé -2 en VHDL, et dans les ordinateurs en général, sera toujours une série de 1 et un 0 à l'extrême droite. C'est à cause du fonctionnement de l'extension de signe. En savoir plus à ce sujet dans mon tutoriel précédent :

Comment utiliser signé et non signé en VHDL

Enfin, en convertissant le type signé en non signé, nous obtenons la deuxième valeur la plus élevée que pwm_cnt peut contenir.

Sur la ligne 18, nous vérifions si le compteur PWM libre est supérieur à l'entrée du rapport cyclique. Si cela est vrai, nous définissons la sortie PWM sur "1" car nous sommes dans la période ON du cycle de service.

C'est pourquoi nous avons dû ramener le compteur PWM à 0 à sa deuxième valeur la plus élevée. Si le compteur PWM pouvait atteindre la valeur la plus élevée possible que le rapport cyclique peut avoir, il ne serait pas possible de régler le rapport cyclique sur 100 %. Le pwm_cnt < duty_cycle la ligne serait toujours fausse quand pwm_cnt était à sa valeur maximale.

Cela a du sens car nous devons représenter les états entièrement OFF et ON en plus des étapes intermédiaires du cycle de service. Imaginez que pwm_bits est réglé sur 2, et parcourez toute la séquence de comptage comme un exercice mental pour voir ce que je veux dire !

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

En tenant compte de ces faits, nous pouvons dériver la formule ci-dessus pour calculer la fréquence PWM précise. Tandis que clk_hz est la fréquence de l'horloge du système FPGA, les deux autres variables sont les constantes d'entrée génériques.

Module supérieur

Pour tester le module PWM sur du matériel réel, j'ai créé une implémentation qui régulera l'éclairage de la LED de mise sous tension sur le Lattice iCEstick. J'utilise cette carte de développement FPGA abordable dans mon cours pour débutant VHDL Fast-Track et pour mon cours avancé sur FPGA à matrice de points.

L'image ci-dessus montre l'avant de l'iCEstick enfichable par USB avec le voyant de mise sous tension indiqué par la flèche. Il y a cinq LED sur l'iCEstick disposées en étoile. La LED de mise sous tension est verte, tandis que les autres émettent une lumière de couleur rouge. Sur l'iCEstick, il y a une broche FPGA dédiée pour chacune des LED. Reportez-vous au manuel d'utilisation iCEstick pour voir les numéros de broches exacts pour les contrôler.

Le schéma ci-dessous montre comment les sous-modules du module supérieur sont connectés. Nous avons déjà parlé du module PWM, et je décrirai brièvement les modules de compteur et de réinitialisation plus loin dans cet article.

Entité du module supérieur

Au lieu de coder en dur les constantes dans le module supérieur, je les déclare en tant que génériques sur l'entité de niveau supérieur. Ensuite, j'attribue des valeurs par défaut qui conviennent à l'iCEstick. L'un des avantages de cette approche est que vous pouvez remplacer ces valeurs dans le testbench pour accélérer la simulation. Je n'attribue rien aux génériques lorsque je synthétise le design. Ainsi, les valeurs par défaut correctes se retrouveront dans la conception routée.

Nous transmettrons pwm_bits et clk_cnt_len aux génériques sur l'entité du module PWM avec les mêmes noms. La fréquence d'horloge de l'oscillateur iCEstick est de 12 Mhz. En utilisant la formule présentée précédemment, nous pouvons intégrer ces valeurs pour calculer la fréquence PWM :\frac{12e6}{(2^8 - 1) * 47} \approx 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;

Vous avez peut-être remarqué qu'il existe une troisième constante, cnt_bits , dans la déclaration des génériques dans le code ci-dessus. Il contrôle la longueur d'un compteur en dents de scie à enroulement automatique. Nous allons utiliser ce compteur supplémentaire pour créer un éclairage progressif de la LED de mise sous tension afin que nous puissions observer le fonctionnement du module PWM en temps réel.

Nous allons connecter les bits hauts de ce nouveau compteur à l'entrée du rapport cyclique du module PWM. Parce que ce compteur comptera les cycles d'horloge, les cnt_bits générique détermine la fréquence de pulsation de la LED de mise sous tension. La formule, qui est fonction de la fréquence d'horloge et de la longueur du compteur, est indiquée ci-dessous.

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

Dans la déclaration du port, j'ai postfixé l'entrée de réinitialisation avec _n , indiquant que la réinitialisation externe a une polarité négative. Nous allons configurer le FPGA Lattice pour utiliser une résistance pull-up interne sur cette broche.

Enfin, vous pouvez voir que j'ai répertorié toutes les LED présentes sur l'iCEstick dans la déclaration du port. Nous n'utiliserons que la LED numéro 5, mais nous devons piloter activement les autres LED. S'ils ne sont pas connectés, ils s'illumineront d'une couleur rouge pâle.

Si vous souhaitez examiner de plus près le code VHDL et les fichiers de contraintes, saisissez votre adresse e-mail dans le formulaire ci-dessous. Vous recevrez un fichier Zip avec le code complet avec les projets ModelSim et Lattice iCEcube2.

Signaux internes du module supérieur

J'aime garder mes modules supérieurs exempts de logique RTL. C'est un concept qui s'appelle un module structurel . D'après mon expérience, il est plus facile de maintenir un projet VHDL structuré lorsque vous séparez la logique RTL et l'interconnexion. Le code ci-dessous montre les déclarations de signal dans le module supérieur et les affectations de signal simultanées.

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;

Tout d'abord, nous déclarons un signal de réinitialisation qui sera notre version synchrone non inversée de la réinitialisation externe.

Le deuxième signal déclaré, nommé cnt , est le compteur de cycles d'horloge à enroulement infini. C'est un type non signé qui maintiendra l'état de notre onde en dents de scie d'intensité LED à tout moment.

Vient ensuite le pwm_out signal. Nous aurions pu connecter le pwm_out signal du module PWM directement au led_5 sortie, mais je voulais observer pwm_out dans le simulateur. L'outil de synthèse déterminera que les deux signaux appartiennent au même réseau. Cela ne coûtera pas de ressources supplémentaires.

Vient enfin la déclaration du duty_cycle vecteur—cette fois, j'ai utilisé l'alias mot-clé au lieu de créer un nouveau signal. Les alias VHDL fonctionnent un peu comme des macros en C. Lorsque nous utilisons le duty_cycle nom à partir de maintenant, le compilateur le substituera aux bits de poids fort du cnt vecteur.

Après le début mot-clé, nous attribuons le pwm_out signal au led_5 production. Toutes les autres LED sont câblées à '0' pour les empêcher d'allumer une lumière de couleur rouge.

Instanciations

Avant d'utiliser des signaux externes à l'intérieur du FPGA, nous devons toujours les synchroniser avec l'horloge système interne. Sinon, nous pourrions rencontrer des problèmes de métastabilité, des problèmes difficiles à déboguer.

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

La réinitialisation externe ne fait pas exception, mais comme je n'autorise aucune logique RTL dans le module structurel de niveau supérieur, nous implémentons le synchroniseur de réinitialisation en tant que module autonome.

La prochaine instanciation est le module PWM, comme indiqué dans l'extrait de code ci-dessous. Dans l'instanciation du module PWM, nous utilisons le duty_cycle alias pour attribuer les bits les plus significatifs du cnt vecteur au duty_cycle saisir. Cela augmentera la luminosité de la LED jusqu'à ce que le compteur atteigne sa valeur maximale. Quand cnt revient à zéro, la LED s'éteint brièvement et le cycle se répète.

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

La troisième et dernière instanciation dans le module supérieur est le compteur de cycle d'horloge, comme illustré ci-dessous. Pour rendre ce module plus générique, j'ai inclus un count_enable signal. Mais dans cette conception, nous allons le définir sur un "1" constant car nous voulons compter chaque cycle d'horloge.

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

Laissez votre adresse e-mail dans le formulaire ci-dessous si vous avez besoin du code VHDL complet pour ce projet.

Simulation de la pulsation de la LED PWM

Un avantage important de rendre les longueurs de compteur personnalisables grâce aux génériques est que cela vous permet d'accélérer la simulation. La plupart du temps, nous sommes intéressés à tester les transitions et les événements dans notre logique. Nous ne sommes pas si enthousiastes à l'idée de parcourir un compteur ultra-long alors que rien d'autre ne se passe dans la conception.

Avec les génériques, nous pouvons changer ces choses de manière non invasive depuis le banc d'essai. Le code ci-dessous montre les valeurs que j'ai attribuées à la carte générique lors de l'instanciation du module PWM dans le testbench.

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

Lorsque nous simulons l'utilisation de ces constantes dans ModelSim, il suffit de fonctionner pendant 1400 microsecondes à 100 MHz pour révéler deux cycles PWM complets. Si nous avions utilisé les valeurs réelles, nous aurions dû simuler près de 6 secondes. C'est 32 millions de cycles d'horloge de presque rien que de compter. Cela prendrait une éternité dans ModelSim.

L'image ci-dessous montre la forme d'onde de la simulation PWM dans ModelSim. J'ai changé le format du duty_cycle signal du type de numéro par défaut à une présentation d'onde analogique. Vous pouvez le faire dans ModelSim en faisant un clic droit sur le signal dans la forme d'onde et en sélectionnant Format->Analogique (personnalisé)… , et définissez la hauteur des pixels et la plage de données pour qu'elles correspondent aux valeurs min et max de votre signal.

Dans la forme d'onde, nous pouvons voir pourquoi on l'appelle un signal en dents de scie. Le compteur d'emballage à course libre ressemble aux dents d'une lame de scie.

Remarquez comment la durée des périodes hautes de la sortie PWM (led_5 ) augmente à mesure que le rapport cyclique augmente. Nous pouvons également voir que led_5 est un « 1 » continu très brièvement à la pointe de la dent de scie. C'est alors que le rapport cyclique est de 255, la valeur maximale.

Si nous n'avons pas ajouté l'instruction if supplémentaire dans le module PWM, celle qui encapsule le pwm_cnt signal de retour à zéro à sa deuxième valeur la plus élevée, nous ne verrions pas cela. Nous ne serions jamais en mesure d'atteindre la puissance de sortie maximale. C'est une erreur courante lors de la mise en œuvre de générateurs PWM. Je l'ai fait aussi une ou deux fois.

La mise en œuvre du FPGA

J'ai implémenté la conception sur le Lattice iCEstick en utilisant iCEcube2, le logiciel de conception de Lattice. La liste ci-dessous montre l'utilisation des ressources signalée après le lieu et l'itinéraire. Même si le FPGA iCE40 est minuscule, le PWM et les modules de support n'utilisent que 5 % des LUT disponibles.

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

Après avoir généré le bitstream de programmation dans iCEcube2, j'ai utilisé le programmeur autonome Lattice Diamond pour configurer le FPGA sur USB.

L'animation Gif ci-dessous montre comment le signal de rapport cyclique d'onde en dents de scie fait se comporter la LED de mise sous tension sur l'iCEstick. Il s'illumine avec une intensité croissante jusqu'au cnt contre-enveloppements. Ensuite, le rapport cyclique devient entièrement nul et la LED s'éteint brièvement. Après cela, le cycle se répète indéfiniment.

L'iCEstick est une carte de développement FPGA peu coûteuse et polyvalente. C'est bon pour les débutants, mais il convient également aux projets embarqués avancés. De plus, le logiciel Lattice est simple et facile à utiliser. C'est pourquoi j'utilise l'iCEstick à la fois dans mon cours VHDL pour débutant et dans le cours avancé sur FPGA.

Si vous possédez déjà un iCEstick, vous pouvez utiliser le formulaire ci-dessous pour télécharger le projet iCEcube2.

Cycle de service d'onde sinusoïdale pour l'effet de respiration LED

Vous savez maintenant comment contrôler l'éclairage d'une LED à l'aide de PWM.

La LED pulsant dans un motif d'onde en dents de scie est sans doute plus froide qu'une simple application clignotante ON/OFF. C'est une première tâche typique pour les étudiants VHDL, et je suis sûr que vous avez fait clignoter une LED à un moment donné.

Cependant, le clignotement des LED devient encore plus impressionnant si vous utilisez une onde sinusoïdale pour contrôler le rapport cyclique. L'animation Gif ci-dessous montre notre module PWM pulsant la LED avec une variation d'intensité sinusoïdale dans le temps.

Je suis sûr que vous avez déjà vu ce genre d'effet de "respiration" sur les LED. C'est ainsi que se comporte la LED de notification sur mon téléphone portable, et je pense que cela semble naturel car il n'y a pas de changements brusques d'intensité lumineuse.

Dans mon prochain article de blog, je vous montrerai comment créer un générateur d'onde sinusoïdale en utilisant de la RAM en bloc dans les FPGA. Et nous allons modifier le pwm_led module pour pulser la LED sur l'iCEstick avec une intensité d'onde sinusoïdale.

Cliquez ici pour accéder au prochain article de blog :
Comment créer un effet LED respirant à l'aide d'une onde sinusoïdale stockée dans le bloc RAM

Voir aussi :
Contrôleur d'asservissement RC utilisant PWM à partir d'une broche FPGA


VHDL

  1. Contrôleur d'alimentation PWM
  2. Comment créer une liste de chaînes en VHDL
  3. Comment créer un banc d'essai piloté par Tcl pour un module de verrouillage de code VHDL
  4. Comment arrêter la simulation dans un testbench VHDL
  5. Comment générer des nombres aléatoires en VHDL
  6. Comment créer un tampon circulaire FIFO en VHDL
  7. Comment créer un banc d'essai d'auto-vérification
  8. Comment créer une liste chaînée en VHDL
  9. Comment charger un condensateur ?