Conduire la fréquence de sortie PWM

8

Après de nombreuses heures de recherche et de lecture infructueuses, je ne comprenais toujours pas comment et pourquoi produire des fréquences spécifiques à partir de la broche PWM matérielle du RPi sans utiliser la `` boîte noire '' de quelqu'un d'autre.

Il semble y avoir beaucoup d'informations inexactes ou incomplètes sur les détails, ainsi que sur les différents termes utilisés - `` diviseur d'horloge '', `` cycle de service '', `` plage PWM '' et les données PWM elles-mêmes, et comment elles sont toutes liées ensemble pour produire une fréquence spécifique - dans mon cas, pour chasser des fréquences audio spécifiques d'un sondeur piézo.

Neil
la source

Réponses:

14

J'ai finalement obtenu une compréhension complète (ish) du fichier d'en-tête du pilote bcm2835.h, alors j'ai pensé publier et répondre à ma propre question pour les autres.

Les bits pertinents de l'en-tête:

PWM

Le BCM2835 prend en charge le PWM matériel sur un sous-ensemble limité de broches GPIO. Cette bibliothèque bcm2835 fournit des fonctions pour configurer et contrôler la sortie PWM sur ces broches.

Le BCM2835 contient 2 canaux PWM indépendants (0 et 1), chacun étant connecté à un sous-ensemble limité de broches GPIO. Les broches GPIO suivantes peuvent être connectées aux canaux PWM suivants:

  GPIO PIN    RPi pin  PWM Channel    ALT FUN
  12                    0             0
  13                    1             0
  18          1-12      0             5
  19                    1             5
  40                    0             0
  41                    1             0
  45                    1             0
  52                    0             1
  53                    1             1

Pour qu'une broche GPIO émette une sortie de son canal PWM, elle doit être réglée sur la fonction Alt indiquée ci-dessus. Notez soigneusement que les versions actuelles du Raspberry Pi exposent uniquement l'une de ces broches (GPIO 18 = RPi Pin 1-12) sur les en-têtes IO, et c'est donc la seule broche IO du RPi qui peut être utilisée pour PWM. De plus, il doit être réglé sur ALT FUN 5 pour obtenir une sortie PWM.

Les deux canaux PWM sont pilotés par la même horloge PWM, dont l'horloge peut être modifiée à l'aide de bcm2835_pwm_set_clock(). Chaque canal peut être activé séparément avec bcm2835_pwm_set_mode(). La sortie moyenne du canal PWM est déterminée par le rapport DONNÉES / PLAGE pour ce canal. Utilisez bcm2835_pwm_set_range()pour définir la plage et bcm2835_pwm_set_data()définir les données dans ce rapport

Chaque canal PWM peut fonctionner en mode symétrique ou Mark-Space. En mode équilibré, le matériel envoie une combinaison d'impulsions d'horloge qui se traduit par une impulsion de données globale par impulsions de plage. En mode Mark-Space, le matériel définit la sortie HIGH pour les impulsions d'horloge DATA large, suivie de LOW pour les impulsions d'horloge RANGE-DATA.

L'horloge PWM peut être réglée pour contrôler les largeurs d'impulsion PWM. L'horloge PWM est dérivée d'une horloge de 19,2 MHz. Vous pouvez définir n'importe quel séparateur, mais certains sont communs fournis par lebcm2835PWMClockDivider

Par exemple, supposons que vous vouliez piloter un moteur à courant continu avec PWM à environ 1 kHz et contrôler la vitesse par incréments de 1/1024 de 0/1024 (arrêté) à 1024/1024 (complètement activé). Dans ce cas, vous pouvez régler le diviseur d'horloge sur 16 et la plage sur 1024. La fréquence de répétition des impulsions sera de 1,2 MHz / 1024 = 1171,875 Hz.

bcm2835PWMClockDividerSpécifie le diviseur utilisé pour générer l'horloge PWM à partir de l'horloge système. Les figures ci-dessous donnent le diviseur, la période d'horloge et la fréquence d'horloge. L'horloge divisée est basée sur une fréquence d'horloge de base PWM nominale de 19,2 MHz. Les fréquences affichées pour chaque diviseur ont été confirmées par mesure

typedef enum
{
    BCM2835_PWM_CLOCK_DIVIDER_2048  = 2048,    /*!< 2048 = 9.375kHz */
    BCM2835_PWM_CLOCK_DIVIDER_1024  = 1024,    /*!< 1024 = 18.75kHz */
    BCM2835_PWM_CLOCK_DIVIDER_512   = 512,     /*!< 512 = 37.5kHz */
    BCM2835_PWM_CLOCK_DIVIDER_256   = 256,     /*!< 256 = 75kHz */
    BCM2835_PWM_CLOCK_DIVIDER_128   = 128,     /*!< 128 = 150kHz */
    BCM2835_PWM_CLOCK_DIVIDER_64    = 64,      /*!< 64 = 300kHz */
    BCM2835_PWM_CLOCK_DIVIDER_32    = 32,      /*!< 32 = 600.0kHz */
    BCM2835_PWM_CLOCK_DIVIDER_16    = 16,      /*!< 16 = 1.2MHz */
    BCM2835_PWM_CLOCK_DIVIDER_8     = 8,       /*!< 8 = 2.4MHz */
    BCM2835_PWM_CLOCK_DIVIDER_4     = 4,       /*!< 4 = 4.8MHz */
    BCM2835_PWM_CLOCK_DIVIDER_2     = 2,       /*!< 2 = 9.6MHz, fastest you can get */
    BCM2835_PWM_CLOCK_DIVIDER_1     = 1        /*!< 1 = 4.6875kHz, same as divider 4096 */
} bcm2835PWMClockDivider;

En résumé:

  1. Si vous voulez du PWM matériel - vous êtes coincé avec la broche 12 (BCM18), les autres broches GPIO utiliseront le logiciel PWM.

  2. Vous devrez probablement régler le mode PWM sur le mode 'Mark-Space' pour la plupart des cas d'utilisation et pour des raisons de raison comme décrit ci-dessus.

  3. Dans ce mode, la durée pendant laquelle chaque «impulsion» est ÉLEVÉE par rapport à BASSE est déterminée par le rapport des données PWM à la plage PWM - ceci indépendamment de la vitesse d'horloge PWM.

  4. La plage PWM est en fait la «résolution» ou le nombre de «divisions» possibles de chaque impulsion. Plus il y a de divisions, plus la résolution est élevée et donc plus d'états codables pour une largeur d'impulsion donnée.

  5. Le «cycle de service» est le rapport des données PWM à la plage PWM exprimé en pourcentage. Une plage PWM de 10 avec des données PWM de 8 est un rapport cyclique de 80%.

  6. La vitesse d'horloge PWM est une puissance de deux diviseurs. Votre vitesse d'horloge choisie pour PWM doit donc être divisor & (divisor -1) == 0Bien que les 12 valeurs valides soient répertoriées ci-dessus.

  7. La division de la fréquence d'horloge PWM par la fréquence de sortie souhaitée donne la valeur de la plage d'impulsions.

  8. Comme j'encodais l'audio et que j'utilisais un sondeur piézo, j'avais besoin d'un rapport cyclique de 50% pour maximiser l'oscillation piézo et donc le volume. La valeur des données PWM est donc toujours la moitié de la valeur de la plage PWM - 50% HIGH 50% LOW.

Pour calculer votre fréquence requise, choisissez un diviseur d'horloge qui a du sens pour votre application - j'ai choisi 16, ce qui équivaut à 1,2 MHz. Donc:

La note de A est 440Hz, F # est 370Hz, C # est 277Hz

PWMClock = 16; // 1.2Mhz

const A4_RANGE = 1.2e6 / 440;  // 1.2Mhz/440Hz
A4Data = A4_RANGE / 2;

const F4S_RANGE = 1.2e6 / 370;  // 1.2Mhz/370Hz
F4SData = F4S_RANGE / 2;

const C4S_RANGE = 1.2e6 / 277;  // 1.2Mhz/277Hz
C4SData = C4S_RANGE / 2;

Vous pouvez facilement décaler la gamme PWM de haut en bas d'octaves par multiples - la plage * 2 la fera descendre d'une octave, la plage * 0,5 la fera monter d'une octave.

Si vous vouliez piloter un servo à 50 Hz par exemple, le même calcul de plage est vrai:

PWM Range = PWM frequency / Desired Output Frequency

(La valeur maximale de la plage PWM selon certains articles est anecdotique de 4096 - selon mon expérience, ce n'est pas vrai car jouer un C # comme ci-dessus donne une plage PWM de 4332 qui fonctionne comme prévu.)

Comme la plupart des choses - c'est facile quand on sait comment.

~ N

Neil
la source
3
Notez que le bit "broche 12 uniquement" s'applique aux modèles à 26 broches. Les modèles à 40 broches en ont trois de plus (13, 18 et 19), mais il n'y a toujours que 2 canaux d'horloge et les broches ont une association câblée avec l'un ou l'autre (les broches 12 et 18 sont le canal 0, 13 et 19 sont le canal 1); selon les documents cités ci-dessus, libbcm2835 vous permettra de configurer les deux canaux et les quatre broches. Les fonctions ALT pour ce faire diffèrent pour chaque broche; il y a un tableau ici dont une grande partie est directement extraite de la fiche technique Broadcom SoC. Les entrées barrées ne concernent que les modèles à 40 broches.
goldilocks
7

Sur les Pis récents (ceux avec l'en-tête d'extension à 40 broches et le module de calcul), GPIO 12/13/18/19 peut être utilisé pour fournir des signaux PWM matériels.

La source d'horloge PWM n'a pas besoin d'être le cristal 19,2 MHz , pigpio utilise le PLLD 500 MHz.

Pour une méthode simple en ligne de commande pour définir une fréquence PWM matérielle, voir http://abyz.me.uk/rpi/pigpio/pigs.html#HP

joan
la source