Estoy utilizando TI Tiva C TM4C123GH6PM en un Launchpad combinado con un ANUNCIO 9850 DDS para crear frecuencia del modulador.
Actualmente tengo un muy sencillo programa que básicamente establece periféricos del microcontrolador y el AD9850 y luego entra en un bucle en el que las muestras de audio de las señales al microcontrolador del ADC y con base en los resultados ajusta la frecuencia de salida del DDS.
Mi problema es que el bucle del tiempo de ejecución no es constante.
El ciclo está dividido en tres partes: En la primera parte, que obtener una muestra de la ADC, en la segunda parte, los ajustes necesarios para el AD9850 se calculan y en la tercera parte, los valores se envían a la AD9850.
Después de hacer algunas ciclo de conteo, resulta que la segunda y tercera parte siempre la última para 2670 ciclos de reloj. Esto me deja con el único sospechoso de ser la primera parte.
Después de medir el tiempo de ejecución de la primera parte por si solo, me he dado cuenta de que varía desde un mínimo de 100 ciclos hasta 8000 ciclos.
He aquí una bonita gráfica que tengo de el depurador muestra cómo el número de ciclos de cambios con el tiempo:
Me puse a pensar en la hoja de datos de la pieza y en el Tivaware controladores de Periféricos manual del Usuario de Biblioteca y yo no podía encontrar una razón por la que el muestreo tendría tan drásticas fluctuaciones. El ADC de muestreo más tiempo de conversión aparece como 1 microsegundo, que es de alrededor de 80 ciclos de procesador, ya estoy corriendo a 80 MHz, la frecuencia de reloj. Esto hace que la duración del bucle en la zona de alrededor de 100 a 200 ciclos ven bien, pero no tengo absolutamente ninguna idea de lo que está sucediendo en el caso cuando el tiempo está en los miles de ciclos.
También he leído la fe de erratas para el ADC y por lo que puedo ver, ninguno de los numerosos problemas que se aplican a mi caso. También la parte que tengo es un real TM4 parte, no experimental XM4 parte.
He aquí la problemática es la parte del código:
c_start = HWREG(DWT_BASE + DWT_O_CYCCNT); // starts cycle counting
ROM_ADCIntClear(ADC0_BASE, 3);//clears interrupt flag
ADCProcessorTrigger(ADC0_BASE, 1);//Triggering sequence 1
while(!ROM_ADCIntStatus(ADC0_BASE, 3, false))//Waits for ADC to finish converting
{//Busy wait to be replaced with an ISR at some point
}
ROM_ADCSequenceDataGet(ADC0_BASE, 3, adcData);//adcData pointer to memory location
//used to store results
c_stop = HWREG(DWT_BASE + DWT_O_CYCCNT); // Ends cycle count
c_dur=c_stop-c_start;//Provides number of cycles, refresh breakpoint goes here
Aquí está la instalación de ADC código:
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);//Pin is PD1=>channel AIN6
ROM_ADCHardwareOversampleConfigure(ADC0_BASE, 64);
//Averages 64 samples and stores them in one FIFO slot,
//has apparently no effect on the conversion time, same results when disabled
HWREG(ADC0_BASE+ 0x038) = 0x40;//This enables hardware dithering
ADCSequenceConfigure(ADC0_BASE,3,ADC_TRIGGER_PROCESSOR,0);
//Uses ADC0, sequence 3=>FIFO with length of one, highest prioroty
ADCSequenceStepConfigure(ADC0_BASE,3,0,ADC_CTL_CH6|ADC_CTL_IE|ADC_CTL_END);
//First and last step, selects ADC0, sequence 3, step zero, channel 6,
// enables interrupt and ends sequence
ADCSequenceEnable(ADC0_BASE,3);
//Enables sequence
ACTUALIZACIÓN: Me fui por delante y hice la prueba con el pin retorciéndose y tengo relativamente similares resultados. En esta imagen, un pin va alto y luego inmediatamente a la baja tan pronto como ADC está hecho. Esto es tomado con difuminado y hardware de sobremuestreo de movilidad, con una frecuencia de muestreo de 1 MSa/s y de búfer FIFO de profundidad de 1.