J'ai activé le transfert de périphérique DMA vers la mémoire pour ADC1 dans CubeMX et généré le code. Cependant, je ne sais pas où les données de l'ADC seront écrites? Dois-je définir explicitement une variable pour contenir ces données? Comment puis-je récupérer les données dans le DMA Channel 1 ISR?
4 Réponses :
DMA et uC ne savent rien des variables. Le périphérique DMA possède deux registres de configuration dans lesquels vous stockez l'adresse du périphérique et l'adresse mémoire. Si vous commencez par lire la documentation uC au lieu de HAL, tout sera clair instantanément
Si vous jetez un œil aux documents et exemples HAL, vous trouverez un exemple d'utilisation de l'ADC avec DMA.
En bref:
Pour démarrer la conversion, vous utilisez la fonction: p>
HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);
Où pData est votre variable / tableau où le DMA doit placer les données.
Le DMA ne gère pas la mémoire et ne choisit pas d'adresse valide pour définir les données. De manière générale, le DMA permet les transferts de données sans utiliser le processeur, mais pas plus.
Les microcontrôleurs STM32 assurent les transferts depuis:
Dans chacun d'eux, les développeurs doivent être conscients de leur objectif afin de configurer (en plus de DMA) les lieux source et de destination, tels que l'adresse des périphériques, la mémoire de réserve (et quel type de mémoire), etc. .
Dans votre cas particulier (consultez RM , AN , docs , etc.), les principaux acteurs d'un ADC vers la mémoire (périphérique vers mémoire) les transferts sont:
Bien que faire DMA à une adresse sur la pile ne soit pas fondamentalement impossible à obtenir correctement, le faire n'importe où en dessous, disons main (), est une idée potentiellement mauvaise, car vous devez vous assurer que le code ne retourne pas invalider ce cadre de pile avant le DMA est terminé.
Bien que je sois d'accord sur le commentaire de Lundin concernant la volatilité, je ne suis pas d'accord avec celui-ci lorsqu'il y a des restrictions ou des ressources limitées. Réserver un tas de RAM uniquement pour DMA n'est pas toujours possible, alors qu'il est vrai que ce doit être la première option.
Vous indiquez au pilote HAL DMA ADC où placer les exemples de données lorsque vous démarrez la conversion:
volatile uint32_t adcBuffer[SAMPLE_COUNT]; HAL_ADC_Start_DMA( &hadc, adcBuffer, SAMPLE_COUNT );
Notez que certaines parties STM32 ont une SRAM divisée sur plusieurs bus avec une section beaucoup plus petite que d'autres. La réservation de cette section pour les tampons DMA présente des avantages en termes de performances, car elle réduit les conflits de bus avec les extractions de données logicielles normales. Vous pouvez donc personnaliser votre script de création de liens pour créer des sections et placer explicitement des tampons DMA dans un tout en excluant le placement des données d'application.
Pour configurer le DMA, vous devez lui donner l'adresse et la taille effective (en terme de taille et de nombre de mots) d'une mémoire tampon, espérons-le à un endroit valide dans la RAM. Les données y atterriront. Vous seul avez le code, donc vous seul savez où il se trouve.
Le
DMA
signifie adresse mémoire directe. Cela signifie que l'ADC écrira directement dans l'adresse mémoire que vous lui donnez. Donc d'aborduint16_t adcvalues [10];
, puis configurez DMA pour écrire 10 valeurs dans le pointeuradcvalues
, attendez la fin, puis vous lisez les valeurs uniquement à partir deadcvalues code>.
Remarque: les tampons DMA doivent toujours être déclarés comme
volatils
, ou vous pouvez obtenir toutes sortes de bogues d'optimisation étranges. Vous devez également envisager une réintroduction entre le matériel DMA et votre application.