cancel
Showing results for 
Search instead for 
Did you mean: 

How to establish UART communication between two microcontrollers

ESpra.1
Senior

I am trying to transfer sensor data collected on a NUCLEO-144 L552ZET6Q board to a Sparkfun Artemis BLE Module via UART DMA. However, I can't get the STM32 to send anything on any UART besides messages to TeraTerm using the basic HAL_UART_TRANSMIT function on LPUART1.

I've tried using a logic analyzer, and it's showing absolutely no response from the UART, and the debugger in STM32CubeIDE is showing an error code of 0x200001f8, which I can't match to any combination of errors so far.

I'm pretty new to STM32Cube, so it's likely that I'm missing something in the setup, though I haven't been able to find what it is so far. Anyone see anything that I've missed so far?

Below is a few pieces of a basic program to count the number of UART transfers from the STM32 to the Artemis BLE. The Artemis is then meant to write that count to a BLE Characteristic to be read on a BLE Scanning app like BLE Scanner or nRF Connect.

int main(void)
{
  /* USER CODE BEGIN 1 */
	uint8_t cnt = 0;
  /* 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_LPUART1_UART_Init();
  MX_RTC_Init();
  MX_UCPD1_Init();
  MX_USART2_UART_Init();
  MX_USB_PCD_Init();
  /* USER CODE BEGIN 2 */
  uint8_t tx_buf[64] = "";
  uint8_t len = 0;
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	cnt++;
	len = sprintf(tx_buf, "Transmissions sent: %d\r\n", cnt);
	if(HAL_UART_Transmit_DMA(&huart2,tx_buf,sizeof(tx_buf)) != HAL_OK)
	{
		Error_Handler();
	}
	HAL_Delay(500);
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
 
static void MX_USART2_UART_Init(void)
{
 
  /* USER CODE BEGIN USART2_Init 0 */
 
  /* USER CODE END USART2_Init 0 */
 
  /* USER CODE BEGIN USART2_Init 1 */
 
  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */
 
  /* USER CODE END USART2_Init 2 */
 
}
 
static void MX_DMA_Init(void)
{
 
  /* DMA controller clock enable */
  __HAL_RCC_DMAMUX1_CLK_ENABLE();
  __HAL_RCC_DMA1_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA1_Channel1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
 
}

Feel free to let me know what other information might be helpful

5 REPLIES 5
S.Ma
Principal

Check cube nucleo 2 boards uart examples. Not a plug and play, just a first thing to help find the root cause. Make sure the uart pins are not the ones wired to the builtin stlink virtual com port...

ESpra.1
Senior

I tried that and things went haywire in CubeIDE. I'll take another look though.

*update as I was working on this: Progress! I'm seeing the latter half of the first transmission being sent to BLE! It looks like this on my end: "ssions sent: 1". And this is with HAL_UART_Transmit_DMA! Unfortunately, it encounters an error after the first transfer.

Does this ring a bell to anyone?

Yeah, trying to search the example you suggest crashed CubeIDE... Anywhere else I can find it?

S.Ma
Principal

If in the cube nucleo example projects you are lucky to have richer uart example with cyclic buffers, start from these ones. On my side, i use LL because with console like protocol, block length is known last and usually 1Mbps hardly justify a DMA like a 12 Mbps SPI would do, unless using the dma to have time periodic checks without interrupts.

Bob S
Principal

May not be your issue, but...

if(HAL_UART_Transmit_DMA(&huart2,tx_buf,sizeof(tx_buf)) != HAL_OK)

That line will ALWAYS send 64 bytes (the size of tx_buf[]). The additional bytes will be NULL chars (i.e. zeros). I don't know if that will confuse your other device. Use strlen(tx_buf), or "len" instead of sizeof().

Not related to your problem, but something to improve your future code:

len = sprintf(tx_buf, "Transmissions sent: %d\r\n", cnt);

Get in the habit of using snprintf() instead of sprintf(). Yeah, in this particular case you can be sure you won't overflow tx_buf. But in bigger programs that may not be as clear. Or someone may change the buffer size trying to save a few bytes of RAM, or add to the format string, or you print integer values that you KNOW will never be > 1000 but some bug corrupts the value and it is suddenly something like 2147483648. snprint() will save you many hours of debugging time.