AnsweredAssumed Answered

Advice to handle data between Timer IRQ and DMA USART TX IRQ

Question asked by anton.bogdan on Feb 22, 2018


i am working on a project where i read 4 external adc's in a timer irq and i need to send the data very fast via usart.

I know this is achievable only trough DMA USART TX request.


The timer irq is executing once every 1ms, inside this i read the adc via spi ( takes around 4us which is enough time before the next irq event occurs)


i have a  char buffer[]  to feed the DMA,.



The incoming adc data is uint16_t , i am converting to 0.2% float,  and my char packet has the following structure


buffer = "1.23$4.56$7.89$1.23\r\n" - where $ is the delimiter for each sensor, plus the terminating \r\n


My concern is where should i do the conversion from int/float to char?


I was thinking something like bellow :


 1) in in the timer isr :  -  read the sensors

                                   -  set the valid flag, indicating a new data is available for processing

 2) in the main program loop : - wait for valid flag to be set

                                                - reset the valid flag

                                                -  convert the data to string

                                                - enable the USART TX DMA request

What do you think?



I have posted a "simplified" code 


int main(void) 


 timer, usart,dma,rcc setup...







                valid =0; // reset flag

                 buffer = add adc data from sensor[0..3] to char format

                 USART_DMACmd(USART3, USART_DMAReq_Tx, ENABLE); //  USART TX DMA Request











void DMA1_Stream3_IRQHandler(void)
    if (DMA_GetITStatus(DMA1_Stream3, DMA_IT_TCIF3))  // DMA transfer complete

            DMA_ClearITPendingBit(DMA1_Stream3, DMA_IT_TCIF3);

            USART_DMACmd(USART3, USART_DMAReq_Tx, DISABLE); // Disable USART TX DMA Request


void TIM1_UP_TIM10_IRQHandler(void)

     if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET)
     TIM_ClearITPendingBit(TIM1, TIM_IT_Update);

     sensor[0] = readSPI_ADC(1);

     sensor[1] = readSPI_ADC(2);

     sensor[2] = readSPI_ADC(3);

     sensor[3] = readSPI_ADC(4);

     valid = 1;