STM32 DMA Transfer Complete Interrupt

Gast #6113947
Halli zusammen,
ich habe folgendes Problem:

Über einen ADC schreibe ich die Werte mehrerer Channel in den Puffer 
einer DMA mit bekannter Größe. Sobald diese fertig ist möchte ich die 
Daten schnellmöglich berarbeiten. Daher möchte ich mit:

HAL_DMA_RegisterCallback(&DmaHandle, HAL_DMA_XFER_CPLT_CB_ID, 
TransferComplete);

eine Funktion bestimmen, die beim Transfer Complete Interrupt auslöst.

Wenn ich das so mache wird meine Funktion allerdings nicht aufgerufen. 
IRQ des DMA ist aktiviert...
Hier der Code:

//Init der DMA:
static void MX_DMA_Init(void)
{

  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA2_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);

}

//in der main Funtkion dann:
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */


  /* MCU 
Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the 
Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_ETH_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  MX_TIM9_Init();
  /* USER CODE BEGIN 2 */
  HAL_DMA_RegisterCallback(&hdma_adc1, HAL_DMA_XFER_CPLT_CB_ID, 
DMA_ISR);

... usw.

Weiß jemand worauf dabei zu achten ist? Ich kann nicht sehen was ich im 
Vergleich zum Beispiel von ST anders mache (DMA_Flash2RAM Beispiel eines 
beliebigen STMF4)
Gast
fgd schrieb:
> wo ist die passende ISR dazu ?

Die ISR-Funktion ist wie im Beispiel in der main.c

static void DMA_ISR(DMA_HandleTypeDef *hdma_adc1){

  addCurrentValues();
  toggle++;

}

Die ganze Funktion hab ich der Übersicht zuliebe nicht ausgeschrieben...
Gast
Johnny B. schrieb:
> Wenn du die HAL verwendest, dann musst Du nur noch folgenden Handler
> hinzufügen, der dann nach erfolgtem DMA-transfer aufgerufen wird:
>
> void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
> {
>  // Dein Code...
> }

Aber das wäre dann ja nach conversion der Daten und nicht nach dem 
Transfer der DMA oder irre ich mich da?
Gast
RH schrieb:
> fgd schrieb:
>> wo ist die passende ISR dazu ?
>
> Die ISR-Funktion ist wie im Beispiel in der main.c
>
> static void DMA_ISR(DMA_HandleTypeDef *hdma_adc1){
>
>   addCurrentValues();
>   toggle++;
>
> }
>
> Die ganze Funktion hab ich der Übersicht zuliebe nicht ausgeschrieben...

da sollte eigentlich sowas drinstehen:

void DMA2_Stream0_IRQHandler(void)
{
    HAL_DMA_IRQHandler(&DmaHandle);
}

wenn alles initialisiert wurde irgendwo sowas:

HAL_DMA_StartIT(&DmaHandle)
Gast
Johnny B. schrieb:
> RH schrieb:
>> Weiß jemand worauf dabei zu achten ist?
>
> Wenn du die HAL verwendest, dann musst Du nur noch folgenden Handler
> hinzufügen, der dann nach erfolgtem DMA-transfer aufgerufen wird:
>
> void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
> {
>  // Dein Code...
> }

normalerweise ja...
Da er aber den DMA auf seine callbacks umbiegt

RH schrieb:
> HAL_DMA_RegisterCallback(&hdma_adc1, HAL_DMA_XFER_CPLT_CB_ID,
> DMA_ISR);
landen die Daten in der funktion DMA_ISR()


Wenn er jedoch die standard ADC funktionen der HAL inkl DMA nutzt...
Dann wäre es aber auch

HAL_ADC_Start_DMA(..)

Dann wären die standardcallbacks

__weak void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hadc);
  /* NOTE : This function Should not be modified, when the callback is 
needed,
            the HAL_ADC_ConvCpltCallback could be implemented in the 
user file
   */
}

__weak void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hadc);
  /* NOTE : This function Should not be modified, when the callback is 
needed,
            the HAL_ADC_ConvHalfCpltCallback could be implemented in the 
user file
   */
}

__weak void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hadc);
  /* NOTE : This function Should not be modified, when the callback is 
needed,
            the HAL_ADC_ErrorCallback could be implemented in the user 
file
   */
}
fgd schrieb:
> Da er aber den DMA auf seine callbacks umbiegt

Ja so ist es. Leider wurde bereits alles "verbastelt".

Also ich würde mit CubeMX nochmals ein frisches Projekt erstellen und 
den ADC und DMA in CubeMX definieren.

Dann brauchts eigentlich nur noch
1
HAL_ADC_Start_DMA(&DmaHandle, ...

Und dieses hinzuzufügen:
1
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
2
{
3
 // Dein Code...
4
}

Den Rest macht die HAL.
Gast
Johnny B. schrieb:
> Ja so ist es. Leider wurde bereits alles "verbastelt".
>
> Also ich würde mit CubeMX nochmals ein frisches Projekt erstellen und
> den ADC und DMA in CubeMX definieren.
>
> Dann brauchts eigentlich nur noch
> HAL_ADC_Start_DMA(&DmaHandle, ...
>
> Und dieses hinzuzufügen:
> void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle)
> {
>  // Dein Code...
> }
>
> Den Rest macht die HAL.

Alles klar, ich setze vielleicht nochmal das Projekt neu auf.

Ich hatte vorhin aber mal den 
HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* AdcHandle) Callback in 
meiner Main implementiert. Dieser wird auch aufgerufen allerdings glaube 
ich, dass er direkt nach der fertigen Conversion des ADC auslöst, also 
da wo auch erst die DMA anängt zu arbeiten. Getestet habe ich das indem 
ich eine einzlne ADC-Wandlung gestartet habe und im Anschluss im 
HAL_ADC_ConvCpltCallback() die Werte aus dem DMA-Array in zwei Variablen 
geschrieben habe. DIe Variablen blieben = 0 also muss der Interrupt ja 
ausgelöst worden sein bevor der DMA-Transfer fertig war...

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 6 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.