El módulo ADC del STM32 se usa en mi aplicación, que es muy sensible al consumo de energía.
En esta aplicación, se requiere que el ADC funcione solo a 20 muestras por segundo. Usar el DMA usa más poder del que esperaba. Decidí hacer que funcionara en modo de muestra única haciendo que una tarea (FreeRTOS) active un converso y espere a que se realice cada 50 ms.
Aquí está mi código:
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);
Donde "sizeof (ADC_Channel_Table)" es 5 porque se muestrean 5 canales.
El tiempo de muestra es ADC_SampleTime_239Cycles5 (en realidad 256 ciclos donde se incluye el tiempo de conversión). 5 canales por lo tanto requieren aproximadamente 1500 ciclos. El reloj ADC es de 12 MHz y 1500 ciclos son aproximadamente 120 µs.
Y mira el código:
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC))
{
}
Esto significa que la CPU se mantiene ocupada esperando a que se realice la conversión, y el tiempo de espera es de 120 µs en total.
120 µs es grande ya que la CPU debe esperar tanto tiempo y esto desperdicia energía, pero este nivel de tiempo es demasiado pequeño para el RTOS. El RTOS no puede usar tan poco tiempo.
Así que quiero insertar algunas instrucciones de "ahorro de energía" en el ciclo de espera.
Por ejemplo:
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC))
{
__ASM("NOP");__ASM("NOP");__ASM("NOP");__ASM("NOP");
}
Pero NOP consume la misma cantidad de energía que cualquier otra instrucción que haya probado.
¿Qué instrucción puedo insertar en mi bucle while que consumiría la menor cantidad de energía?