Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Bus I2c PDF
Bus I2c PDF
Microcontroladores AVR`s
Elaborado:
Ing. Xavier Flores C
I ♥AVR ´s
BUS I2C
TWI AVR es el módulo para la comunicación serial I2C del microcontrolador AVR,
la comunicación serial I2C se le llama TWI que viene de las siglas en inglés de
interfaz serial a 2 hilos, en la comunicación I2C o TWI se utilizan 2 hilos a lo que
se conoce como bus I2C o en el caso del AVR se le llama bus TWI, a estos hilos se
conectan los dispositivos que se puedan comunicar mediante el protocolo I2C, por
uno de los hilos se enviará una señal de reloj para la sincronización y por el
otro hilo se enviarán o recibirán datos, se pueden conectar varios dispositivos de
los que uno de ellos será el maestro, es el que generará la señal de reloj además
de decidir cuándo se inicia o finaliza la comunicación y si la comunicación
será de recepción o transmisión de datos, los demás dispositivos conectados al
bus I2C se conocen como esclavos, el protocolo I2C es efectiva para distancias
cortas y ampliamente usada para la comunicación entre sensores, rtc, eeprom
y lcds.
Cada uno de los dispositivos tiene una dirección, cuando el maestro necesita
comunicarse con alguno de los esclavos lo hará enviando la dirección del
esclavo a través del bus I2C, cuando el esclavo reciba su dirección podrá
comunicarse con el maestro, el maestro además tiene que enviar un bit mediante el
cual le indica al esclavo si quiere enviarle un dato o quiere recibir un dato del
esclavo, el microcontrolador AVR puede ser utilizado como maestro o como
esclavo en la comunicación serial I2C AVR.
Los pines que se utilizan en la comunicación serial I2C son los nombrados como
SDA serial data y SCL serial clock, el pin SDA es para enviar o recibir los datos,
y el pin SCL es para la señal de reloj, a estos pines se les debe conectar mediante
unas resistencias que pueden ser de 4K7 a la tensión de alimentación del
microcontrolador AVR, o también se puede habilitar las resistencias internas pull up
de estos pines, con lo que ya no se necesita utilizar las resistencias externas para
la comunicación I2C AVR; los pines de los demás dispositivos conectados al bus
I2C también están nombrados como SDA y SCL.
A/D
LCD MCU D/A RTC
SCL
SDA
I ♥AVR ´s
vcc
SDA
SCL
Interfaz del BUS I2C
Dado que las líneas son de “drenaje abierto” o colector abierto, es necesario
proveer un voltaje alto al gate del transistor. Si el voltaje del gate está en bajo,
el transistor no se activará y la correspondiente línea conducirá en alto.
I ♥AVR ´s
FRAMES DE DATOS
Para que los paquetes de datos sean válidos en la línea SDA debe mantenerse en
alto el estado de la línea de SCL, el dato en la línea SDA solo cambiara cuando
pase de alto a bajo el pulso de la línea del SCL.
I ♥AVR ´s
Secuencia START
SDA
SCL
Para finalizar la transmisión la línea SDA cambia de estado bajo a alto mientras la
línea SCL mantiene su estado.
I ♥AVR ´s
Secuencia STOP
SDA
SCL
SDA D7 D6 D5 D4 D3 D2 D1 D0 ACK
SCL 1 2 3 4 5 6 7 8 9
CLOCK STRETCHING
Unas de las características del protocolo I2C es el ensanchamiento del pulso del
reloj, es un tipo de flujo de control. Si la dirección de un dispositivo esclavo no está
lista para procesar más información, éste sufrirá un ensanchamiento en el pulso del
reloj, hasta que esa pueda seguir recibiendo información, por lo tanto se esperara a
que el esclavo libere la línea SCL para poder transferir el siguiente bit.
Diagrama de Tiempo
• Esto continúa hasta esclavo ya no puede recibir datos y no envía el bit ACK.
• Esto es cuando el maestro se da cuenta de que el esclavo se ha vuelto loco (no
aceptar más), y se detiene la transacción (o reiniciar).
Vemos que la transferencia de datos nunca cambia su dirección. Los datos siempre
fluyen de maestro a esclavo, lo que hace que la configuración bastante fácil.
Un ejemplo de este caso sería como realizar operaciones de escritura de página en
un chip de memoria EEPROM.
Caso 2: Esclavo (transmisor) a Maestro (receptor) transferencia de datos.
Ejemplo:
Mostrar como el master escribe el valor 11110000 a un esclavo con dirección
1001101.
Sol.
Las siguientes acciones son desempeñadas por el master:
I ♥AVR ´s
(1) El master pone de alto a bajo el pulso en SDA mientras, SCL está en alto
genera una condición de START para la transmisión.
(2) El master transmite 10011010 dentro del bus. Los primeros sietes bits
(1001101) indican la dirección del esclavo, y el octavo bit indica la operación
de escritura que empezara cuando el maestro escriba el siguiente byte dentro
del esclavo.
(3) El esclavo pone la línea del SDA en bajo para la señal del ACK, y decir que
esta lista para recibir el byte del dato.
(4) Después de recibir el ACK, el master transmite el byte de dato (11110000)
en la línea del SDA (MSB primero)
(5) Cuando el dispositivo esclavo recibe el dato, deja la línea SDA en alto para
la señal NACK. Esto informa al maestro que el esclavo recibió el ultimo byte
del dato y no necesita más.
(6) Después de recibir el NACK, el maestro sabe que no necesita enviar más
información. El master cambia la línea del SDA cuando la línea del SCL en
alto para transmitir la condición de parada y liberar el bus para otra función.
I ♥AVR ´s
Para programar la comunicación serial I2C AVR se recomienda mucho leer la hoja
de datos del AVR utilizado, es lo mejor que se puede hacer, como referencia se verá
para el ATMEGA328p, para lo que se utilizan los siguientes registros: el registro
TWBR, el registro TWCR, el registro TWSR, el registro TWDR, el registro TWAR, y
el registro TWAMR.
TWBR=((8000000/400000)-16)/(2*1)
de donde:
TWBR=2
Por lo que para obtener una velocidad de 400Khz se tendrá que cargar el registro
TWBR con 2.
El registro TWCR este es el registro de control del módulo TWI para la comunicación
I2C AVR
también se encuentran los bits mediante los cuales se elige el prescaler para
obtener la velocidad de la comunicación I2C AVR.
Si las combinaciones de estos bits es por ejemplo 0x08 quiere decir que se ha dado
el inicio de la comunicación I2C AVR, las combinaciones de estos bits son utilizadas
dentro del programa para verificar que la comunicación transcurre con normalidad.
El bit2 no se utiliza se pone a 0.
I ♥AVR ´s
Los bits 1 y 0 con las combinaciones de estos bits se elige el prescaler a utilizar
para obtener la frecuencia de transmisión, de donde se obtiene el valor a cargar en
el registro TWBR, las combinaciones son las siguientes:
El primer paso en una transmisión TWI es transmitir una condición START. Esto se
realiza escribiendo un valor específico en TWCR, instruyendo al hardware TWI para
transmitir una condición de START. El valor que debe escribir se describe más
adelante. Sin embargo, es importante que el bit TWINT se establezca en el valor
escrito. Escribir un uno a cero la bandera TWINT. El TWI no se iniciará ninguna
operación, siempre que el bit TWINT en TWCR se establece.
Inmediatamente después de la aplicación se ha aclarado TWINT, el TWI iniciar la
transmisión de la condición de START.
2. Cuando la condición de START ha sido transmitido, la Bandera TWINT en TWCR
se fija, y TWSR se actualiza con un código de estado que indica que la condición
de arranque se ha enviado correctamente.
3. El software de aplicación debe ahora examinar el valor de TWSR, para
asegurarse de que la condición de START se transmitió con éxito. Si TWSR indica
lo contrario, el software de aplicación pudiera tomar ciertas medidas especiales,
como llamar a una rutina de error. Suponiendo que el código de estado es como se
esperaba, la aplicación debe cargar SLA + W en TWDR. Recuerde que TWDR se
utiliza tanto para la dirección y los datos. Después TWDR ha cargado con la
deseada SLA + W, un valor específico se debe escribir en TWCR, instruyendo el
hardware TWI para transmitir el SLA + W presente en TWDR. El valor que debe
escribir se describe más adelante. Sin embargo, es importante que el bit TWINT se
establece en el valor escrito. Escribir un uno a cero la bandera TWINT. El TWI no
iniciará ninguna operación tanto como el bit TWINT en TWCR es cambiado
inmediatamente después de la aplicación se ha aclarado TWINT, el TWI inicia la
transmisión del paquete de direcciones.
4. Cuando el paquete de dirección se ha transmitido, la Bandera TWINT en TWCR
se fija, y TWSR se actualiza con un código de estado que indica la dirección de
paquetes que se ha enviado satisfactoriamente. El código de estado también
reflejará si un esclavo reconoce el paquete o no.
5. El software de aplicación debe ahora examinar el valor de TWSR, para
asegurarse de que el paquete de dirección se ha transmitido correctamente, y que
I ♥AVR ´s
el valor del ACK fue como se esperaba. Si TWSR indica lo contrario, el software de
aplicación pudiera tomar ciertas medidas especiales, como llamar a una rutina de
error. Suponiendo que el código de estado es como se esperaba, la aplicación debe
cargar un paquete de datos en TWDR. Posteriormente, un valor específico se debe
escribir en TWCR, instruyendo el hardware TWI para transmitir el paquete de datos
presente en TWDR. El valor que debe escribir se describe más adelante. Sin
embargo, es importante que el bit TWINT se establece en el valor escrito. Escribir
un uno a cero la bandera TWINT. El TWI no se iniciará ninguna operación, siempre
que el bit TWINT en TWCR se establece. Inmediatamente después de la aplicación
ha despejado TWINT, el TWI iniciará la transmisión del paquete de datos.
6. Cuando el paquete de datos ha sido transmitido, la Bandera TWINT en TWCR se
fija, y TWSR se actualiza con un código de estado que indica que el paquete de
datos se ha enviado correctamente. El código de estado también reflejará si un
esclavo reconoce el paquete o no.
7. El software de aplicación debe ahora examinar el valor de TWSR, para
asegurarse de que los paquetes de datos se han transmitido correctamente, y que
el valor del bit ACK fue como se esperaba. Si TWSR indica lo contrario, el software
de aplicación pudiera tomar ciertas medidas especiales, como llamar a una rutina
de error. Suponiendo que el código de estado es como se esperaba, la aplicación
debe escribir un valor determinado a TWCR, instruyendo el hardware TWI para
transmitir un estado de STOP. El valor que debe escribir se describe más adelante.
Sin embargo, es importante que el bit TWINT se establece en el valor escrito.
Escribir un uno a cero la bandera TWINT. El TWI no se iniciará ninguna operación,
siempre que el bit TWINT en TWCR esté cambiado. Inmediatamente después de la
aplicación se ha aclarado TWINT, el TWI iniciará la transmisión de la condición de
STOP. Tenga en cuenta que TWINT no se establece después de una condición de
parada se ha enviado.
A pesar de que este ejemplo es simple, que muestra los principios implicados en
todas las transmisiones de inmersión recíproca. Estos se pueden resumir como
sigue:
I ♥AVR ´s
#ifndef I2C_H_
#define I2C_H_
//////////////////////////////////////////////////////////////////
//inicialización del módulo TWI I2C AVR en el ATMEL STUDIO en una
función////
//para el ATMEGA88 como maestro
//a 400KHz con un oscilador de 8Mhz
void i2c_iniciar(){
PORTC|=((1<<4)|(1<<5)); //activa resistencias pull upp para
SCL y SDA
TWBR=2; //velocidad 400Khz, Fosc 8Mhz,
prescaler de 1
TWCR|=(1<<TWEN); //módulo TWI iniciado
}
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Función de espera: mientras el bit7 o bit TWINT del registro
// TWCR sea 0, el IC2 AVR se esperará
// antes de realizar algún trabajo
void i2c_espera(){
while ((TWCR & (1<<TWINT)) == 0);//espera mientras el bit de
interrupcion sea 0
}
////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
Función de inicio de la comunicación I2C AVR
void i2c_inicia_com() {
I ♥AVR ´s
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//bandera de
interrupción a 1, start, habilita I2C AVR
i2c_espera(); //espera mientras el bit TWINT sea 0
}
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Función de parada de la comunicación I2C I2C
void i2c_detener() {
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);//bandera de
interrupción a 1, detener, habilita I2C AVR
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
//Función de transmisión de datos del maestro al esclavo
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
//Función de recepción de datos enviados por el esclavo al maestro
//esta función es para leer los datos que están en el esclavo
//en forma continua, esto es tras leer uno se volverá a leer otro
/////////////////////////////////////////////////////////////////
//función para averiguar el estado de la comunicación I2C AVR
//útil para detectar errores, el valor que retorna esta función
//se compara con el estado que deberían indicar los bits del 7 al
3
//del registro TWSR según tabla, durante la comunicación I2C AVR,
uint8_t i2c_estado_com(){
uint8_t estado; //variable donde se almacena el estado
de la comunicación
//I2C AVR
estado = TWSR & 0xf8; //en la variable estado se guarda el
valor de los 5 bits de
//mas peso del registro TWSR seguidos de 3 ceros,
//el número obtenido indica
//el estado en que se encuentra la comunicación I2C AVR
#endif /* I2C_H_ */
Referencias:
microcontroladores-mrelberni.com/i2c-avr-comunicacion-serial-twi/
maxembedded.com/2014/02/inter-integrated-circuits-i2c-basics/
www.embedds.com/programming-avr-i2c-interface/
AVR PROGRAMMING IN C, editorial 2014
DATASHEET AVR ATMEGA328P