The ADC module of the STM32 is used in my application which is very sensitive to power consumption.
In this application, the ADC is required to work only at 20 samples per second. Using the DMA uses more power than I expected. I decided to make it work in single-sample mode by having a task (FreeRTOS) trigger a convert and wait for the convert to be done every 50 ms.
Here is my code:
u16 i;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE);
for(i=0;i<sizeof(ADC_Channel_Table)/sizeof(u8);i++)
{
ADC_RegularChannelConfig(ADC1, ADC_Channel_Table[i], 1, ADC_SampleTime_71Cycles5);
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC))
{
}
ADCConvertedValue[i] = ADC_GetConversionValue(ADC1);
}
ADC_Cmd(ADC1, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, DISABLE);
Where "sizeof(ADC_Channel_Table)" is 5 because 5 channels are sampled.
The sample time is ADC_SampleTime_239Cycles5 (actually 256 cycles where the convert time is included). 5 channels therefore requires about 1500 cycles. ADC clock is 12 MHz and 1500 cycles is about 120 µs.
And look at the code:
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC))
{
}
This means the CPU keeps busy-waiting for the convert to be done, and the wait time is 120 µs in total.
120 µs is big as the CPU must wait for such a long time and this wasted the power, but this level of time is too small for the RTOS. The RTOS is unable to use up such a small time.
So I want to insert some "power-saving" instructions to the wait loop.
For example:
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC))
{
__ASM("NOP");__ASM("NOP");__ASM("NOP");__ASM("NOP");
}
But NOP consumes the same amount of power as any other instruction I have tried.
What instruction can I insert in my while loop that would consume the least amount of power?