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.