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 ?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

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

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

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?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

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?