2019-10-10 01:57 AM
Hello, I'm new to STM32 and I'm trying to use this MCU to do timer triggered multiple ADC sampling at 10Hz. I watched a few youtube guides on this matter which all use STM32F~ discovery boards, and have followed along, but got no good results so far.
I have set
1) enabled timer6 with update event every 100ms (baseclock 2.097mHz, prescaler 2097, counter period 100)
2) enabled ADC In 3-7
3) ADC_regular_conversionMode external trigger source timer6 trigger out event, trigger detection on rising edge
4) DMA continuous requests enabled
then in Keil:
1) uint16_t adcVar[5]
2) in main loop,
HAL_ADC_Start_DMA(&hadc, (uint32_t *)&adcVal, 5);
HAL_TIM_Base_Start(&htim6);
-----
Now I'm wondering how I could send each sample from each channel every 100ms through USART? I have tried using ADC interrupt to do so, but I can't get HAL_UART_Transmit to send the correct data.. any help please?
2019-10-10 07:09 PM
What problem are you running into? What’s wrong with the data you’re trying to send?
i would probably use dma tx complete to start the uart transmission, but it could be done in many ways.
2019-10-10 10:53 PM
Hi, I'll outline my complete setup:
CubeMX:
Timer
TIM6 enabled, prescaler: 2097, counter:100, Trigger event: update event
ABP1 timer clock 2.097MHz
ADC
ADC IN3-7 enabled, DMA continuous requests enabled, EOC selection: end of sequence of conversion
sample time: 19.5cycles, external trigger source: timer6 trigger out, external trigger edge: trigger detection on rising edge
DMA mode circular peripheral-to-memory, data width: half word
DMA1 channel 1 interrupt enabled
ADC interrupt enabled
USART
USART1 enabled, USART_TX DMA enabled
DMA mode circular memory-to-peripheral, data width: byte
DMA1 channel 2 interrupt enabled
Keil:
variables
volatile uint16_t adcVal[5];
char header[10] = "AA";
while loop
/* USER CODE BEGIN 2 */
HAL_ADC_Start_DMA(&hadc, (uint32_t *)&adcVal, 5);
HAL_TIM_Base_Start(&htim6);
/* USER CODE END 2 */
ADC complete interrupt
HAL_UART_Transmit(&huart1, (uint8_t *)header, strlen(header), 10);
-------------------------------------
Soo it also seems that what was working yesterday isn't working anymore either (my 5 channel ADC values are not changing in debugging mode)...
What I wanted to do with the above ADC interrupt was to send the header variable first through USART, then send the five 16bit ADC data from channels 3-7 through USART as well...
So my question is:
1) Is there a reason my ADC isn't working anymore (seems like the interrupt stopped completely as well since not even the header is going through USART)? I've changed quite a bit of settings since yesterday and I'm not sure if I can return it to when it worked...
2) after ADC starts working and interrupt works, do I just have to do the following to send five 16bit data in ten 8bit data format?
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)&adcVal, 10);
Thanks for the help, I really appreciate it as a beginner
2019-10-10 11:27 PM
> ADC complete interrupt
> HAL_UART_Transmit(&huart1, (uint8_t *)header, strlen(header), 10);
Do not send in an interrupt context.
Rather set a flag, and send from "normal" user context. You might need to copy the data before.
I hope you checked the output channel (serial interface) bandwidth can keep up with the input data (ADC value / strings).
2019-10-10 11:29 PM
Hi Ozone, thanks for the reply. I actually tried the same code in the main while loop, but saw no avail (I received no data on the RX side). Could you tell me more what you mean by the bandwidth of the output channel? I just have the output of the USART connected to a CP2102 chip which I have always used to send 16bit data in 115200 baud rate. Thanks!