¿Por qué varía el tiempo de conversión de ADC?

5

Estoy usando TI Tiva C TM4C123GH6PM en un Launchpad combinado con un AD 9850 DDS para crear un modulador de frecuencia.

Actualmente tengo un programa extremadamente simple que básicamente configura los periféricos del microcontrolador y el AD9850 y luego ingresa en un bucle en el que muestrea la señal de audio que llega al ADC del microcontrolador y, según los resultados, ajusta la frecuencia de salida del DDS.

Mi problema es que el tiempo de ejecución del bucle no es constante.

El bucle se divide en tres partes básicas: en la primera parte, obtengo una muestra del ADC, en la segunda parte, se calculan los ajustes necesarios para el AD9850 y en la tercera parte esos ajustes se envían al AD9850 .

Después de hacer un recuento de algunos ciclos, resulta que la segunda y la tercera parte siempre duran 2670 ciclos de reloj. Esto me deja con el único sospechoso siendo la primera parte.

Después de medir el tiempo de ejecución de la primera parte solo, me he dado cuenta de que varía desde 100 ciclos hasta 8000 ciclos.

Aquí hay un buen gráfico que obtuve del depurador que muestra cómo el número de ciclos cambia con el tiempo:

MiréenlahojadedatosdelapiezayenlaGuíadelusuariodelaBibliotecadecontroladoresperiféricosdeTivawareynopudeencontrarunarazónporlaqueelmuestreotuvieraunafluctuacióntandrástica.ElmuestreodeADCmáseltiempodeconversiónsemuestracomo1microsegundo,queesalrededorde80ciclosdeprocesador,yaqueestoyfuncionandoaunafrecuenciaderelojde80MHz.Estohacequeladuracióndelbucleeneláreadealrededorde100a200ciclosseveabien,peronotengoabsolutamenteningunaideadeloqueestásucediendoenelcasocuandoeltiempoestáenlosmilesdeciclos.

TambiénheleídolaerrataparaelADCy,porloquepuedover,ningunodelosnumerososproblemasseaplicaamicaso.TambiénlapartequetengoesunaparterealdeTM4,nounaparteexperimentaldeXM4.

Aquíestálaparteproblemáticadelcódigo:

c_start=HWREG(DWT_BASE+DWT_O_CYCCNT);//startscyclecountingROM_ADCIntClear(ADC0_BASE,3);//clearsinterruptflagADCProcessorTrigger(ADC0_BASE,1);//Triggeringsequence1while(!ROM_ADCIntStatus(ADC0_BASE,3,false))//WaitsforADCtofinishconverting{//BusywaittobereplacedwithanISRatsomepoint}ROM_ADCSequenceDataGet(ADC0_BASE,3,adcData);//adcDatapointertomemorylocation//usedtostoreresultsc_stop=HWREG(DWT_BASE+DWT_O_CYCCNT);//Endscyclecountc_dur=c_stop-c_start;//Providesnumberofcycles,refreshbreakpointgoeshere

AquíestáelcódigodeconfiguracióndeADC:

ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);//PinisPD1=>channelAIN6ROM_ADCHardwareOversampleConfigure(ADC0_BASE,64);//Averages64samplesandstorestheminoneFIFOslot,//hasapparentlynoeffectontheconversiontime,sameresultswhendisabledHWREG(ADC0_BASE+0x038)=0x40;//ThisenableshardwareditheringADCSequenceConfigure(ADC0_BASE,3,ADC_TRIGGER_PROCESSOR,0);//UsesADC0,sequence3=>FIFOwithlengthofone,highestpriorotyADCSequenceStepConfigure(ADC0_BASE,3,0,ADC_CTL_CH6|ADC_CTL_IE|ADC_CTL_END);//Firstandlaststep,selectsADC0,sequence3,stepzero,channel6,//enablesinterruptandendssequenceADCSequenceEnable(ADC0_BASE,3);//Enablessequence

ACTUALIZACIÓN:Seguíadelanteehicelapruebaconmovimientodepinesyobtuveresultadosrelativamentesimilares.Enestaimagen,unpinsubeyluegobajainmediatamentetanprontocomoserealizaelADC.Estosetomaconelditheringyelsobremuestreodehardwaredeshabilitados,conunafrecuenciademuestreode1MSa/syunamemoriaintermediaFIFOde1.

    
pregunta AndrejaKo

5 respuestas

1

Si bien hay otras razones que describen las causas de su fluctuación de fase, depender de cosas como el tiempo de conversión (o incluso las ramas ocultas en las bibliotecas de funciones en las que cada rama toma diferentes tiempos) es una mala práctica para los sistemas en tiempo real.

Si necesita un tiempo de bucle de inestabilidad bajo, debe HACERLO creando una interrupción de temporizador para dársela. Si necesita velocidad, el temporizador debe configurarse en su tiempo máximo a través de sus bucles, más un poco de espacio para la cabeza. En una interrupción por temporizador, debe revisar todo lo que debe hacerse en función de su última lectura de ADC, luego hacer la siguiente lectura de ADC.

    
respondido por el Scott Seidman
0
  

Cuando esto sucede, el microcontrolador no se reinicia. Si lo hiciera, lo vería en el depurador.

Sospecho que siempre estás ejecutando esto bajo el depurador y que has configurado un reloj en adcData porque son datos interesantes. El IDE es útil preservar que entre ejecuciones. Además, supongo que el procesador de TI admite puntos de control de hardware en las escrituras de memoria, y el depurador los está utilizando para detectar actualizaciones en adcData . Cada vez que pasa por su bucle, el depurador llega al punto de observación y se detiene durante el tiempo que le lleve al depurador externo leer los datos y reanudar el chip.

Si mantuviera el movimiento de bits y corriera sin el depurador, podría probar esta teoría.

    
respondido por el Ben Jackson
0

Como una nota al margen, se supone que el tiempo de adquisición del ADC es finito, pero he visto algunas variaciones en la caracterización de los componentes. La hoja de datos probablemente da un típico o un "garantizado por diseño". Además, la validez de cada adquisición no está garantizada debido al ruido, ya sea por diseño o por cualquier otro motivo.

    
respondido por el Whistle1560
0

No menciona interrupciones, pero veo que está borrando un indicador de interrupción en el código. Si aún no lo ha hecho, intente deshabilitar las interrupciones globalmente. Si se desencadenan otras interrupciones, pueden estar causando este jitter.

Con un bucle basado en software, hay muchas cosas que pueden causar una ejecución irregular. La forma más confiable de obtener datos muestreados de manera precisa es activar el ADC usando una fuente confiable como un temporizador (que creo que puede hacer sin hardware externo en este dispositivo). La misma señal del temporizador podría desencadenar un ISR, donde puede recopilar y usar el resultado con mayor tranquilidad, o podría provocar que DMA copie muestras en un búfer de algún tipo.

Sugiero precaución con bibliotecas como TivaWare. Por lo general, se escriben por conveniencia, no de alta eficiencia. Si puedes rastrear el código fuente, es probable que encuentres que están realizando una gran cantidad de tareas domésticas en esas rutinas. Muy a menudo obtendrás un rendimiento mucho mejor al golpear directamente los registros.

    
respondido por el MPA
0

Hay 3 tipos de convertidores analógico a digital más utilizados.

  • Tipo de contador ADC.
  • Tipo de aproximación sucesiva ADC.
  • Flash tipo ADC.

    1. Tipo de contador ADC:

      En este tipo, la entrada se compara con un voltaje de referencia generado digitalmente. el voltaje de referencia se incrementa paso a paso hasta que el voltaje de referencia es mayor que el voltaje de entrada. Por lo tanto, para diferentes voltajes de entrada, el tiempo de conversión es diferente. p>

    2. Tipo de aproximación sucesiva ADC:

      En este tipo, se usa el mismo principio pero de manera inteligente. La primera tensión de entrada se compara con Va / 2 (donde Va es el límite superior de la tensión de entrada) para encontrar en qué mitad se encuentra. si es mayor que Va / 2, se compara con 3Va / 4; de lo contrario, se compara con Va / 4 para encontrar en qué trimestre se encuentra. Algo así como una búsqueda binaria en programas de computadora.

    3. Flash tipo ADC:

      En este tipo, la tensión de entrada se compara con todos los niveles de tensión al mismo tiempo y se proporciona la salida correspondiente. El tiempo empleado en este tipo de conversión es constante y no depende del voltaje de entrada.

Para obtener más información sobre ADC, lea pdf: enlace

Sugiero que un ADC de Flash sería lo mejor para tu circuito. Si desea trabajar en el mismo hardware, hay dos cosas que podría hacer.

  1. encuentre el tiempo máximo (Ta) que toma el ADC para la conversión. Establezca una interrupción de temporizador en cualquier valor más que Ta. Cada vez que solicite una conversión, inicie el temporizador y ejecute el resto del código solo después de que se haya producido la interrupción. Esta no es la mejor manera, pero obtendrás la conversión ADC en un tiempo constante. La estructura del código se verá así:

    • (parte 1):
    • Solicitud de conversión.
    • Configurar la interrupción del temporizador.
    • i = 0;
    • while (i == 0) {} // no es necesario realizar una encuesta
    • almacenar datos desde ADC
    • ejecuta la parte 2 y la parte 3 igual que antes

      Rutina de servicio de interrupción para la interrupción del temporizador

      • {i = 1;}

    Nota: configurar la interrupción del temporizador   significa poner el temporizador a 0 y habilitar interrupciones.

O

  1. use el ADC en modo de ejecución libre (el ADC sigue convirtiendo, sin importar si se solicita o no una conversión). Cada vez que desee tomar una muestra, simplemente cárguela sin solicitar la conversión de ADC. no hay necesidad de bucle while. (Pero para que se utilice este método, su ADC debe ser compatible con el modo de ejecución libre)
respondido por el Tanmay

Lea otras preguntas en las etiquetas