Libreria I2C en modo esclavo para AVR (TWI)

Hace un rato que uso los microcontroladores AVR para los proyectos en los que me involucro, y la verdad trabajar con el bus i2c ha sido de gran ayuda, ya que me permite conectar distintos dispositivos con casi nada de hardware extra (solo un par de resistencias). Configurar el hardware del AVR para que trabaje en modo master, ha sido estudiado por muchas personas por mucho tiempo y la mejor libreria que he encontrado para este modo la tiene Peter Fleury.

En fin, no siempre podremos hacer todo con el microcontrolador master (a veces ni por mas poderoso que sea) y no siempre encontramos dispositivos esclavos que tengan las funciones que necesitamos. Este ultimo caso en concreto me llevo a desarrollar una librería (todavía muy básica)  para configurar un AVR en modo slave para i2c. Ahora bien, ya hay librerías i2c en modo esclavo para AVR’s, de hecho hay una implementación en la aplication note AVR311, pero a mi se me hace bien tediosa, ademas de que es complicado aplicarla a cada proyecto que desarrollemos.

La libreria que propongo (desarrollada para AVRGCC, pero de fácil portabilidad) trabaja con un principio simple: hacer un buffer de comunicacion entre el master y el slave. Esto es, el slave tendra apartado una seccion de memoria en el cual el master podra escribir y leer en cualquier momento.

Esto facilita la adaptación de la librería para diferentes necesidades, lo único que tiene que hacer el proceso principal del  slave es leer los “comandos” del master en el buffer sin preocuparse de la comunicación i2c, o en su caso escribir las respuestas para el master en le buffer. El master también solo tendrá que leer/escribir en registros/buffer del slave.

Para su uso solo hay una función de inicialización: “i2c_slave_ini()” donde pondremos que dirección tendrá nuestro nuevo slave (esta librería no contempla funciones “general call”, no las necesito por el momento 😛 ), lo demas es hecho en el buffer y la interpretación de cada “registro” dependerá de la aplicación.

La transmisión típica debería ser: primero escribir el registro a leer/escribir, que indicara al driver donde escribir/leer y después hacer la lectura/escritura. El driver recorre automáticamente el puntero al registro a leer. La secuencia de operación es igual que si trabajáramos con una memoria 24LCXX.

****EDITADO***** (18/feb/2014)

En fin, aqui les dejo el archivo de la libreria : i2cslave.zip

****/EDITADO*****

Si quieren saber mas acerca del bus i2c, lean directo el manual del bus, es mas sencillo de leer de lo que parece.

Por cierto, el driver esta basado en el apartado del TWI del manual del ATmega8, pero deberá funcionar con cualquier mega que tenga TWI. 😉

Espero que les sirva. Cualquier bug… no ha de ser difícil que lo resuelvan jajajaja

Cambio y fuera…

Anuncios

17 pensamientos en “Libreria I2C en modo esclavo para AVR (TWI)

    • No, el attiny2313, tiene un modulo USI (Universal Serial Interface) y esta libreria esta hecha para dispositivos que tienen modulo TWI (Two Wire Interface) como el atmega8, atmega16 o atmega32.

      De hecho el primer intento para una libreria de i2c en esclavo que hice, fue para un attiny2313, pero requiere de muchas llamadas de interrupcion por parte del USI, ademas de una respuesta rapida por parte del procesador, ya que si no optimizas bien el software (y mas si trabajas en lenguaje c) no puedes llegar a manejar velocidades aceptables de comunicacion.

      Por la necesidad que tenia de que el procesador trabajar con otras interrupciones (INT0 e INT1) la USI no alcanzaba a responder a tiempo el llamado (y se estancaba el clock y trababa el bus i2c), una solucion fue bajar la velocidad del clock, pero las transferencias de datos eran muy bajas, no supere los 40KHz (el estandar es 100KHz).

      Asi que cuando cambie a un procesador con TWI, se soluciono mi problema, ya que las llamadas de interrupcion por la comunicacion son menos y mas sencillas, permitiendome distribuir mejor la carga de trabajo del procesador.

      Si quieres implementar i2c esclavo en un micro con USI (attiny2313) te aconsejo checar el appnote de atmel AVR312 (solo googlea AVR312 y sale luego luego 😉 )

  1. Muchas gracias por compartir el código. Tengo una duda:
    ¿No es necesario configurar la velocidad del bus I2C, en la función i2c_slave_ini ?
    ¿Lo acuerda de alguna forma, el hardware, con el Master? ¿A qué velocidad trabaja este código?

    • No es necesario configurar la velocidad de operacion, ya que el master es quien controla la velocidad (controla la señal de SCL), el codigo puede trabajar sin problemas en la velocidad estandar (100kHz) con un ATmega8 corriendo a 8MHz y puede llegar sin problemas a los 400kHz, pero es recomendable usar una velocidad de procesador mas alta (cristal externo) para que el procesador pueda atender rapidamente la interrucion del i2c y al programa principal.

      Saludos.

  2. Hola gracias por compartir el codigo.
    Una consulta, necesito código adicional para trabajar como esclavo al atmega? es decir, necesito alguna configuracion adicional al twi? o con la librería ya debería recibir todo en i2c_slave_buffer[]?? gracias de antemano. Saludos.

    • Hola, con esta libreria es sificiente para el modo escalvo del i2c. Una vez inicializada, con lo unico que con lo que hay que lidiar es con el i2c_slave_buffer[] 😉 Espero te sea de utilidad. Saludos.

  3. Hola ¿Has probado el programa TWI Master de Peter (Creo es la más usada) y tu libreria TWI Slave en un arreglo de 1 Master y N esclavos? Te pregunto, porque una vez probé una librería TWi Slave que igual utilizaba el ISR para constante comunicación, y al momento de poner más de 1 esclavo toda la comunicación se caia.

    Saludos.

    • He usado el TWI Master de Peter, es muy buena, le hace falta alguna actualizacion (no por funcionamiento, mas bien por actualizarla a las nuevas versiones de compiladores, ya uso codevision). Acerca de mi libreria, la he usado con un master, 2 escalvos (atmega8, 8MHz internos con velocidad i2c a 100kHz) y con un reloj DS1307 (tambien i2c) en el mismo circuito, incluso los esclavos tambien manejaban interrupciones externas (INT0 e INT1) y pude accesar tanto a los 2 “esclavos” como al reloj de tiempo real sin falla.

      Espero te sea de ayuda.

      Saludos

      • Me fue de muchas ayuda te libreria. La acabo de implementar (En una prueba simple), y no se me cayó la comunicación. Anteriormente utilicé la libreria de Martin Junghans (Un alemán). Lo malo es que es para comunicación uno a uno (1Master – 1 Slave). Pero no me había dado cuenta de eso (Puesto que no me había detenido a leer sus comentarios en alemán), puesto que no tenía tus cases de error en los que libera el bus de datos cuando no se le esta hablando a ese esclavo. La otra librería no tenía ese case, solo tiraba toda la comunicación. Hasta el momento, no le veo problemas a tu libreria con multiples esclavos. La simulación la hago en proteus, y solo me muestra los errores internos de los slaves (Tal como los tienes en tus cases). Durante los proximos días la estaré implementando en mi proyecto, espero no tener problema alguno. Lo que si, es que te recomiendo una cosa, usa 2 variables para los buffers. Modifiqué esa parte en tu código y aun funciona muy bien. Cree estas 2:

        static unsigned char i2c_slave_bufferrx[MAX_I2C_BUFFER];
        static unsigned char i2c_slave_buffertx[MAX_I2C_BUFFER];

        Una para recibir y otra para enviar. No se si estoy mal o bien al hacer eso, pero me parece más practico. Cualquier cosa, te consulto despues.

        Saludos.

        PD. Esta genial que aun revises tus posts para contestarle a la gente, muchos los dejan olvidados jeje.

      • Que bueno que te fue util!! 🙂 Por cierto, esta bien lo de los 2 buffers tambien he hecho esa “modificacion”. La “razon” de que lo dejara solo con uno, era que intentaba la “emulacion de una eeprom serial, ya que es uno de los primeros dispositivos con los que uno tiene acceso i2c 😉

        Saludos

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s