¿Cómo programar el ADC10 en un MSP430G2553?

Actualmente estoy escribiendo mi primera aplicación seria con un controlador MSP430 (específicamente, un MSP430G2553) y estoy un poco confundido por la documentación sobre cómo se supone que debo configurar el ADC10. Quiero usarlo así:

  • La señal (procedente de un potenciómetro de 100 kΩ entre V CC y GND) se conecta a la entrada A4 (pin 6) y está en el rango de GND a V CC
  • De vez en cuando (cuando el usuario presiona un botón) quiero probar el voltaje en esa entrada. Una muestra es suficiente.
  • Tengo suficiente tiempo para hacer lo que sea necesario para probar la entrada cuando llegue el momento de hacerlo.
  • Preferiría hacer esto sincrónicamente (es decir, sin interrupciones) para no complicar demasiado la lógica del programa.
  • El ADC10 debe apagarse cuando no lo esté usando para ahorrar energía.
  • Ni el ADC10 ni el ping 6 se utilizan de ninguna otra forma en esta aplicación.

¿Cómo configuro y uso el ADC10 en este caso de uso? Estoy programando el MSP430 en ensamblaje, pero una respuesta en C también es útil.

Así es como creo que se supone que debe configurarse el ADC:

ADC10CTL0:
  SREFx      = 000  (V_CC)
  ADC10SHTx  = 11   (64 clocks, we have enough time)
  ADC10SR    = 1    (50 kbps should be enough)
  REFOUT     = 0
  REFBURST   = don't care
  MSC        = don't care
  REF2_5V    = don't care
  REFON      = 0
  ADC10ON    = 1    (set to 1 after finishing the configuration)
  ADC10IE    = 0    (no interrupts)

ADC10CTL1
  INCHx      = 0100 (A4)
  SHSx       = 00   (sample and hold sourced from ADC10SC)
  ADC10DF    = 0    (no two's complement)
  ISSH       = 0    (no inversion)
  ADC10DIVx  = 000  (not too sure either)
  ADC10SSELx = 0    (is this the right clock?)
  CONSEQx    = 00   (single channel single conversion)

ADC10AE0     = 0x10 (A4 enabled)
ADC10DTC1    = 0    (DTC disabled)

Creo que la secuencia para muestrear datos se ve así:

  1. poner ADC10ONa 1, ENCy ADC10SCa 0 y configurar todos los registros.
  2. establecer ADC10SCy ENCa 10 para iniciar la conversión
  3. espere 64 + 12 + 1 = 77 ciclos para que finalice la conversión
  4. leer el resultado deADC10MEM

¿Es correcta esta secuencia? ¿Son correctos los ajustes?

Elija ensamblador o C. Las respuestas serán muy diferentes. (recomendación personal: elija C; la programación en ensamblador, a excepción de pequeños fragmentos, tiene poco sentido hoy en día).
Nota: este no es un servicio de escritura de código. Por favor, muestre lo que ha hecho hasta ahora y dónde está realmente su problema. Upps, lo siento, no miré el cartel. FuZxxI, deberías saberlo mejor
Comenzaría con la FUG (guía del usuario familiar). Simplemente configure los registros como se indica en la sección ADC10 y la selección de puertos.
sí claro, dame un momento, estoy en un tren en este momento.
@Olaf Como digo en la pregunta, estoy interesado principalmente en el código ensamblador, pero si prefiere proporcionar una respuesta en C, también está bien.
@Olaf He agregado mi idea de cómo creo que se supone que se debe usar el ADC.
Creo que la idea básica es correcta. Pero como todavía no he trabajado con ese dispositivo en particular o ADC10, no estoy seguro. Sólo inténtalo. El tiempo depende del reloj del sistema. No olvide configurar el PIN correctamente (IIRC, MSP430 necesita pasivar las entradas analógicas del circuito digital, debe haber un registro para el puerto).
@Olaf ¿Qué pasa con las partes de las que no tengo idea?
Tuve que leerme a mí mismo y profundizar más en esto de lo que realmente quiero en este momento; para ser honesto (¡por favor (!) comprenda, tengo mi propio gran proyecto). Por ahora, trato de darte consejos. Estoy bastante seguro de que hay algunas notas de aplicación de TI. ¿Has revisado microcontroller.net? Es posible que puedan proporcionar más ayuda. Al menos es un foro y más adecuado que SO.
Los bits se describen bastante bien en el FUG.
@Olaf Bien, creo que tengo una idea de qué completar para las configuraciones restantes. Realmente me gustaría saber si todo esto es correcto porque es bastante difícil probar esto en un programa, ya que no tengo forma de generar ningún dato mientras el programa se está ejecutando (no quedan pines para UART) y no puedo con precisión probar el tiempo cuando el depurador se está ejecutando. Solo quiero que alguien diga "Jepp, esto es correcto" en este punto.
Ok, REFBURSTdepende de la administración de energía. MSCno importa si no es modo múltiple/secuencia. SHSx depende de su disparador de muestra. Si inicia manualmente, establezca en 0 (bit ADC10SC). Por lo demás, realmente debe verificar la configuración de su hardware. El tiempo depende de qué reloj, frecuencia, etc. Normalmente, comenzaría con la configuración básica, luego usaría periféricos, etc.
Puede obtener la salida cambiando un período de temporizador y conectando un piezoeléctrico simple (sin electrónica integrada) a una salida de temporizador (con un transistor-inversor simple, no conecte directamente: alto voltaje (o use una resistencia en serie más diodo zehner). Simplemente pregúntele a alguien en la HU o a un amigo con experiencia en electrotecnia si se siente perdido al respecto.
@Olaf, por supuesto, puedo dejar que un LED parpadee o algo así, pero no puedo estar seguro de esta manera si la salida es correcta (puede ser que siempre esté leyendo la salida de la última vez o algo así). Creo REFBURSTque no es necesario ya que no estoy usando el generador de voltaje de referencia.
El LED no es bueno para eso, ya que el rango dinámico es demasiado pequeño. Tus oídos pueden rastrear un rango mucho más grande. También puede usar un contador de frecuencia (algunos multímetros tienen uno), que incluso podría dar una lectura bastante precisa. Para que alguien diga "¡funciona!" él necesitaría tener el mismo hardware y escribir el código para usted en realidad...
@Olaf Aún así, esto no me dirá si estoy leyendo accidentalmente el último resultado o si hay algún Heisenbug. Prefiero saber si estoy haciendo las cosas bien en lugar de decir “parece que funciona”, por eso hago esta pregunta.
Principalmente porque "parece que funciona", dejar de fumar a menudo significa "no, no funciona, pero no lo verá fallar hasta que sea demasiado tarde".
"...siempre leyendo la salida de la última vez..." bueno, si ves un cambio al girar el potenciómetro, eso me parece bastante correcto. De lo contrario, necesitaría un osciloscopio más un generador de señal para rastrear la entrada y la salida, esperando un retraso (casi) constante para la entrada rectangular a la salida.
@Olaf También veré cambios si siempre veo el penúltimo cambio. Realmente me gustaría estar seguro. Esto no me lleva a ninguna parte sin alguien que pueda decir "sí, lo estás haciendo bien". (O de otra forma).
"... Realmente me gustaría estar seguro..." ¡Bienvenido al maravilloso mundo de la programación de sistemas integrados bare-metal de bajo costo!
He intentado usar GRACE de TI.
Esta pregunta se adapta al sitio Embedded System SE. ¿Puede volver a publicar esta pregunta allí?
@prasad ¿Qué es eso? ¿Es posible migrar mi pregunta?
@prasad ¿Estás seguro de que no pertenece aquí? Encuentro muchas preguntas similares en este sitio.
Sí, tiene usted razón. Pero hay preguntas superpuestas. Y al ser un firmware relacionado, pertenece al sitio Embedded System SE.

Respuestas (1)

Su configuración parece correcta. Sin embargo, tengo la sensación de que no estás seguro acerca del cronometraje.

En su secuencia de muestreo, manténgalo ADC10ONen 0 hasta que el resto de los registros estén configurados. Luego, cuando esté esperando para tomar muestras, no espere un número específico de ciclos. En su lugar, sondee ADC10BUSYhasta que sea 0.

Los 64 relojes a los que se hace referencia en la configuración de tiempo de muestra y retención ADC10SHTxno son relojes de CPU (MCLK); son relojes relativos a cualquier fuente de reloj que seleccione con la ADC10SSELxconfiguración, divididos por el ADC10DIVxvalor.

Con su configuración actual, su ADC se ejecuta desde el ADC10OSC(oscilador interno de ADC) que funciona a aproximadamente 5 MHz, y está dividiendo ese reloj por 1. Su tiempo de muestra está configurado en 64 relojes, o 12,8 µs. Puede multiplicar este tiempo de muestra por 2, 4 u 8 dividiendo el reloj por el mismo valor.

El tiempo de muestra que necesita depende de su hardware, específicamente, cuánto tiempo le tomaría a su fuente de voltaje llenar un capacitor en particular. Si no espera lo suficiente, aún obtendrá una lectura, pero será incorrecta. La Guía del usuario de la familia MSP430 tiene más detalles. Sin embargo, la configuración "simplemente haz que funcione; tengo todo el tiempo del mundo" sería usar la fuente ACLK (12 kHz, suponiendo que ACLK se obtenga internamente del VLO) dividido por 8 (= 1,5 kHz) con 64 muestras de reloj. durante un tiempo de muestra de 42 ms. En realidad, tomará 77 relojes como calculó anteriormente, por lo que la lectura tardará aproximadamente 51 ms en completarse. Esto es realmente lento y exagerado, pero no es un mal punto de partida para sintonizar.

Gracias por tu comentario. Probé la configuración descrita anteriormente (sin embargo, sondeé ADC10BUSYen lugar de esperar) con un reloj de 512 Hz (oscilador externo de 32768 Hz dividido por 64) y parece funcionar hasta ahora. Gracias por tu respuesta, me ayuda.