solution limitée sans DMA
STM32F4 les contrôleurs ont 12 minuteurs avec jusqu'à 4 canaux PWM chacun, 32 au total. Certains d'entre eux peuvent être synchronisés pour commencer ensemble, par ex. vous pouvez avoir TIM1
en commençant TIM2
, TIM3
, TIM4
et TIM8
simultanément. C'est 20 sorties PWM synchronisées. Si ce n'est pas assez, vous pouvez former des chaînes où un timer esclave est un master pour un autre, mais il serait assez difficile de les garder parfaitement synchronisés. Pas si difficile, si un décalage de quelques cycles d'horloge est acceptable.
Il existe plusieurs exemples dans la section des exemples de projets de la bibliothèque STM32CubeF4, à partir desquels vous pouvez assembler votre configuration, voir Projects/*_EVAL/Examples/TIM/*Synchro*
.
solution générale
Un but général ou une minuterie avancée (c'est tous sauf TIM6
et TIM7
) peuvent déclencher un transfert DMA lorsque le compteur atteint la valeur de rechargement (événement de mise à jour) et lorsque le le compteur est égal à l'une des valeurs de comparaison (capture/compare event). L'idée est de laisser DMA écrire le modèle binaire souhaité sur la moitié basse (ensemble) de BSRR
sur un événement de comparaison et les mêmes bits sur la moitié haute (réinitialisation) de BSRR
sur un événement de mise à jour.
Il existe cependant un problème: DMA1
ne peut absolument pas accéder au bus AHB (voir Fig. 1 ou 2 du Manuel de référence) auquel les registres GPIO sont connectés. Par conséquent, nous devons utiliser DMA2
, et cela nous laisse avec les minuteurs avancés TIM1
ou TIM8
. Les choses sont encore plus compliquées parce que les requêtes DMA provoquées par la mise à jour et la comparaison des événements de ces temporisateurs aboutissent sur différents flux DMA (voir Tableau 43 dans la RM). Pour le rendre un peu plus simple, nous pouvons utiliser DMA 2, Stream 6 ou Stream 2, Channel 0, qui combinent les événements de 3 canaux de minuterie. Au lieu d'utiliser l'événement de mise à jour, nous pouvons définir le registre de comparaison sur un canal de minuterie à 0.
Mettre en place le flux DMA de la minuterie sélectionnée pour
- canal 0
- transfert unique (pas burst)
- taille mémoire de données 16 bits
- taille de données périphérique 16 bits
- aucun incrément de mémoire
- incrément adresse périphérique
- en mode circulaire
- mémoire périphérique
- régulateur de débit périphérique: Je ne sais pas, expérience
- nombre d'éléments de données 2
- adresse périphérique
GPIOx->BSRR
- points d'adresse mémoire vers le modèle de bit de sortie
- mode direct
- enfin, activer le canal.
Maintenant, régler la minuterie
- définir le prédiviseur et générer un événement de mise à jour si nécessaire
- définir la valeur de recharge automatique pour atteindre la fréquence requise
- ensemble la valeur de comparaison du canal 1 à 0
- définir la valeur de comparaison du canal 2 au cycle de service requis
- activer la demande DMA pour les deux canaux
- permettent de comparer sur les deux canaux
- activer le compteur
De cette façon, on peut contrôler 16 broches avec chaque minuterie, 32 si l'on utilise tous les deux en mode maître-esclave. Pour contrôler encore plus de broches (jusqu'à 64) à la fois, configurez les flux DMA supplémentaires pour les événements de comparaison et de mise à jour de canal 4, définissez le nombre d'éléments de données sur 1 et utilisez ((uint32_t)&GPIOx->BSRR)+2
comme adresse de périphérique pour la mise à jour courant.
Les canaux 2 et 4 peuvent être utilisés comme sorties PWM régulières, ce qui vous donne 4 broches supplémentaires. Peut-être que Channel 3 aussi.
Vous pouvez toujours utiliser TIM2
, TIM3
, TIM4
et TIM5
(chacun peut être asservi à TIM1
ou TIM8
) pour 16 autres sorties PWM comme décrit dans la première partie de mon poste. Peut-être TIM9
et TIM12
aussi, pour 4 de plus, si vous pouvez trouver une configuration maître-esclave appropriée.
C'est 90 broches basculant à la fois. Attention aux limites de courant total.
qu'est-ce que 10kHz plus tard? Hz n'est pas l'unité de temps. DMA ne peut pas effectuer d'opérations logiques. Il ne fait que transférer les données de l'emplacement A vers l'adresse B. –
Ok ... 100us plus tard, je veux appliquer le même pwm 200khz aux différentes broches du GPIO. Ainsi, nous transférons la variable contenant le masque vers le GPIOx-> BSRR ou avec DMA sur le front montant du PWM, puis sur le front descendant, nous remettons le GPIO à zéro ... 100us layer, un timer différent déborde ou compare ou quelque chose, et puis le seul changement qui conduit est que maintenant nous chargeons le DMA avec une valeur différente sur le front montant – testname123
Je vous ai déjà donné la réponse. Mon exemple était pour 1 bit. ça peut être 16 aussi. Sinon, utilisez le minuteur généré PWM –