AnsweredAssumed Answered

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

Question asked by anton.bogdan on Feb 22, 2018

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;

     }

}

Outcomes