cancel
Showing results for 
Search instead for 
Did you mean: 

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

Bogdan
Senior
Posted on February 22, 2018 at 07:46

Hello,

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...

      while(1)

    {

             if(valid)

            {

                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;

     }

}

0 REPLIES 0