2018-02-21 10:46 PM
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;
}
}