Hello,
Currently I completed a Rs232 programm with Keil uVision5 and the V5.06 Compiler.
It all works pretty well but today i switched to the Compiler V6.14 and after that, I got only a "00" as answer in hterm instead of the right frame.
The correct frame is in the array and also the pointers are right.
The answer is transmitted by DMA1 Stream1.
Receiving a frame with Interrupt still works perfect, only transmitting with DMA and without DMA doesn't work after changing the Compiler.
I hope you can help me
#include "stm32h7xx_ll_gpio.h" #include "stm32h7xx_ll_usart.h" #include "stm32h7xx_ll_dma.h" #include "stm32h7xx_ll_tim.h" #include "AllgemeineFunktionen.h" #include "Rs232Kommunikation.h" #include "ModbusRtu.h" #include <string.h> Rs232 oRs232; Rs232::Rs232() { } void Rs232::init(UINT32 ui32Baudrate) { LL_TIM_InitTypeDef sTimInitStruktur; LL_GPIO_InitTypeDef sGpioInitStruktur; LL_USART_InitTypeDef sUSART_InitStruct; LL_DMA_InitTypeDef DMA_InitStruct; //------------------------------ // Timer initialisieren //------------------------------ LL_TIM_StructInit(&sTimInitStruktur); sTimInitStruktur.Autoreload = 15000; //Interrupt alle 0.25ms sTimInitStruktur.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; sTimInitStruktur.CounterMode = LL_TIM_COUNTERMODE_UP; sTimInitStruktur.Prescaler = 1; sTimInitStruktur.RepetitionCounter = 15000; LL_TIM_Init(TIM12, &sTimInitStruktur); //------------------------------ // GPIO initialisieren //------------------------------ sGpioInitStruktur.Pin = LL_GPIO_PIN_10 | LL_GPIO_PIN_11; sGpioInitStruktur.Pull = LL_GPIO_PULL_NO; sGpioInitStruktur.Speed = LL_GPIO_SPEED_HIGH; sGpioInitStruktur.Alternate = LL_GPIO_AF_7; sGpioInitStruktur.Mode = LL_GPIO_MODE_ALTERNATE; LL_GPIO_Init(GPIOB, &sGpioInitStruktur); //------------------------------ // USART initialisieren //------------------------------ LL_USART_StructInit(&sUSART_InitStruct); sUSART_InitStruct.BaudRate = ui32Baudrate; sUSART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B; sUSART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; sUSART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; sUSART_InitStruct.Parity = LL_USART_PARITY_NONE; sUSART_InitStruct.PrescalerValue = LL_USART_PRESCALER_DIV1; sUSART_InitStruct.StopBits = LL_USART_STOPBITS_1; sUSART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX; LL_USART_Init(USART3, &sUSART_InitStruct); //------------------------------ // DMA initialisieren //------------------------------ LL_DMA_StructInit(&DMA_InitStruct); DMA_InitStruct.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; DMA_InitStruct.FIFOMode = LL_DMA_FIFOMODE_DISABLE; DMA_InitStruct.FIFOThreshold = LL_DMA_FIFOTHRESHOLD_FULL; DMA_InitStruct.MemBurst = LL_DMA_MBURST_SINGLE; DMA_InitStruct.MemoryOrM2MDstAddress = (UINT32)&aui8Antwort_senden[0]; DMA_InitStruct.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE; DMA_InitStruct.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; DMA_InitStruct.Mode = LL_DMA_MODE_NORMAL; DMA_InitStruct.NbData = 5; DMA_InitStruct.PeriphBurst = LL_DMA_PBURST_SINGLE; DMA_InitStruct.PeriphOrM2MSrcAddress = (UINT32)&USART3->TDR; DMA_InitStruct.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE; DMA_InitStruct.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; DMA_InitStruct.PeriphRequest = LL_DMAMUX1_REQ_USART3_TX; DMA_InitStruct.Priority = LL_DMA_PRIORITY_HIGH; LL_DMA_Init(DMA1, LL_DMA_STREAM_1, &DMA_InitStruct); LL_DMA_EnableBufferableTransfer(DMA1, LL_DMA_STREAM_1); // DMA_InitStruct.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY; // DMA_InitStruct.FIFOMode = LL_DMA_FIFOMODE_DISABLE; // DMA_InitStruct.FIFOThreshold = LL_DMA_FIFOTHRESHOLD_FULL; // DMA_InitStruct.MemBurst = LL_DMA_MBURST_SINGLE; // DMA_InitStruct.MemoryOrM2MDstAddress = (UINT32)&aui8Test; // DMA_InitStruct.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE; // DMA_InitStruct.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; // DMA_InitStruct.Mode = LL_DMA_MODE_CIRCULAR; // DMA_InitStruct.NbData = DF_DMA_EMPFANGENE_DATEN; // DMA_InitStruct.PeriphBurst = LL_DMA_PBURST_SINGLE; // DMA_InitStruct.PeriphOrM2MSrcAddress = (UINT32)&USART3->RDR; // DMA_InitStruct.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE; // DMA_InitStruct.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; // DMA_InitStruct.PeriphRequest = LL_DMAMUX1_REQ_USART3_RX; // DMA_InitStruct.Priority = LL_DMA_PRIORITY_HIGH; // LL_DMA_Init(DMA1, LL_DMA_STREAM_2, &DMA_InitStruct); // LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_2); //------------------------------ // USART DMA aktivieren //------------------------------ LL_USART_Enable(USART3); LL_USART_EnableDMAReq_TX(USART3); //LL_USART_EnableDMAReq_RX(USART3); LL_USART_EnableDirectionTx(USART3); //------------------------------ // Interrupts aktivieren //------------------------------ LL_USART_EnableIT_RXNE_RXFNE(USART3); NVIC_EnableIRQ(USART3_IRQn); LL_TIM_ClearFlag_UPDATE(TIM12); LL_TIM_EnableIT_UPDATE(TIM12); NVIC_EnableIRQ(TIM8_BRK_TIM12_IRQn); //------------------------------ // Buffer Pointer setzten //------------------------------ pui8BufferRx_schreiben = &aui8Buffer_Rx[0]; pui8BufferRx_lesen = &aui8Buffer_Rx[0]; pui8BufferTx_schreiben = &aui8Buffer_Tx[0]; pui8BufferTx_lesen = &aui8Buffer_Tx[0]; //------------------------------ // Timer setzten //------------------------------ LL_TIM_EnableCounter(TIM12); Zeitueberwachung3_5_setzen(true); } void Rs232::daten_empfangen(void) //mit jedem Interrupt werden Empfangene Daten in das Feld Buffer_Rx geschrieben und die Zähler auf 0 gesetzt { LL_TIM_SetCounter(TIM12, 0x0000); ui8Timer1_5Z = 0; ui8Timer3_5Z = 0; *pui8BufferRx_schreiben = LL_USART_ReceiveData8(USART3); pui8BufferRx_schreiben_hochzaehlen(); ui8BufferRxFuellstand++; } void Rs232::daten_senden(UINT8 laenge) //Daten über DMA senden { LL_USART_TransmitData8(USART3, 'A'); LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_1, laenge); LL_DMA_ClearFlag_TC1(DMA1); LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_1); Zeitueberwachung3_5_setzen(false); LL_TIM_SetCounter(TIM12, 0x0000); //Pausentimer starten ui8Timer3_5Z = 0; } void Rs232::pui8BufferRx_schreiben_hochzaehlen() //Pointer BufferRx_schreiben erhöhen { if(pui8BufferRx_schreiben >= &aui8Buffer_Rx[Rx_BUFFER_GROESSE-1]) { pui8BufferRx_schreiben = &aui8Buffer_Rx[0]; } else { pui8BufferRx_schreiben++; } } void Rs232::pui8BufferRx_lesen_hochzaehlen() //Pointer BufferRx_lesen erhöhen { if(pui8BufferRx_lesen >= &aui8Buffer_Rx[Rx_BUFFER_GROESSE-1]) { pui8BufferRx_lesen = &aui8Buffer_Rx[0]; } else { pui8BufferRx_lesen++; } } //void Rs232::pui8BufferRx_schreiben_runterzaehlen() //Pointer BufferRx_schreiben runterzählen //{ // if(pui8BufferRx_schreiben <= &aui8Buffer_Rx[0]) // { // pui8BufferRx_schreiben = &aui8Buffer_Rx[20]; // } // else // { // pui8BufferRx_schreiben--; // } // //} void Rs232::pui8BufferTx_schreiben_hochzaehlen(bool Fehlerstatus) //Pointer BufferTx_schreiben erhöhen { if(pui8BufferTx_schreiben >= &aui8Buffer_Tx[Tx_BUFFER_GROESSE-1]) { pui8BufferTx_schreiben = &aui8Buffer_Tx[0]; } else { pui8BufferTx_schreiben++; } } void Rs232::pui8BufferTx_lesen_hochzaehlen() //Pointer BufferTx_lesen erhöhen { if(pui8BufferTx_lesen >= &aui8Buffer_Tx[Tx_BUFFER_GROESSE-1]) { pui8BufferTx_lesen = &aui8Buffer_Tx[0]; } else { pui8BufferTx_lesen++; } } void Rs232::daten_zum_senden_ueberpruefen(UINT8 Datenmenge) //Antwort in BufferTx schreiben { UINT8 Paketlaenge; Paketlaenge = Datenmenge; for(UINT8 i=0; i<20; i++) { aui8Antwort_senden[i]=0; } if(boZeitueberwachung1_5 == false) { for(UINT8 i=0; i<Paketlaenge; i++) { aui8Antwort_senden[i] = *pui8BufferTx_lesen; pui8BufferTx_lesen_hochzaehlen(); } daten_senden(Paketlaenge); } else { Zeitueberwachung1_5_setzen(false); } } void Rs232::Fehlercode_zum_senden_ueberpruefen() //Antwort Fehlercode in BufferTx schreiben { aui8Antwort_senden[0] = *pui8BufferTx_lesen; pui8BufferTx_lesen_hochzaehlen(); aui8Antwort_senden[1] = *pui8BufferTx_lesen; pui8BufferTx_lesen_hochzaehlen(); daten_senden(2); } UINT8 Rs232::BufferRxFuellstand_uebergeben() { return ui8BufferRxFuellstand; } void Rs232::BufferRxFuellstand_leeren(UINT8 Menge) { ui8BufferRxFuellstand -= Menge; } bool Rs232::Zeitueberwachung1_5_abfragen() { return boZeitueberwachung1_5; } void Rs232::Zeitueberwachung1_5_setzen(bool Wert) { boZeitueberwachung1_5 = Wert; } bool Rs232::Zeitueberwachung3_5_abfragen() { return boZeitueberwachung3_5; } void Rs232::Zeitueberwachung3_5_setzen(bool Wert) { boZeitueberwachung3_5 = Wert; } void USART3_IRQHandler (void) //Interrupt Handler USART3 { oRs232.daten_empfangen(); } void TIM8_BRK_TIM12_IRQHandler (void) //Interrupt Handler Timer 12 { if (LL_TIM_IsActiveFlag_UPDATE(TIM12) == SET) { //LL_GPIO_TogglePin(GPIOI, LL_GPIO_PIN_9); //Test um Frequenz zu messen an Fehler LED oRs232.ui8TimerTest++; oRs232.ui8Timer3_5Z++; oRs232.ui8Timer1_5Z++; if(oRs232.ui8Timer1_5Z >= 3) { oRs232.Zeitueberwachung1_5_setzen(true); } if(oRs232.ui8Timer3_5Z >= 7) { oRs232.Zeitueberwachung3_5_setzen(true); } LL_TIM_ClearFlag_UPDATE(TIM12); } }
Andi