2017-06-14 8 views
2

J'utilise une carte de découverte stm32f3 et la HAL de CubeMX. J'essaie d'utiliser 2 canaux ADC à ADC4. J'ai configuré DMA en mode circulaire. Befor la boucle principale principale, je l'appelle:Que manque-t-il pour que stm32 ADC DMA fonctionne? La concurrence de transfert ne se produit pas

HAL_ADC_Start_DMA(&hadc4, DMA_adc4_buffer, 16); 

I mis en œuvre les fonctions HAL_ADC_ConvHalfCpltCallback et HAL_ADC_ConvCpltCallback. Maintenant, la partie étrange: HAL_ADC_ConvHalfCpltCallback est appelée régulièrement, HAL_ADC_ConvCpltCallback n'est pas.

Il me dit, que l'ADC avec le transfert DMA fonctionne bien. Mais pourquoi le transfert n'est-il pas appelé? Si je démarre l'ADC avec HAL_ADC_Start_IT la fonction d'interruption est appelée, mais ce n'est pas ce que je veux. L'insertion de points d'arrêt dans HAL_DMA_IRQHandler dans la ST HAL indique également que le rappel n'est jamais appelé.

Pour être complet ici parties de la fonction ADC4_Init:

/**Common config 
*/ 
hadc4.Instance = ADC4; 
hadc4.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; 
hadc4.Init.Resolution = ADC_RESOLUTION_12B; 
hadc4.Init.ScanConvMode = ADC_SCAN_ENABLE; 
hadc4.Init.ContinuousConvMode = ENABLE; 
hadc4.Init.DiscontinuousConvMode = DISABLE; 
hadc4.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; 
hadc4.Init.ExternalTrigConv = ADC_SOFTWARE_START; 
hadc4.Init.DataAlign = ADC_DATAALIGN_RIGHT; 
hadc4.Init.NbrOfConversion = 2; 
hadc4.Init.DMAContinuousRequests = ENABLE; 
hadc4.Init.EOCSelection = ADC_EOC_SEQ_CONV; 
hadc4.Init.LowPowerAutoWait = DISABLE; 
hadc4.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; 

Merci à vos idées pour.

+0

Aucune configuration de canal et aucune configuration DMA, donc comment vous pensez que cela va fonctionner. –

Répondre

1

Le problème était que l'horloge de l'ADC était de 48 MHz, l'horloge de base seulement 12 MHz. Les contrôles de HAL_DMA_IRQHandler fonction FRST pour le drapeau d'interruption pour moitié transfert complet, puis pour un transfert complet dans le style

if (half transfer complete){ 
    HAL_ADC_ConvHalfCpltCallback(); 
} **ELSE** if (transfer complete){ 
    HAL_ADC_ConvCpltCallback(); 
} 

Depuis indicateur d'interruption moitié de transfert est toujours réglé de façon rapide par le CAN/DMA et le processeur est si lent, le noyau ne vient jamais à la branche ìf et n'appelle donc jamais le ConvCpltCallback().