We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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