AnsweredAssumed Answered

How to speed up usart communication?

Question asked by Jakub B on Oct 5, 2017
Latest reply on Oct 6, 2017 by AvaTar

Hi

i have a problem with my project's communication. I'm making board that is communicating with usart with another board. my board is waiting for order from master board and then checks inputs and sends back answer. master is sending order at 9600 8n1 every second.

while all communication works there is a lot of missed orders which results in master doesnt getting answer from my board once in about 15-20 times. I need it to work all the time because its for power management systems (thats why i'll be omiting some data about structure of order and answer and crc check.

I'm using stm32f030c8t6, project built in Cube and Keil

/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f0xx_hal.h"

/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart1_tx;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
 uint8_t Received[8]; // tablica przechowujaca odebrana wiadomosc
 uint8_t adres;  // bierzacy adres modulu WEWY
 uint8_t adresik;
 static uint8_t Data[17];    // Tablica przechowujaca wysylana wiadomosc
 uint8_t we[1];
 uint8_t wy[1];
 uint8_t wejscia1;       // stan wejsc1
 uint8_t wejscia2;       // stan wejsc2
 int i;                              // zmienna pomocnicza
 uint8_t ramka;             // zmienna pomocnicza
 uint8_t bufor[8];      // bufor rozkazu
 unsigned int crcmem; // zmienna pomocnicza w obliczaniu crc
 unsigned int wy_crc; // zmienna pomocnicza w obliczaniu crc ramki wychodzacej
 char wy_crc1;                // zmienna pomocnicza w dodawaniu crc ramki wychodzacej
 char wy_crc2;                // zmienna pomocnicza w dodawaniu crc ramki wychodzacej
 char we_crc1;                // zmienna pomocnicza w sprawdzeniu crc ramki przychodzacej
 char we_crc2;                // zmienna pomocnicza w sprawdzeniu crc ramki przychodzacej
 unsigned int we_crc_spr; // zmienna pomocnicza w sprawdzeniu crc ramki przychodzacej
 
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART1_UART_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
//crc calculating
int CRC2 (int LiczbaBajtow, unsigned char *lbb){
...

...
    return(crcmem);
}
//checking inputs
 void stany(void) {
 wejscia1=0x00;  // zerowanie zmiennej
 wejscia2=0x00;  // zerowanie zmiennej
 uint8_t odpowiedz[15]; // ramka bez crc do wyslania
 if((HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0))==0) {wejscia1=wejscia1+128;};
 if((HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1))==0) {wejscia1=wejscia1+64;};
 if((HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2))==0) {wejscia1=wejscia1+32;};     
 if((HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3))==0) {wejscia1=wejscia1+16;};     
 if((HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4))==0) {wejscia1=wejscia1+8;};     
 if((HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_5))==0) {wejscia1=wejscia1+4;};     
 if((HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6))==0) {wejscia1=wejscia1+2;};     
 if((HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_7))==0) {wejscia1=wejscia1+1;};
 if((HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0))==0) {wejscia2=wejscia2+128;};
 if((HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1))==0) {wejscia2=wejscia2+64;};
 if((HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2))==0) {wejscia2=wejscia2+32;};     
 if((HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_10))==0) {wejscia2=wejscia2+16;};     
 if((HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_11))==0) {wejscia2=wejscia2+8;};     
 if((HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12))==0) {wejscia2=wejscia2+4;};     
 if((HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_13))==0) {wejscia2=wejscia2+2;};     
 if((HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_14))==0) {wejscia2=wejscia2+1;};
 sprintf(odpowiedz,"...%c%c...", ..., wejscia1, wejscia2,...); //info for crc calculate
 wy_crc=CRC2(14,odpowiedz); //ramka do obliczenia crc
 wy_crc1=wy_crc; //crc1 do ramki wysylane
 wy_crc=wy_crc>>8; //przesuwamy bity
 wy_crc2=wy_crc; // crc2 do ramki wysylanej
 sprintf(Data,"...%c%c...", ..., wejscia1, wejscia2,...,wy_crc1,wy_crc2); // preparing answer
HAL_UART_Transmit_DMA(&huart1, Data, 17); // sending answer
  }

 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    
we_crc_spr=CRC2(5,Received);
we_crc1=we_crc_spr;
we_crc_spr=we_crc_spr>>8;
we_crc2=we_crc_spr;
    //checking order and crc
     if(Received[0]==adres){
     if(we_crc1==Received[6] && we_crc2==Received[7]){
     ramka=1; //zmienna pomocnicza
     memcpy(bufor,Received,8); //kopiuje odebrana ramke do bufora
 }
 }
}
/* USER CODE END PFP */

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

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();

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

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART1_UART_Init();

  /* USER CODE BEGIN 2 */

 

//inputs for adress of board jumpers
 adres=0x00;
 adresik=0x00;
 if((HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_5))==1) {adresik=adresik+8;};
 if((HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6))==1) {adresik=adresik+4;};
 if((HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7))==1) {adresik=adresik+2;};
 if((HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8))==1) {adresik=adresik+1;};
 adres=adresik;
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
        HAL_UART_Receive_DMA(&huart1, Received, 8); //start of listening
        if (ramka==1){
            //przekierowanie rozkazu do funkcji
            switch(bufor[1]){
                case 4:{
                stany(); break;
                }
        }
    }
    ramka=0;
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

}

/** System Clock Configuration
*/
void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_PeriphCLKInitTypeDef PeriphClkInit;

    /**Initializes the CPU, AHB and APB busses clocks
    */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL12;
  RCC_OscInitStruct.PLL.PREDIV = RCC_PREDIV_DIV1;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

    /**Initializes the CPU, AHB and APB busses clocks
    */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }

  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }

    /**Configure the Systick interrupt time
    */
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

    /**Configure the Systick
    */
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

/* USART1 init function */
static void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 9600;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }

}

/**
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{
  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

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

}

/** Configure pins as
        * Analog
        * Input
        * Output
        * EVENT_OUT
        * EXTI
        * Free pins are configured automatically as Analog (this feature is enabled through
        * the Code Generation settings)
*/
static void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8|GPIO_PIN_11, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_SET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3|GPIO_PIN_4, GPIO_PIN_SET);

  /*Configure GPIO pins : PC13 PC14 PC15 */
  GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pins : PA0 PA1 PA2 PA3
                           PA4 PA5 PA6 PA7 */
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PB0 PB1 PB2 PB10
                           PB11 PB12 PB13 PB14 */
  GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_10
                          |GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pins : PB15 PB9 */
  GPIO_InitStruct.Pin = GPIO_PIN_15|GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pins : PA8 PA11 */
  GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_11;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PA12 PA15 */
  GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pins : PF6 PF7 */
  GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);

  /*Configure GPIO pins : PB3 PB4 */
  GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  /*Configure GPIO pins : PB5 PB6 PB7 PB8 */
  GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @param  None
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler */
  /* User can add his own implementation to report the HAL error return state */
  while(1)
  {

  }
  /* USER CODE END Error_Handler */
}

#ifdef USE_FULL_ASSERT

/**
   * @brief Reports the name of the source file and the source line number
   * where the assert_param error has occurred.
   * @param file: pointer to the source file name
   * @param line: assert_param error line source number
   * @retval None
   */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */

}

#endif

/**
  * @}
  */

/**
  * @}
*/

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

 

I don't know if something is slowing down recieve and transmission and if i can speed it up?

Maybe i have problem somewhere else? Can you advise something?

Outcomes