<?xml version="1.0" encoding="utf-8"?><!DOCTYPE article  PUBLIC '-//OASIS//DTD DocBook XML V4.4//EN'  'http://www.docbook.org/xml/4.4/docbookx.dtd'><article><articleinfo><title>WebHome/Hardware/ModuloADC</title><revhistory><revision><revnumber>22</revnumber><date>2016-10-18 21:40:36</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>21</revnumber><date>2016-10-14 22:19:26</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>20</revnumber><date>2016-10-14 22:17:43</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>19</revnumber><date>2016-10-14 22:16:44</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>18</revnumber><date>2016-10-14 22:11:39</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>17</revnumber><date>2016-10-14 21:09:42</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>16</revnumber><date>2016-10-14 21:08:33</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>15</revnumber><date>2016-10-14 21:07:25</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>14</revnumber><date>2016-10-14 19:40:07</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>13</revnumber><date>2016-10-13 22:45:27</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>12</revnumber><date>2016-09-29 21:00:49</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>11</revnumber><date>2016-09-29 20:46:23</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>10</revnumber><date>2016-09-29 19:51:57</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>9</revnumber><date>2016-09-29 19:50:29</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>8</revnumber><date>2016-09-29 19:47:30</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>7</revnumber><date>2016-09-29 19:24:33</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>6</revnumber><date>2016-09-29 19:11:38</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>5</revnumber><date>2016-09-28 22:45:12</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>4</revnumber><date>2016-09-28 22:09:56</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>3</revnumber><date>2016-09-28 21:41:31</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>2</revnumber><date>2016-09-28 20:11:09</date><authorinitials>GuillermoSteiner</authorinitials></revision><revision><revnumber>1</revnumber><date>2016-09-28 18:42:22</date><authorinitials>GuillermoSteiner</authorinitials></revision></revhistory></articleinfo><section><title>ADC (Analog Digital Converter)</title><para>Este periférico permite convertir señales analógicas en una cuenta o valor digital. </para><section><title>Características y Registros ADC</title><para>El LPC43xx posee 2 ADC idénticos, cada uno de ellos posee las siguientes características: </para><itemizedlist><listitem><para>Conversor de 10 bits </para></listitem><listitem><para>8 entradas multiplexadas </para></listitem><listitem><para>Rango de entrada de 0 a 3,3 V </para></listitem><listitem><para>Tiempo de conversión 2,45us </para></listitem><listitem><para>Modo Ráfaga (Burst) para una entrada o múltiples entradas (multiplexado). </para></listitem><listitem><para>Un registro de resultado para cada canal AD </para></listitem></itemizedlist><section><title>Entradas</title><itemizedlist><listitem><para>ADC0_0 a ADC0_7 Entrada del ADC 0. </para></listitem><listitem><para>ADC1_0 a ADC1_7 Entrada del ADC 1. </para></listitem><listitem><para>ADCTRIG0 Entrada Trigger ADC0/1. </para></listitem><listitem><para>ADCTRIG1 Entrada Trigger ADC0/1. </para></listitem></itemizedlist><para>Estos nombres deben buscarse dentro del mapa del SCU y configurar adecuadamente el pin para su uso como ADC. </para></section><section><title>Alimentación</title><para>El ADC posee entradas separadas de alimentación denominadas V<subscript>DDA</subscript> y V<subscript>SSA</subscript>, usadas para el bloque analógico, las mismas deben estar correctamente aisladas de las demás señales para no generar errores en la conversión producto de las fluctuaciones en estas lineas. </para><para>V<subscript>DDA</subscript> es usada además como V<subscript>REF</subscript> </para></section><section><title>Registro de control (CR)</title><informaltable><tgroup cols="4"><colspec colname="col_0"/><colspec colname="col_1"/><colspec colname="col_2"/><colspec colname="col_3"/><tbody><row rowsep="1"><entry colsep="1" rowsep="1"><para>bits 7-0 </para></entry><entry colsep="1" rowsep="1"><para>SEL </para></entry><entry colsep="1" rowsep="1"><para>Estos bits determina en cual o cuales de los 8 canales se realizará la conversión, correspondiendo cada bits a cada una de las entradas, este registro funciona de dos maneras diferentes: * Controlado por software, en este modo solo un bits puede ser puesto en 1, el cual será el canal donde se realizará la conversión. * Controlado por hardware, en este modo se selecciona con 1 a todos los canales donde se deben realizar una conversión, una vez activo el ADC en este modo, se producirá un barrido de todos estos canales. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>bits 15-8 </para></entry><entry colsep="1" rowsep="1"><para>CLKDIV </para></entry><entry colsep="1" rowsep="1"><para>El clock interno del ADC se extrae del VPB (PCLK) dividido el valor guardado en CLKDIV, el resultado no deberá ser superior a 4,5 Mhz, generalmente este divisor de configura para producir la máxima frecuencia posible del ADC ( 4,5Mhz) pero en ciertos casos conviene una menor frecuencia, por ejemplo en casos de que la señal a medir provenga de fuentes de alta impedancia. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>bit 16 </para></entry><entry colsep="1" rowsep="1"><para>BURS </para></entry><entry colsep="1" rowsep="1"><para>Si el bit es 0, la conversión es controlada por software requiriendo 11 ciclos de reloj, si en cambio es 1, se activa el control por hardware, ahora el tiempo de conversión y el rango de la misma será designado por CLKS, produciendo un barrido en cada canal que se encuentre activo en el registro SEL, comenzando por el bit menos significativo en 1. La conversión continuará hasta que se borre el el bits del BURST, con lo cual se detendrá el proceso una vez que la convención que se esté efectuando termine. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>bits 19-17 </para></entry><entry colsep="1" rowsep="1"><para>CLKS </para></entry><entry colsep="1" rowsep="1"><para>Este campo es usando en el modo de control por hardware y determina el número de ciclos usados para la conversión y el número de bits de precisión, pudiendo elegir entre 11 clock (10bits) = 000, 10 clock (9bits) = 001 hasta 4 clock (3bits) = 111. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>bit 20 </para></entry><entry colsep="1" rowsep="1"/><entry colsep="1" rowsep="1"><para>Reservado. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>bit 21 </para></entry><entry colsep="1" rowsep="1"><para>PDN </para></entry><entry colsep="1" rowsep="1"><para>1 = el ADC está operacional 0 = el ADC está en modo power down. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>bits 23-22 </para></entry><entry colsep="1" rowsep="1"/><entry colsep="1" rowsep="1"><para>Reservado. </para><!--Alignment center&amp not supported--></entry></row><row rowsep="1"><entry colsep="1" morerows="8" nameend="col_0" namest="col_0" rowsep="1"><para>bits 26-24 </para><!--Alignment center&amp not supported--></entry><entry colsep="1" morerows="8" nameend="col_1" namest="col_1" rowsep="1"><para>START </para></entry><entry colsep="1" rowsep="1"><para>Configura de que manera el ADC comenzará a convertir, en caso de estar configurado en modo control por software (BURST = 0). </para><!--Alignment center&amp not supported--></entry><entry colsep="1" morerows="8" nameend="col_3" namest="col_3" rowsep="1"/></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>0x0: no comienza, este es el valor a usar cuando PDN = 0. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>0x1: comenzar la  conversión ahora. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>0x2: flanco del tipo establecido en EDGE en el pin  CTOUT_15. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>0x3: flanco del tipo establecido en EDGE en el pin CTOUT_8. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>0x4:  flanco del tipo establecido en EDGE en el pin ADCTRIG0. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>0x5: flanco del  tipo establecido en EDGE en el pin ADCTRIG1. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>0x6: flanco del tipo  establecido en EDGE en el pin Motocon PWM output MCOA2. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>0x7: reservado. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"/></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>bit 27 </para></entry><entry colsep="1" rowsep="1"><para>EDGE </para></entry><entry colsep="1" rowsep="1"><para>Este bits es utilizado en caso de configurar a START en algún modo que requiera flanco (modo 0x2 a 0x6). EDGE = 0 la conversión inicia en un flanco de bajada. EDGE = 1 la conversión inicia en un flanco de subida. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>bits 31-28 </para></entry><entry colsep="1" rowsep="1"/><entry colsep="1" rowsep="1"><para>Reservado. </para></entry></row></tbody></tgroup></informaltable></section><section><title>Registro global de datos (GDR)</title><informaltable><tgroup cols="3"><colspec colname="col_0"/><colspec colname="col_1"/><colspec colname="col_2"/><tbody><row rowsep="1"><entry colsep="1" rowsep="1"><para>bits 15-6 </para></entry><entry colsep="1" rowsep="1"><para>V/V3A </para></entry><entry colsep="1" rowsep="1"><para>indica el resultado de la conversión. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>bits 26-24 </para></entry><entry colsep="1" rowsep="1"><para>CHN </para></entry><entry colsep="1" rowsep="1"><para>Indica el canal de la ultima conversión. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>bit 30 </para></entry><entry colsep="1" rowsep="1"><para>OVERRUN </para></entry><entry colsep="1" rowsep="1"><para>En modo BURST este bits está en 1 si una o varias conversiones fueron perdidas por no leer a tiempo el registro antes de que una nueva la pisara. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>bit 31 </para></entry><entry colsep="1" rowsep="1"><para>DONE </para></entry><entry colsep="1" rowsep="1"><para>Este registro indica con 1 que la conversión a finalizado, es borrado cuando este registro es leído y cuando el CR es escrito, si el CR es escrito mientras que se estaba realizando una conversión, este bit es puesto a 1 y una nueva conversión arranca </para></entry></row></tbody></tgroup></informaltable></section><section><title>Registro de habilitación de interrupción (INTEN)</title><informaltable><tgroup cols="3"><colspec colname="col_0"/><colspec colname="col_1"/><colspec colname="col_2"/><tbody><row rowsep="1"><entry colsep="1" rowsep="1"><para>bits 7-0 </para></entry><entry colsep="1" rowsep="1"><para>ADINTEN </para></entry><entry colsep="1" rowsep="1"><para>Indica que canal/es generará/n interrupción, un 1 en el bit 0 indica que el canal 0 generará interrupción al finalizar la conversión, un 1 en el bit 1 corresponderá una interrupción para el canal 1 y asi con los demás canales. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>bits 8 </para></entry><entry colsep="1" rowsep="1"><para>ADGINTEN </para></entry><entry colsep="1" rowsep="1"><para>Cuando su valor es 1 habilita la interrupción cuando el bit DONE se ponga en 1, en caso de 0 la interrupción la genera los canales individuales indicados en ADINTEN. </para></entry></row></tbody></tgroup></informaltable></section><section><title>Registro de Datos (DR0-DR7)</title><para>Es una copia del registro GDR pero particular para cada canal, disponiendo del último dato convertido para un canal en particular, el bit DONE para verificar si hay un nuevo dato a leer y OVERRUN para detectar perdida de datos convertidos. </para></section><section><title>Registro de Status (STAT)</title><para>Permite acceder a los bit DONE y OVERRUN de todos los canales </para><informaltable><tgroup cols="3"><colspec colname="col_0"/><colspec colname="col_1"/><colspec colname="col_2"/><tbody><row rowsep="1"><entry colsep="1" rowsep="1"><para>bits 7-0 </para></entry><entry colsep="1" rowsep="1"><para>DONE </para></entry><entry colsep="1" rowsep="1"><para>Bits DONE de los 8 canales. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>bits 15-8 </para></entry><entry colsep="1" rowsep="1"><para>OVERRUN </para></entry><entry colsep="1" rowsep="1"><para>Bits OVERRUN de los 8 canales. </para></entry></row><row rowsep="1"><entry colsep="1" rowsep="1"><para>bit 16 </para></entry><entry colsep="1" rowsep="1"><para>ADINT </para></entry><entry colsep="1" rowsep="1"><para>Este bit se pone en 1 cuando algún canal termina de convertir y el mismo está habilitado para generar interrupción via el registro ADINTEN </para></entry></row></tbody></tgroup></informaltable></section></section><section><title>Configuración y Lectura de un ADC</title><para>Para la configuración y lectura del ADC se utilizará las librerías de las LPCOpen </para><section><title>Configuración de la SCU</title><para>Una diferencia importante que comparten el ADC junto con el DAC con respecto a los demás periférico, es la configuración de los pines de entrada (ADC) o salida (DAC), como se detalló en otros casos, el primer paso es configurar los pines para que estos puedan ser utilizados por el periférico, en la mayoría de los casos esto se realiza con los registros SFSP utilizando la funcion de la LPCOpen <code>Chip_SCU_PinMux()</code>. </para><para>La situación es diferente para los dos periféricos analógicos (ADC y DAC), en estos casos, es necesario configurar el registro ENAIO (ENAIO0 y ENAIO1 para las dos ADC y ENAIO2 para el caso del DAC), el mismo permite cambiar la configuración de los pines de digital a analógico quedando de esta forma el pin listo para su uso en el periférico correspondiente. De esta manera se configura entonces mediante la siguiente función del LPCOpen. </para><para><code>  STATIC INLINE void Chip_SCU_ADC_Channel_Config(uint32_t ADC_ID, uint8_t channel);</code> </para><para>Como ejemplo si se quiere configurar al canal 1 del del ADC0 se escribirá lo siguiente. </para><para><code> Chip_SCU_ADC_Channel_Config(0,ADC_CH1); </code> </para></section><section><title>Inicialización del Periférico</title><para>La inicialización del ADC se realiza con la función Chip_ADC_Init(), esta función inicializa el periférico y establece una configuración para su funcionamiento por defecto, esta configuración por defecto será la siguiente: </para><itemizedlist><listitem><para>Velocidad de conversión = 400Ksamples </para></listitem><listitem><para>Cantidad de bits = 10 </para></listitem><listitem><para>Modo burst (ráfaga) desactivado. </para></listitem></itemizedlist><para>El formato de la función es el siguiente </para><para><code> void Chip_ADC_Init(LPC_ADC_T *pADC, ADC_Clock_Setup_T *ADCSetup);</code> </para><para>Donde ADCSetup es una estructura que devuelve la configuración por defecto. </para></section><section><title>Habilitación del Canal</title><para>Con el comando </para><para><code>Chip_ADC_EnableChannel(LPC_ADC_T *pADC, ADC_CHANNEL_T channel, FunctionalState NewState)</code> </para><para>Se habilita o se deshabilita uno de los canales del ADC </para><itemizedlist><listitem><para><emphasis role="strong">channel</emphasis> es el número de canal (ADC_CH0, ADC_CH1 ... ADC_CH7) </para></listitem><listitem><para><emphasis role="strong">NewState</emphasis> es la acción que se desea aplicar sobre el canal (ENABLE para activar el canal DISABLE para desactivarlo) </para></listitem></itemizedlist></section><section><title>Modo de Arranque</title><para>El paso final es configurar el modo de arranque del ADC, es decir que evento generará un <emphasis role="strong">Start Conversion</emphasis> </para><para><code>Chip_ADC_SetStartMode(LPC_ADC_T *pADC, ADC_START_MODE_T mode, ADC_EDGE_CFG_T EdgeOption)</code> </para><para>mode puede tener los siguientes valores: </para><itemizedlist><listitem><para>ADC_NO_START : Para el caso de funcionamiento modo Burst </para></listitem><listitem><para>ADC_START_NOW : Arranca la conversión ahora </para></listitem><listitem><para>DDC_START_ON_CTOUT15 : flanco del tipo establecido en EdgeOption en el pin  CTOUT_15 </para></listitem><listitem><para>ADC_START_ON_CTOUT8 : flanco del tipo establecido en EdgeOption en el pin CTOUT_8 </para></listitem><listitem><para>ADC_START_ON_ADCTRIG0 : flanco del tipo establecido en EdgeOption en el pin ADCTRIG0 </para></listitem><listitem><para>ADC_START_ON_ADCTRIG1 : flanco del  tipo establecido en EdgeOption en el pin ADCTRIG1 </para></listitem><listitem><para>ADC_START_ON_MCOA2 : flanco del tipo  establecido en EdgeOption en el pin Motocon PWM output MCOA2 </para></listitem></itemizedlist><para>Mientras que EdgeOption </para><itemizedlist><listitem><para>ADC_TRIGGERMODE_RISING : el evento se produce en el flanco de subida </para></listitem><listitem><para>ADC_TRIGGERMODE_FALLING : el evento se produce en el flanco de bajada </para></listitem></itemizedlist></section><section><title>Lectura del ADC</title><para>Una vez realizada la configuración del periférico ADC y generado el <emphasis role="strong">Start Conversion</emphasis>, solo queda efectuar la lectura del valor. </para><para>La lectura se realizará en dos pasos </para><section><title>Verificación de Fin de conversión</title><para>Antes de realizar la lectura del calor convertido es necesario verificar si el proceso de conversión ya terminó, esto se realiza cun la instrucción </para><para><code>Chip_ADC_ReadStatus(LPC_ADC_T *pADC, uint8_t channel, uint32_t StatusType)</code> </para><para>donde <ulink url="https://ciii.frc.utn.edu.ar/TecnicasDigitalesII/WebHome/Hardware/ModuloADC/TecnicasDigitalesII/StatusType#">StatusType</ulink> indica la bandera que se busca leer </para><itemizedlist><listitem><para>ADC_DR_DONE_STAT: bandera que indica fin de conversión. </para></listitem><listitem><para>ADC_DR_OVERRUN_STAT: bandera para verificar si la última conversión sobrescribió la anterior sin ser antes. </para></listitem><listitem><para>ADC_DR_ADINT_STAT: si algún canal terminó de convertir y el mismo está habilitado para generar interrupciones. </para></listitem></itemizedlist><para>Esta función devuelve <emphasis role="strong">SET</emphasis> para el caso afirmativo o <emphasis role="strong">RESET</emphasis> para el caso contrario. </para></section><section><title>Lectura del valor</title><para>La lectura del valor convertido se realiza mediante la función </para><para><code>Chip_ADC_ReadValue(LPC_ADC_T *pADC, uint8_t channel, uint16_t *data)</code> </para><para>Donde data es el puntero a la variable donde se guardará el valor. </para><para>La propia instrucción verifica antes de leer el dato si un valor nuevo espera ser leído (bit DONE) devolviendo <emphasis role="strong">ERROR</emphasis> si no hay dato nuevo o <emphasis role="strong">SUCCESS</emphasis> en caso de una lectura exitosa. </para></section></section></section><section><title>Manejo del ADC por Interrupción</title><para>Aquellos periféricos que poseen un tiempo de respuesta relativamente lento respecto a la velocidad de procesamiento del microcontrolador, los coloca como candidatos a ser administrados mediante interrupciones. El ADC entra como periférico de lenta respuesta, debido a que desde el inicio de conversión hasta su finalización transcurre 2,5 uS, un tiempo donde un micro con un clock a 200MHz puede ejecutar 500 instrucciones. Para la configuración del ADC por interrupciones, se deberá configurar lo siguiente  </para><section><title>Habilitar el pedido de interrupción del ADC</title><para><code>void Chip_ADC_Int_SetChannelCmd(LPC_ADC_T *pADC, uint8_t ichannel,FunctionalState NewState)</code> </para><para>Donde ichannel indica el canal (ADC_CH0, ADC_CH1 .. ADC_CH7) y <ulink url="https://ciii.frc.utn.edu.ar/TecnicasDigitalesII/WebHome/Hardware/ModuloADC/TecnicasDigitalesII/NewState#">NewState</ulink> indica la habilitación (ENABLE) o la deshabituación (DISABLE) del canal seleccionado para realizar interrupciones. </para><para>Finalmente con la instrucción de la NVIC  </para><para><code> NVIC_EnableIRQ(17) </code> </para><para>Habilita la NVIC para capturar los pedidos de interrupción del ADC </para></section><section><title>Función para atender la interrupción</title><para>La función deberá leer el valor convertido y eventualmente lanzar una nueva conversión. </para><para>Esta función deberá reemplazar a la función por defecto que se encuentra en el vector de interrupciones dentro de <emphasis role="strong">vector.c</emphasis> correspondiente al vector 0x21 o IRQ 17. </para><screen><![CDATA[   ISR_NoHandler,      /* 0x1e 0x00000078 - No Handler set for ISR TIMER2 (IRQ 14) */
   ISR_NoHandler,      /* 0x1f 0x0000007C - No Handler set for ISR TIMER3 (IRQ 15) */
   ISR_NoHandler,      /* 0x20 0x00000080 - No Handler set for ISR MCPWM (IRQ 16) */
   ADC0_IRQ,           /* 0x21 0x00000084 - No Handler set for ISR ADC0 (IRQ 17) */
   ISR_NoHandler,      /* 0x22 0x00000088 - No Handler set for ISR I2C0 (IRQ 18) */
   ISR_NoHandler,      /* 0x23 0x0000008C - No Handler set for ISR I2C1 (IRQ 19) */
   ISR_NoHandler,      /* 0x24 0x00000090 - No Handler set for ISR SPI (IRQ 20) */
   ISR_NoHandler,      /* 0x25 0x00000094 - No Handler set for ISR ADC1 (IRQ 21) */]]></screen><para>(Ejemplo reemplazando la función generica ISR_NoHandler por la función ADC0_IRQ) </para></section></section></section></article>