Obtención de valores de acelerómetro de MPU 6050

0

Estoy intentando leer los valores del acelerómetro de mpu 6050 en atmega328p (Arduino UNO). Quiero un programa en C incorporado, por eso no quiero usar ninguna biblioteca externa. Así que leí sobre el protocolo I2C, leí la hoja de datos de MPU 6050, registré la hoja de MPU 6050 y desarrollé un código según mi entendimiento. Aquí está el código

#include<avr/io.h>
const int MPU_addr=0x68;
void i2c_init() {
  TWSR=0x00;
  TWBR=0x48;
  TWCR = _BV(TWEN) | _BV(TWIE) | _BV(TWEA);
}

void i2c_start() {
  TWCR=(1<<TWEN)|(1<<TWINT)|(1<<TWSTA);
  while((TWCR&(1<<TWINT))==0);  
}

void i2c_stop() {
  TWCR=(1<<TWEN)|(1<<TWINT)|(1<<TWSTO);
}

void i2c_write(uint8_t data) {
  TWDR=data;
  TWCR=(1<<TWINT)|(1<<TWEN);
  while((TWCR&(1<<TWINT))==0);  
}

uint8_t i2c_read(unsigned char isLast) {
  if(isLast==0) {
    TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA);
  }
  else {
    TWCR=(1<<TWINT)|(1<<TWEN);
  }
   return TWDR;
}

int main() {
  uint16_t i;
  i2c_init();
  i2c_start();
  i2c_write((MPU_addr<<1)|(1<<0));
  i2c_write(0x6B);
  i2c_write(0);
  i2c_stop();
  Serial.begin(9600);
  while(1) {
    i2c_start();
    i2c_write((MPU_addr<<1)|(1<<0));
    i2c_write(0x3B);
    i2c_start();
    i2c_write((MPU_addr<<1)|(0x00));
    i=(i2c_read(0)<<8)|i2c_read(0);
    Serial.println(i,BIN);
  }
return 1;
}

El problema está en el bucle while, el programa se bloquea después de i2c_start (); llamada. He comprobado esto poniendo un Serial.println ("a"); después de esa línea, pero nada se imprime en el monitor de serie. También he comprobado que el programa entra en el bucle while con éxito. Entonces, ¿alguien puede ayudar dónde está el problema en el código?

Nota: 1. Todas las funciones i2c están de acuerdo con el libro "El microcontrolador Avr y el sistema integrado que utiliza el ensamblaje y la C" de Ali Mazidi ".

    
pregunta Aditya Singh

2 respuestas

0

Mirando el datasheet of El 328p (página 297) , parece que estás manejando mal el bit TWINT.

Por la hoja de datos, el bit nunca se borra por el hardware, que es lo que está viendo. Es establecido por el hardware en su lugar.

Al hojear rápidamente el código, lo que podría hacer simplemente sería invertir la lógica en torno al TWINT: borrarlo para que funcione y esperar a que se vuelva a configurar.

    
respondido por el Richard the Spacecat
0

Aprenderás mucho sobre el dispositivo si lo das paso a paso. Pero antes de continuar quita ese bit TWIE. No está utilizando interrupciones en el resto de su código.

Comience leyendo la ID del chip (6 bits en reg 0x75). Cuando lo hagas bien sabrás que tu función de lectura es correcta (debe ser 0x68). Tenga en cuenta que lo que está leyendo ahora en el bucle principal es en realidad la dirección de esclavo completa + bit de lectura (0xD0). Sugerencia: hay que esperar a que los datos vuelvan.

Luego haga la inicialización. Veo que configura la fuente del reloj para el reloj interno. Esto debería funcionar, pero en el futuro recomiendo usar PLL de cualquiera de los giroscopios, es más preciso.

Pero aún no has terminado, debes configurar el rango de escala completo al menos para el acelerómetro (yo también lo configuré para giroscopios).

No estoy 100% seguro, pero creo que la inicialización solo se puede hacer mientras el chip está en modo de suspensión. Al menos en mi propia biblioteca MPU6050 mantengo el dispositivo en reposo después del encendido, realizo todas las configuraciones y solo borro el bit SLEEP.

Finalmente, en la lectura del bucle principal no envía NACK después del segundo byte. Y continúas usando repetidamente Start. Enviaría la condición NACK + Stop al final del bucle e introduciría un retardo al menos correspondiente a la velocidad de datos seleccionada. No tiene sentido leer más rápido, entonces los datos pueden actualizarse.

El mayor problema con su código, sin embargo, es la falta de un manejo adecuado del registro de estado, solo está verificando TWINT. Esto realmente funciona, pero solo en condiciones ideales donde no hay errores y esclavos siempre ACK.

    
respondido por el Maple

Lea otras preguntas en las etiquetas