En esta práctica aprenderemos a utilizar el protocolo I2C para obtener información de un acelerómetro y encender los leds de la barra de leds correspondientes a la inclinación del mismo.
Para usar este protocolo es necesario que definamos lo siguiente:
#use I2C(MASTER, SCL=PIN_A1, SDA=PIN_A2) //Configuración del I2C
En la parte de configuración tenemos que definir en que pines estará conectado nuestro dispositivo, en este caso el pin SCL está en el pin A1 y el pin SDA en el A2.
Para poder comunicarnos con los dispositivos I2C haremos uso de las siguientes funciones:
i2c_start(); //Envía la condición de inicio i2c_write(0x3A); //Envía información y = i2c_read(0); //Recibe información y la almacena en y i2c_stop(); //Envía la condición de paro
Los pasos necesarios para establecer comunicación por medio de este protocolo son los siguientes:
Envío de información
1. Enviar condición de inicio
2. Enviar dirección esclava de escritura
3. Enviar registro al que se va a escribir
4. Enviar el dato que se va a escribir
5. Enviar condición de paro
i2c_start(); i2c_write(DIR_ESCLAVO_W); i2c_write(registro); i2c_write(dato); i2c_stop();
Recepción de información
1. Enviar condición de incio
2. Enviar dirección esclava de escritura
3. Registro que se va a leer
4. Condición de inicio
5. Enviar dirección esclava de lectura
6. Recibe información del registro
7. Condición de paro
i2c_start(); i2c_write(DIR_ESCLAVO_W); i2c_write(registro); i2c_start(); i2c_write(DIR_ESCLAVO_R); y = i2c_read(0); i2c_stop();
Es conveniente que definamos una función para escritura que realice todo el proceso para no repetir tantas líneas y lo mismo para la lectura. Quedando de la siguiente forma:
void escritura(unsigned int registro, unsigned int dato){ i2c_start(); i2c_write(DIR_ESCLAVO_W); i2c_write(registro); i2c_write(dato); i2c_stop(); } int lectura(unsigned int registro){ int y; i2c_start(); i2c_write(DIR_ESCLAVO_W); i2c_write(registro); i2c_start(); i2c_write(DIR_ESCLAVO_R); y = i2c_read(0); i2c_stop(); return y; }
De esta forma podremos crear otra función que sirva para inicializar el módulo del acelerómetro, enviando la información correspondiente a cada registro del mismo, de la siguiente forma:
void acel_init(){ //Inicialización del módulo del acelerómetro escritura_acel(0x0B, 0x01); escritura_acel(0x2A, 0x20); escritura_acel(0x2B, 0x19); escritura_acel(0x2C, 0x02); escritura_acel(0x2D, 0x01); escritura_acel(0x2E, 0x01); escritura_acel(0x2A, 0x21); }
En el datasheet del acelerómetro podemos encontrar por que se pusieron esos valores en los registros.
Para esta práctica vamos a estar leyendo continuamente el registro 0x03 el cual contiene el valor del eje y del acelerómetro, después de leer ese registro lo compararemos con valores entre -20 y 20 para definir cual led se tendrá que encender, según la siguiente imagen:
Imagen 1. Intervalos de encendido de cada led