cancel
Showing results for 
Search instead for 
Did you mean: 

Error Transmitting data via UART when using ADC & DMA (works separately)

ponuliukas
Associate II

Hi All,

I have been a little confused about my code and would appreciate some help greatly...

I have a basic program where I would like to read the ADC values from a sensor, and transmit them via UART for later signal processing and whatnot.

The structure is simple, and when I tested out reading the values from the ADC, as well as sending strings via UART - they both work perfectly fine. But now when I merge the two, the UART does not work anymore... I do not see anything in my serial monitor (Putty)

I feel like I am missing something big, but cannot find it. I would appreciate it if someone pointed me in the right direction 🙂

in my main, I have: 

 

 

uint32_t value[2]; // start adc in DMA mode
int isSent = 1;
uint8_t tx_buffer[] = "Welcome to BinaryUpdates!\n\r"; 

int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  MX_TIM3_Init();
  MX_TIM4_Init();
  MX_TIM2_Init();
  MX_USART6_UART_Init();

  HAL_ADC_Start_DMA(&hadc1, value, 2);

  while (1)
  {
	  if (isSent == 1)
	      {
	  	  HAL_UART_Transmit_DMA(&huart6, tx_buffer, 27);
//       HAL_UART_Transmit_DMA(&huart6, value[0], sizeof(value[0]));
	  	  isSent = 0;
	      }
	      HAL_Delay(1000);
  }
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
	isSent = 1;
}

 

 

16 REPLIES 16

@ponuliukas wrote:

It works alone, but If I start the ADC DMA, it doesn't work. 


What if you use the ADC without DMA ?

I will try that in a second and will let you know how it goes. 

What I have found out is that if I toggle an LED every 500ms, it works perfectly alone, but then if I uncomment the "HAL_ADC_Start_DMA(&hadc1, value, 2);", the LED gets stuck on always ON.


@ponuliukas wrote:

What I have found out is that if I toggle an LED every 500ms, it works perfectly alone, but then if I uncomment the "HAL_ADC_Start_DMA(&hadc1, value, 2);", the LED gets stuck on always ON.


So it's not just the UART which stops working after you call HAL_ADC_Start_DMA - even a simple LED blink stops working?

Have you used the debugger to check if HAL_ADC_Start_DMA is returning at all ?

Or are you getting stuck in a Hard Fault or other Error Handler?

If HAL_ADC_Start_DMA does return, what result code does it give? Again, see:

https://community.st.com/t5/stm32-mcus-boards-and-hardware/hal-rcc-oscconfig/m-p/674455/highlight/true#M19028

 

If I run just the HAL_ADC_Start_DMA , then when I press on my pressure sensor - the values are visible in the live expressions - they go from 0 to 2555, which is a value I expect. 

So where does the toggling LED come into that?

I just toggle it in the main while loop (RGB LED, and I just toggle the red channel) to see if the program would still function correctly when I read the ADC with my sensor values.

  while (1)
  {
	  int del = 500;

	  htim4.Instance->CCR1 = 255;
	  HAL_Delay(del);
	  htim4.Instance->CCR1 = 0;
	  HAL_Delay(del);
}

 

Coming back with a little breakthrough - but not sure how ideal this situation is. 

If I change the DMA for ADC from "circular" to "normal", and put the two in the main while loop, then I manage to read the ADC values and send them via UART. 

 

  while (1)
  {
	  HAL_ADC_Start_DMA(&hadc1, value, 2);
	  raw = value[0];
	  sprintf(buffer, "%u\n\r", raw); \\ char buffer[7]
	  HAL_UART_Transmit(&huart6, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
  }

 

I was wondering whether in your opinion this is a bad way to do this. Should I use interrupts instead, or if it is not broken, then don't fix it?