This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

STM32h7: USART doesn't work anymore after switching from compiler V5.06 to V6.14

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