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)
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...
RH schrieb: > Die ganze Funktion hab ich der Übersicht zuliebe nicht ausgeschrieben... Wäre vielleicht besser gewesen. So wissen wir nicht, ob Du HAL_DMA_Start_IT(&DmaHandle, benutzt hast.
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... }
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?
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)
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 */ }
Und das wird auch mit C und nicht C++ kompiliert? Bei C++ gibt es noch die name mangling Falle wenn das extern C vergessen wurde.
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.
:
Bearbeitet durch User
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...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.