PIC16F88 y acelerómetro MMA7660

Hola, estoy haciendo una comunicación con el acelerómetro de freescale MMA7660 y el PIC16F88, uso el compilador CCS pero al parecer el acelerómetro no responde o no lo estoy configurando bien, el PIC y el acelerómetro ambos son alimentados a 3V, el PIC trabaja a 4MHz. Podrían darme una ayudita? Es algo urgente y no logro hacer que funcione, ya lei las notas de aplicacion y use dos configuraciones diferentes pero ninguna con resultados satisfactorios. La idea es configurarlo para que provoque la interrupción por un movimiento de cualquiera de sus ejes. Les dejo los codigos que use para la comunicacion:

Código:
#use delay(clock=4M, restart_wdt)
#fuses XT , WDT, NOPROTECT, NOMCLR, NOBROWNOUT, NOFCMEN
#use I2C (MASTER, SLOW, SCL=PIN_B7, SDA=PIN_B6, FORCE_SW, NOFLOAT_HIGH, RESTART_WDT)
#use fast_io(B)
#define DIR_MMA7660  0x4C                                                        //direccion I2C del acelerometro
#define I2C_ESCRIBIR 0                                                           //modo escritura i2C
..............................
set_tris_b(0b00000111);
..............................
i2c_start();
I2C = i2c_write(DIR_MMA7660|I2C_ESCRIBIR);
I2C = i2c_write(0x07);
I2C = i2c_write(1);

i2c_stop();
i2c_start();
I2C = i2c_write(DIR_MMA7660|I2C_ESCRIBIR);
I2C = i2c_write(0x08);
I2C = i2c_write(0b011);
i2c_stop();

El otro codigo:

Código:
#use delay(clock=4M, restart_wdt)
#fuses XT , WDT, NOPROTECT, NOMCLR, NOBROWNOUT, NOFCMEN
#use I2C (MASTER, SLOW, SCL=PIN_B7, SDA=PIN_B6, FORCE_SW, RESTART_WDT)
#use fast_io(B)
#define DIR_MMA7660  0x4C                                                        //direccion I2C del acelerometro
#define I2C_ESCRIBIR 1                                                           //modo escritura i2C
...............................
set_tris_b(0b00000111);
..............................
RESTART_WDT();

i2c_start();                                                                     //configuracion de los registros
i2c_write(DIR_MMA7660 | I2C_ESCRIBIR);                                           //direccion del acelerometro y modo escritura
i2c_write(0x07);                                                                 //registro MODE
i2c_write(0x00);                                                                 //acelerometro en stand-by
i2c_stop();

i2c_start();
i2c_write(DIR_MMA7660 | I2C_ESCRIBIR);                                           //direccion del acelerometro y modo escritura
i2c_write(0x05);                                                                 //registro SPCNT
i2c_write(0x00);                                                                 //sin sleep-count  
i2c_stop();

RESTART_WDT();

i2c_start();
i2c_write(DIR_MMA7660 | I2C_ESCRIBIR);                                           //direccion del acelerometro y modo escritura
i2c_write(0x06);                                                                 //registro INTSU
i2c_write(0x03);                                                                 //interrupcion solo por movimientos sobre X,Y,Z
i2c_stop();

i2c_start();
i2c_write(DIR_MMA7660 | I2C_ESCRIBIR);                                           //direccion del acelerometro y modo escritura         
i2c_write(0x09);                                                                 //registro PDET
i2c_write(0xE0);                                                                 //sin tap-detection
i2c_stop();

RESTART_WDT();

i2c_start();
i2c_write(DIR_MMA7660 | I2C_ESCRIBIR);                                           //direccion del acelerometro y modo escritura
i2c_write(0x08);                                                                 //registro SR
i2c_write(0x34);                                                                 //8 muestras por segundo, TILT debounce filter = 2
i2c_stop();

i2c_start();
i2c_write(DIR_MMA7660 | I2C_ESCRIBIR);                                           //direccion del acelerometro y modo escritura
i2c_write(0x0A);                                                                 //registro PD
i2c_write(0x00);                                                                 //No tap detection debounce count enabled
i2c_stop();

RESTART_WDT();

i2c_start();                                                                     //configuracion de los registros
i2c_write(DIR_MMA7660 | I2C_ESCRIBIR);                                           //direccion del acelerometro y modo escritura
i2c_write(0x07);                                                                 //registro MODE
i2c_write(0xC1);                                                                 //interrupcion por flanco de bajada, pin INT es push-pull
                                                                                 //no auto-sleep, no auto-wake, modo activo
i2c_stop();

Saludos y espero puedan ayudarme!
 
Te hago una preguntita dragondgold. Soldaste vos mismo el integrado? Porq yo tengo aca unas muestras, pero son tan pequeñas que no se como voy a hacer para fabricar las plaquitas y soldarlo :S como hiciste??
Gracias y saludos!!!
 
Sisi, conozco ese metodo. Es mas, he soldado varios mma7260, pero el mma7660 es mucho mas pequeño :S encima no consigo las librerias del eagle para hacer la pcb.
En fin, veo q en el foro todopic solucionaste tu problema, yo soy "gera" en ese foro. Si consigo soldarlo y hacerlo funcionar lo estare posteando.
Gracias por tu respuesta, saludos!! :)
 
También puedes mandarlo a soldar a Electrocomponentes o averiguar sobre algún lado que hagan soldado de SMT. La verdad no pude hacer andar el acelerometro todavia y estoy desesperado ya no se que pueda ser, si logras hacerlo funcionar te agradeceria muchisimo que postearas aqui como hiciste.

Muchas gracias y saludos!!!
 
Yo estoy renegando con el mismo acelerometro MMA7660 pero con un atemega lo estoy programando... el unico problema que tengo es la lectura del mismo, pero te dejo una especie de pseudo codigo para que puedas entender como inicializarlo y como leerlo (segun lo que entendi, pero de esta forma me lee un solo dato asi que estoy investigando un poco mas).

Código:
Inicializarlo:
1.- Empezar la conexion con el esclavo 
2.- Direccion del registro que vas a configurar
3.- Dato con lo que lo vas a configurar 
4.- Terminar la comunicacion

Esto lo tenes que repetir para cada uno delos registros que quieras configurar desde el 0x03 al 0x0A. Osea que si queres configurar los samples por segundo. primero vas a tener que configurar el MMA7660 en "mode" "stand by" despues los samples y por ultimo lo pones en "mode" "active" 

Por ejemplo configurar en modo activo:

1.- Inicio de la comunicacion
2.- 0x07
3.- 0x01
4.- Fin de la conexion

Y Para leer por lo que yo tengo entendido la secuencia es:

1.- Inicio de transmicion
2.- Posicionarse en el registro que queremos leer(0x00 , 0x01 , 0x02 para los ejes X Y Z respectivamente)
3.- Fin de la conexion 
4.- Leer de la direccion del esclavo 
5.- Recibir y guardar el dato.

Esto lo que yo tengo entendido, de esta forma puedo escribir bien en el dispositivo pero tengo problemas para leerlo(leo simepre el mismo data que es el eje Z)

PD: yo solde el integrado a mano con una punta de soldador bien fina y lupa de 7x

Salu2
 
Haaa gran detalle el de poner el acelerometro en modo stand-by, ya lo voy a probar a ver que tal. Para leer el acelerometro segun la hoja de datos se hace asi:

1- Inicio la transmicion
2- Direccion del acelerometro con el ultimo bit para escribir (0x98)
3- Direccion del registro a leer
4- Inicio de transmicion nuevamente (start repetido)
5- Direccion del acelerometro con el ultimo bit para leer (0x99)
6- Leer dato
7- Fin de transmicion

PD: para poner el acelerometro en modo stand-by debo poner el registro MODE todo en 0 verdad?
 
Haaa gran detalle el de poner el acelerometro en modo stand-by, ya lo voy a probar a ver que tal. Para leer el acelerometro segun la hoja de datos se hace asi:

1- Inicio la transmicion
2- Direccion del acelerometro con el ultimo bit para escribir (0x98)
3- Direccion del registro a leer
4- Inicio de transmicion nuevamente (start repetido)
5- Direccion del acelerometro con el ultimo bit para leer (0x99)
6- Leer dato
7- Fin de transmicion

PD: para poner el acelerometro en modo stand-by debo poner el registro MODE todo en 0 verdad?

Sisi, para poner el acelerometro en stand by tenes que poner el registro mode en 0x00

PD: Lo logre hacer andar para mi arduino, cualquier cosa consultame.
 
Encerio?? Yo pude configurarlo pero no se como leer los registros de los ejes, siempre lee 0 en el eje por mas que lo mueva, y configurando la interrupción siempre queda en un nivel fijo nunca salta. Si la pongo para que se active en estado alto queda siempre en alto y viceversa. Cualquier ayuda que puedas darme te lo agradeceria :D

Saludoooos
 
Encerio?? Yo pude configurarlo pero no se como leer los registros de los ejes, siempre lee 0 en el eje por mas que lo mueva, y configurando la interrupción siempre queda en un nivel fijo nunca salta. Si la pongo para que se active en estado alto queda siempre en alto y viceversa. Cualquier ayuda que puedas darme te lo agradeceria :D

Saludoooos

che capo aca te de jo el codigo que uso nocturno para leerlo...
Código:
 void InicializaMMA7660() {
    i2c_start();
    i2c_write(DIR_MMA7660|I2C_ESCRIBIR);
    i2c_write(RegMode);
    i2c_write(1);   // Lo configuramos en modo Activo
    i2c_stop();
    
    i2c_start();
    i2c_write(DIR_MMA7660|I2C_ESCRIBIR);
    i2c_write(RegSR);
    i2c_write(0b011);// Lo configuramos para 32 samples por segundo
    i2c_stop();
    
 }
 void LecturaMMA7660() {
    i2c_start();
    i2c_write(DIR_MMA7660|I2C_ESCRIBIR);
    i2c_write(RegX);      // Señalamos el registro X como primero a  leer
    i2c_start();
    i2c_write(DIR_MMA7660|I2C_LEER);
    EjeX=i2c_read(1);   // Leemos RegX
    EjeY=i2c_read(1);   // Leemos RegY
    EjeZ=i2c_read(0);   // Leemos RegZ
    i2c_stop();
 }
Espero te sirva... y sino... postea tus dudas aca http://forums.freescale.com/t5/8-Bit-Microcontrollers/Problems-with-MMA7660/m-p/54971 y te van a contestar al toque...

PD: Si el valor que te lee es 0 en todos los ejes, quiere decir que el acelerometro esta en stand by...

Salu2
 
Te hago una consulta. Veo que lo esta configurando sin ponerlo en modo Stand-by, es correcto? Me podrias pasar como hiciste vos ? Por lo menos los pasos como hiciste unos post anteriores es urgente :S

Muchas gracias voy a probar este codigo a ver que tal!!

Lo hice andar!! Muchisimas gracias emma no tenes idea cuanto me has ayudado :):):):) !!!!!

Saludooooooooos
 
Última edición:
Muy bien ahi che... me alegro que te haya servido. Tengo una duda el proyecto ese es para la facultad mas especificamente para Informatica II??

Salu2
 
dragondgold, podrías subir el codigo del 7660??? tambien tengo unos cuantos y quiero probarlo. puedes subir el codigo que hiciste funcionar?

Saludos.
 
Hola gonpa! El código esta escrito para el compilador CCS, este es el codigo para iniciar el acelerómetro:

Código:
//Configuración del acelerómetro
mma7660_mode(0b00000000);  //acelerometro en stand-by para la escritura de los registros
mma7660_spcnt(0b00000000); //sin sleep-count
mma7660_intsu(0b00000000); //sin interrupciones de ningún tipo
mma7660_pdet(0b11100000);  //sin tap-detection
mma7660_sr(0b00010100);    //32 muestras por segundo, sin TILT debounce filter
mma7660_pd(0b00000000);    //No tap detection debounce count enabled
mma7660_srst(0b00000001);  //sample rate especificado en AMSRS
mma7660_mode(0b11000001);  //acelerometro activo, interrupcion activa = 0
delay_ms(30);              //tiempo que demora el acelerometro para pasar de modo sleep a activo

Para leer el valor de los ejes uso esto:

Código:
void leer_eje (){        //lee los 3 ejes del acelerómetro

i2c_start();                  //inicio transmicion I2C                                    
i2c_write(I2C_ESCRIBIR);      //envío la dirección de esclavo con el bit de escritura W
i2c_write(EJEX);              //envío el eje a leer
i2c_start();                  //condición repetida de start
i2c_write(I2C_LEER);          //envío la dirección del esclavo con el bit de lectura R
EJE_X = i2c_read(1);       //leo primer eje, devuelvo ACK
EJE_Y = i2c_read(1);       //leo segundo eje, devuelvo ACK
EJE_Z = i2c_read(0);       //leo tercer eje, no devuelvo ACK (NAK) para indicar que es el ultimo eje q leo
//Nota: no envio a cada rato el nuevo eje que quiero leer porque el acelerómetro
//autoincrementa la dirección cada vez que se lee
i2c_stop();                   //finalizo transmición
}

Te adjunto el archivo MMA7660.c donde estan todas las funciones y declaraciones. Espero te sirva! Saludos!
 

Adjuntos

  • MMA7660.txt
    3.1 KB · Visitas: 33
Hola Amigos. Soy nuevo en el foro.
Estoy montando un proyecto con el MMA7660 y un PIC18F24K22.
Podriais colgar el codigo completo que SI funcione?

Muchisimas gracias de antemano y enhorabuena por el foro!!! :)
 
Atrás
Arriba