e-Candies(1). Acelerómetro Digital MMA7455

Miércoles, diciembre 1st, 2010


A long time ago…

Bueno, de vuelta poco a poco.

En esta ocasión vamos a hacer un pequeño repaso a esas “golosinas” que suponen nuestros mini módulos que usamos habitualmente en nuestros montajes previos a una integración total con la PCB final, que reutilizamos mil y una vez y que algunas veces nos dan algún quebradero de cabeza, en especial cuando implementamos algún tipo de chip nuevo con el que vamos a experimentar.

En este primer post, me voy a centrar en el acelerómetro digital MMA7455 de Freescale.
Este es un modelo de acelerómetro 2G/4G/8G que se puede interconectar por SPI o I2C.

Tiene una resolucion de 8 bits y hasta 10 bits en modo 8G.

Es muy fácil de configurar modificando simplemente valores en sus registros internos.

Y los datos también son muy sencillos de leer de los propios registros de los ejes o de configuración.

Dispone de dos interrupciones configurables por el usuario y la posibilidad de setear los registros de los ejes para calibrar el dispositivo.

Se alimenta entre 2,5 – 3,6 vDC y tiene un consumo mínimo en standby de 26uA por uno de max 3mA en funcionamiento.

Es un cacharrito interesante para alimentarlo con una pila tipo coin cell (botón).

He optado por hacer una PCB que pueda servir para usarlo de los dos modos posibles. En el caso del SPI usando SDA/SDO en una sola patilla.

La soldadura, teniendo en cuenta que el encapsulado es LGA-14 no ha sido muy complicada. Eso sí, usando pasta de estaño.

La implementación de las comunicaciones tambien he decidido hacerla por I2C, con lo que en este caso será necesario añadir al circuito 2 resistencias de pull-up de 4k7 ohms entre SDI, SDO y Vcc.

Este es el esquema del circuito, que como podeis ver, no es más que un adaptador a SIL (Single In Line) para poder pinchar en la protoboard:

Y esta la PCB resultante:

Implementación en CCS

La implementación de la comunicación I2C del acelerómetro es bien simple. Sólo hay que configurar en el inicio el modo de funcionamiento del acelerómetro y posteriormente leer los registros de los ejes para obtener los datos de aceleración.
Voy a hacer una configuración básica. Lo voy a configurar con un rango +/-2G y en modo de medición, que es el más habitual.
Abrimos el datasheet del acelerómetro, extraemos las tablas de configuración del registro de control del modo de funcionamiento ($16) y vemos que para seleccionar el modo +/-2G debemos poner los bits GLVL[1:0] a 01:

Y para el modo de funcionamiento de medición, los bits MODE[0:1] hemos de ponerlos a 01:
Con lo cual nuestro dato a escribir en el registro $16 va a ser 0b0000101 (0×05).

Para poder escribir y leer datos en el acelerómetro, necesitamos direccionarlo primero en el bus I2C. El datasheet nos dice que la dirección del dispositivo es $1D (0x1D).

Tenemos que fijarnos ahora en los gráficos de escritura y lectura de 1 byte en el acelerómetro para no cometer un error típico en el manejo de dispositivos serie.

La longitud de la dirección del dispositivo ($1D en nuestro caso) es de 7 bits [6:0], no de ocho, ya que la dirección se desplaza 1 bit hacia la izquierda para añadir en el bit menos significativo el flag de lectura o escritura (W/R):

Para escritura, desplazamos y añadimos un 0:
(0x1D)=00011101 desplazamos 1 bit a la izquierda y le sumamos 0 => 00111010 = 0x3A
Y para lectura, desplazamos y añadimos un 1:
(0x1D)=00011101 desplazamos 1 bit a la izquierda y le sumamos 1 => 00111011 = 0x3B
Con lo que para una escritura, enviaríamos:

  • [Start bit]
  • [0x3A] Device Address + W
  • Esperamos Ack
  • [Registro a escribir]
  • Esperamos Ack
  • [Byte a escribir]
  • Esperamos Ack
  • [STOP bit]

Podeis verlo en el siguiente cronograma, escribiendo 0×05 en el registro de configuración 0×16:

Para la lectura de un registro, el procedimiento será:

  • [Start bit]
  • [0x3A] Device Address + W
  • Esperamos Ack
  • [Registro a escribir]
  • Esperamos Ack
  • [0x3B] Device Address + R
  • [Leemos 8 bits]
  • Enviamos NAck
  • [STOP bit]

Podéis verlo tambien en el siguiente cronograma, leyendo el registro de configuración 0×16 que en este caso ya está cargado con 0×05:


Ya podemos hacer algo interesante con él y este podría ser el código que manejara el MMA7455:

//*****************************************************************
//                            MM7455.c
//
//   Librería para control de acelerómetro Freescale MM7455
//   por bus I2C
//   Author codigo C: Droky
//   Released at 19/09/2010
//
//
//*****************************************************************
// --------------------------------------------
// Definición de BUS I2C
// --------------------------------------------
#use i2c(master,fast,sda=PIN_B5, scl=PIN_B4)

//-----------------------------
//Comprobacion de acelerometro
//-----------------------------
BOOLEAN accel_ready() {
   int1 ack;
   i2c_start();            // Si el comando de escritura recibe ACK
   ack = i2c_write(0x3A);  // el dispositivo está listo.
   i2c_stop();
   return !ack;
}
//------------------------------
// Inicializacion Acelerometro
//------------------------------
void  accel_init(){
   i2c_start();
   i2c_write(0x3A); //0x1D desplazado con un 0
   i2c_write(0x16); //Registro MODE CONTROL
   i2c_write(0x05); //Medición contínua
   i2c_stop();
}
//-----------------------------------
// Escritura 1 registro
//-----------------------------------
void  accel_write(int reg, int data){
   i2c_start();
   i2c_write(0x3A); //0x1D desplazado con un  0
   i2c_write(reg);  //Registro a escribir
   i2c_write(data); //Dato a escribir en registro
   i2c_stop();
}
//-----------------------------------
// Lectura 1 registro
//-----------------------------------
int   accel_read(int reg){
   int   data;
   i2c_start();
   i2c_write(0x3A); //0x1D desplazado con un  0
   i2c_write(reg);  //Registro a leer
   i2c_start();
   i2c_write(0x3B); //0x1D desplazado con un  1
   data=i2c_read(0); //Dato leido->data
   i2c_stop();
   return(data);
}
//----------------------------------
// Lectura de 3 ejes de forma
// consecutiva y almacenado en
// 3 variables globales Xdata,
// Ydata y Zdata
//----------------------------------
void accel_read_3axis(){
   i2c_start();
   i2c_write(0x3A); //0x1D desplazado con un  0
   i2c_write(0x06); //Primer registro a leer (eje X)
   i2c_start();
   i2c_write(0x3B); //0x1D desplazado con un 1
   Xdata=i2c_read(); //Lectura eje X
   Ydata=i2c_read(); //Lectura eje Y
   Zdata=i2c_read(0); //Lectura eje Z
   i2c_stop();
 }

Y esto ha sido todo por ahora.
Nos vemos en la próxima entrega de e-candies. Quizás un conversor serial a Bluetooth para comunicarnos inalámbricamente con nuestro aparatito.
Droky.

Descargas


Copy Protected by Tech Tips's CopyProtect Popup Images .