Skip to main content
Associate III
March 8, 2024
Question

sprintf not working when ADC started

  • March 8, 2024
  • 3 replies
  • 2516 views

I'm trying to send ADC results over to a receiver via UART, but somewhy the program freezes on sprintf() IF I have called HAL_ADC_Start_DMA() before. If I call sprintf() before HAL_ADC_Start_DMA() it works fine. However, I need to call it after starting the DMA. How can I fix this?

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

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

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

/* Configure the peripherals common clocks */
 PeriphCommonClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_DMA_Init();
 MX_MEMORYMAP_Init();
 MX_ADC1_Init();
 MX_LPUART1_UART_Init();
 /* USER CODE BEGIN 2 */

 uint32_t values[4] = {0, 0, 0, 0};
 HAL_ADC_Start_DMA(&hadc1, values, 4);

 char str[100];
 sprintf(str, "TEMP_ADC: %d\n", values[1]);
 int size = (int)(ceil(log10(values[1]))+12)*sizeof(char);
 HAL_UART_Transmit(&hlpuart1, str, size, 100);

 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8, SET);

 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	 HAL_Delay(1000);
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}

 

3 replies

Tesla DeLorean
Guru
March 8, 2024

>>How can I fix this?

You debug it, dig into what's actually happening.

Start by stopping the MCU in the debugger and see where it is stuck.

Instrument Hard Fault and Error Handlers so you know if it died there.

Make sure you have the appropriate IRQ Handlers and callbacks to service the interrupts that might occur. 

Make sure there aren't excessive interrupts to the point it saturates the processor, ie > few hundred KHz, or that your handlers/callbacks block

Doubt it is memory related, but don't be using auto/local variables for DMA buffers

Code shown is superficial, issue likely other places.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
JS8Author
Associate III
March 8, 2024

It just crashes once I attempt to move forward from sprintf(). I can't step in the function, as soon is I press it the buttons go gray and the program just stops. The integer variable into sprintf() is completely reasonable. The code you saw was all the code I've written. Everything else is by CubeIDE or C standard library.

Tesla DeLorean
Guru
March 8, 2024

Ok, but presumably the DMA is going to cause an interrupt, so you need a handler to catch that, and call back into the HAL. And then a callback routine on your side for the HAL to call upon completion.

>>The code you saw was all the code I've written

But that's not enough, and likely not the direct cause. It's not that sprintf() isn't working, it that' you've broken the MCU with the task you've assigned it.

The code presented doesn't help me see what's going to happen. The buffer is awfully small and I have no idea of the sample rate, or channels, etc.

Make the DMA buffer static/global, and decimate interrupt loading by making it 10x or 100x larger

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Bob S
Super User
March 8, 2024

Are you sure it is hanging on the sprintf call?  Never reaches a breakpoint set on the next line?  Debug the code, halt the CPU when it is "hung" and see where it is.  Might be deep in the sprintf library/assembly code, might be in a interrupt handler that is getting called repeatedly (probably this).

FYI, sprintf() will return the number of bytes written to the buffer (not including the trailing NULL).  You don't need to calculate it.  And even if you DO need to calculate it, strlen() would be more foolproof in case you change the fixed text in the output string.

FYI #2 - use snprintf() instead of sprintf().  Always.  It is just good programming practice.

JS8Author
Associate III
March 8, 2024

Yes I am 100% sure it is hanging on the sprintf call. As soon as I attempt to step into the function the program crashes.

I can't get the return value of sprintf() because it never returns.

Same issue is with snprintf().

TDK
Super User
March 8, 2024

When you run the program, don't step. Just hit play, then, when the program "hangs", hit pause, see where the cpu is at. Likely it's spinning its wheels in an interrupt somewhere. It's certainly not doing nothing. Use the information in the call stack to identify and fix the problem. If you can't, post a screenshot of the state of the call stack after such a pause.

sprintf does use the heap, could be the issue, hard to tell from the information presented.

"If you feel a post has answered your question, please click ""Accept as Solution""."
JS8Author
Associate III
March 8, 2024

When I started doing this, the code started working out of nowhere. I'm guessing there was bad contact somewhere.