lunes, 25 de mayo de 2015

MSP430: DMA + LM35 + MSP430FR5739

Este capítulo volveremos a usar la placa de desarrollo MSP430-EXP430FR5739 de la empresa Texas Instruments. Dicha placa de desarrollo contiene el microcontrolador MSP430FR5739 cuya novedad es la memoria interna, ya que es del tipo FRAM.

La memoria o tecnología FRAM presenta ciertas ventajas a la inmunidad al ruido y a la escritura en memoria. Pero no debemos asustarnos, los periféricos se trabajan de forma similar a cualquier microcontrolador de la familia MSP430.

El hecho de usar esta placa de desarrollo es que el microcontrolador presente: MSP430FR5739, contiene el módulo DMA ( Direct Memory Address ) y de ese periférico concreto, va a tratar este capítulo.

Para aquellos que todavía no hayáis empleado el módulo DMA en vuestros proyectos, deciros que una vez que lo sepáis controlar, será un aliado que siempre usaréis, y esto es así ya que reduce el código de programa considerablemente y lo mejor de todo, nuestro microcontrolador, su CPU, estará en modo bajo consumo mientras el módulo DMA trabaja a sus anchas, maximizándose de esta forma el ahorro de energía.

Quizás me haya emocionado un poquito cuando he dicho eso de que será un aliado que siempre usaréis, lo admito, pero vamos con un ejemplo teórico que mostrará que mi afirmación no va muy mal encaminada.

[ Ejemplo ] Imaginemos que tenemos un vector con cinco datos de temperatura procedentes de un sensor externo y que queremos transmitirlos por la UART, bien, la forma ( vamos a llamarla tradicional ) de proceder sería algo como cargar el primer dato a transmitir en el registro de la UART y esperar a que el flag asociado al registro nos avise de que ya ha finalizado la transmisión del dato, posteriormente se cargaría el segundo dato en el registro y el procedimiento sería el mismo hasta haber enviado todos los datos del vector por la UART.

Dicho procedimiento de transmitir el vector de datos de temperaturas por la UART se podría gestionar mediante interrupciones para adecuar el siguiente dato a transmitir. En dicha interrupción, la CPU del microcontrolador saldrá de su estado de bajo consumo.

Pero, ¿qué pasaría si usamos el módulo DMA? Bien, el DMA se compone de canales que podremos usarlos para conectar porciones de memoria ( incluso registros del propio microcontrolador ), así que respondiendo a la pregunta, deberíamos configurar un canal y asociar su dirección de fuente a nuestro vector con los datos de temperatura y, asociar el destino al registro de transmisión de datos de la UART.

El siguiente paso será decirle al módulo DMA cuantos datos va a manejar, en nuestro caso, cinco datos que corresponden al número de datos de temperatura que tenemos almacenado en un vector. Y ahora, solo nos queda asociar como el módulo DMA gestionará dichos datos.

En este ejemplo teórico, el objetivo es transmitir por la UART cierto número de datos alojados en un vector, por lo tanto, la manera de proceder del DMA será saber cuando un dato ya haya sido transmitido, así que asociaremos el evento de la UART ( flag  UCxTXIFG ) de paquete transmitido al módulo DMA.

De esta forma, cuando se haya transmitido un paquete por la UART, el flag UCxTXIFG se activará y el módulo DMA pondrá otro paquete para que sea transmitido, así hasta los cinco elementos que hemos configurado, y todo esto, con el microcontrolador en bajo consumo.

Para terminar este ejemplo teórico, decir que por supuesto, se puede activar el servicio de interrupción de cualquier canal del módulo DMA para que nos indique cuando se haya transmitido todos los paquetes.


Y bien, hasta aquí el ejemplo teórico ( espero haber podido transmitir la idea de lo práctico que resulta el módulo DMA ), ahora vamos con el ejemplo práctico de éste capítulo, el programa que vamos a presentar consistirá en realizar tres lecturas consecutivas del sensor externo de temperatura LM35, almacenar dichos valores en un vector y cuando se obtengan dichas lecturas, transmitirlas por el puerto serie usando la UART para que una interfaz gráfica pueda realizar la media de dichos valores y exponer su valor por pantalla, todo ello mediante el módulo DMA.

La forma de proceder será la siguiente, primero emplearemos el Timer A0  para que realice una interrupción cada tres segundos, donde se activará el conversor analógico-digital para realizar las tres lecturas consecutivas del sensor externo de temperatura LM35.

Pero previamente a que el Timer A0 entre en acción, habremos configurado dos canales del módulo DMA para gestionar todo el proceso, el primer canal ( canal 0 ), se le asociará al módulo ADC10 ( fuente ), de tal manera que cada vez que haya un dato en el registro ADC10MEM0, el DMA realizará una lectura y almacenará su contenido en un vector ( destino ), así hasta realizar las tres lecturas consecutivas.

Una vez tengamos las tres lecturas almacenadas en el vector, se producirá una interrupción del módulo DMA ( canal 0 ) donde procederemos a activar el segundo canal del DMA ( canal 1 ). Dicho canal 1, estará asociado al vector de datos de temperaturas ( fuente ) con el registro de transmisión del módulo UART ( destino ), de tal manera que el canal 1 del DMA, gestionará la transmisión de datos a través de la UART.

Una vez transmitido todos los datos, se producirá una interrupción del módulo DMA en el canal 1, donde se volverá a activar el Timer A0 para volver a empezar el proceso.


Y para hacerlo más vistoso, dicha comunicación serie será a través de un par de módulos XBee de forma inalámbrica.



El material que vamos a necesitar y su función, es la que se muestra a continuación:

· MSP430 Launchpad FRAM: Evidentemente, nuestra placa de desarrollo con el microcontrolador MSP430FR5739.

· Módulos XBee: Un par de ellos, en este caso, el módulo XBee es el modelo: XB24-ZB.

· LM35: Dispositivo de temperatura analógico.

· Interfaz Gráfica: Software que se ejecuta en un ordenador con independencia del sistema operativo, solo es necesario tener instalada la máquina virtual de JAVA con al menos, la versión 7 Update 45 o superior. Dicha interfaz gráfica se puede descargar más adelante junto al Firmware..


El código del programa principal, es el siguiente:

/**
* @file       main.c
* @author     Manuel Caballero
* @date       11/5/2015
* @brief      Archivo principal.
* \copyright
*      AqueronteBlog@gmail.com
*
* Este archivo es propiedad intelectual del blog Aqueronte,
* cuya dirección web, es la siguiente:
*
*    http://unbarquero.blogspot.com/
*
* Se permite cualquier modificación del archivo siempre y cuando
* se mantenga la autoria del autor.
*/

#include < msp430.h >
#include < stdint.h >
#include "variables.h"
#include "funciones.h"
#include "interrupciones.h"



/**
 *  \brief     void main( void )
 *  \details   Vamos a trabajar con la placa de desarrollo MSP-EXP430FR5739.
 *
 *             Este programa consiste en realizar tres lecturas consecutivas de datos del sensor externo
 *             de temperatura LM35 cada, aproximadamente 3 segundos, para posteriormente, mandarlas
 *             por la UART.
 *
 *             Pero en este caso, tanto la lectura de los tres valores del ADC10_B como la transferencia
 *             de datos, se realizará por el módulo DMA.
 *
 *             Se asignará dos canales DMA:
 *
 *                · Canal 0: Lectura del resultado del módulo ADC10_B.
 *                · Canal 1: Tranmitir dichos datos por la UART.
 *
 *
 *             Se envían al ordenador por medio de un par de dispositivos XBee usando la UART.
 *
 *             El resto del tiempo, el MCU permanecerá en estado bajo consumo LPM3.
 *
 *
 *  \author    Manuel Caballero
 *  \version   0.0
 *  \date      11/5/2015
 *  \pre       Se utilizarán un par de módulos XBee XB24-ZB ( uno Coordinator y el otro End Device )
 *             a 115200 Baudios.
 *  \pre       El software de ordenador utilizado es el llamado UART1_SW, proporcionado con todos los
 *             archivos necesarios del éste proyecto.
 *  \pre       Code Composer Studio, Version: 6.0.1.00104.
 *  \pre       C Compiler, MSP430 GCC GNU v4.9.1 ( Red Hat ).
 */
void main( void )
{
   conf_WDT    ();           // Configura WDT del sistema
   conf_CLK    ();           // Configura CLK del sistema
   conf_IO     ();           // Configura Entradas/Salidas
   conf_ADC10  ();           // Configura ADC10
   conf_UART   ();           // Configura UART
   conf_TA0    ();           // Configura Timer A0
   conf_DMA    ();           // Configura DMA

   __enable_interrupt();     // Interrupciones ON.


   while(1)
   {
      LPM3;
      // __nop();            // Solo para DEBUG
   }
}

Como vemos, el ejemplo es bastante simple, se recomienda bajar los archivos disponibles más abajo para indagar entre sus librerías y leer sus funciones de manera más detallada.

Un vídeo que demuestra lo explicado anteriormente se presenta a continuación:



Os pongo a vuestra disposición el programa en lenguaje C (IAR y MSPGCC) para que lo podáis descargar y probar:

MSP430FR5739: LM35 + ADC10 + UART + DMA
Compilador IARCompilador MSPGCC
CC
MSP430FR5739: LM35 + DMA
MSP430FR5739: LM35 + DMA
MSP430FR5739: LM35 + DMA
MSP430FR5739: LM35 + DMA


Podéis encontrar el código completo en nuestro repositorio GitHub:

·AqueronteBlog GitHub.


· NOTA 1: En caso de ejecutar el software UART.jar y no inicializarse, es debido a que las librerías no están instaladas debidamente. El software utiliza librerías externas como por ejemplo, para el manejo del puerto serie, dicha librería debe instalarse a mano. En el siguiente enlace hay una breve guía de como hacerlo: Instalar librerías RXTX.

0 comentarios: