Este artículo explora la interfaz TWI entre dos controladores ATmega32. Se recomienda a los lectores que consulten la comunicación TWI y los registros TWI del ATmega32 antes de continuar.
TWI funciona en cuatro modos:
1. MASTER como transmisor.
dos. MAESTRO como receptor.
3. ESCLAVO como receptor.
4. SLAVE como transmisor.
Generalmente los modos 1 y 3 y los modos 2 y 4 se utilizan juntos. Este artículo explica el uso de estos cuatro modos en un experimento.
Objetivo: Establecer comunicación entre dos ATmega32 utilizando la interfaz TWI. Primero, el maestro comienza a enviar datos y luego el esclavo transmite el complemento de datos recibidos al maestro. Cuando el Maestro recibe los datos suplementados, desplaza los datos originales hacia la izquierda. Este proceso de transmisión y recepción continúa. Cuando el valor de los datos alcanza 0x80, se repite todo el proceso. Al principio, el valor de los datos originales es 0x01. El valor recibido se muestra en PORTB en ambos extremos.
Descripción del circuito:
Realice las conexiones como se muestra en el diagrama del circuito.
Explicación del código del controlador MASTER:
Paso 1: inicialización maestra.
La inicialización MASTER significa configurar la frecuencia del reloj TWI (SCL). Esto se hace configurando la tasa de bits en TWBR y los bits del preescalador en TWSR.

Fig. 2: Ecuación de frecuencia de reloj TWI para inicializar el maestro en el AVR
void TWI_init_master(void) // Función para inicializar el maestro
{
TWBR=0x01; // tasa de bits
TWSR=(0<<TWPS1) (0<<TWPS0); // Configurando bits preescalar
// frecuencia SCL= F_CPU/(16+2(TWBR).4^TWPS)
}
Paso 2: Enviar condición inicial
La condición inicial en TWI fue explicada anteriormente. El microcontrolador AVR tiene registros incorporados que facilitan mucho este trabajo.
1. Borre la bandera TWINT escribiéndole una lógica.
dos. Establezca el bit TWSTA para enviar la condición de inicio.
3. Establezca el bit TWEN para inicializar TWI.
4. Supervise el estado de la bandera TWINT.
5. Verifique el byte ACK (usando la condición while ya que la frecuencia SCL es muy pequeña en comparación con la frecuencia del reloj del microcontrolador). El byte ACK se puede comparar monitoreando el estado de TWSR.
anular TWI_start(anular)
{
// Borrar el indicador de interrupción TWI, poner la condición de inicio en SDA, habilitar TWI
TWCR= (1<<TWINT) (1<<TWSTA) (1<<TWEN);
mientras(!(TWCR & (1<<TWINT))); //Esperar hasta que se transmita la condición de inicio.
mientras((TWSR y 0xF8)!= 0x08); // Comprobar el acuse de recibo
}
Paso 3: enviar la dirección del esclavo, el bit de dirección de datos (escritura) y esperar la señal ACK
Fig. 3: Bit de condición inicial en TWI
Estos tres procesos están controlados por los registros TWI del AVR .
1. Coloque la dirección esclava de siete bits y el bit de control de dirección en el TWDR.
dos. Borre la bandera TWINT.
3. Habilite TWI escribiendo uno lógico en el bit TWEN.
4. Supervise el estado del indicador TWINT; el indicador TWINT se borrará cuando se transmitan datos en TWDR.
5. Compruebe el reconocimiento correcto.
void TWI_read_address (datos de caracteres sin firmar)
{
TWDR=fecha; // Dirección y lectura de instrucciones.
TWCR=(1<<TWINT) (1<<TWEN); // Borrar el indicador de interrupción TWI, habilitar TWI
mientras (!(TWCR & (1<<TWINT))); // Espere hasta que se reciba el byte TWDR completo
mientras((TWSR y 0xF8)!= 0x40); // Comprobar el acuse de recibo
}
Paso 4: envíe datos de 8 bits y espere ACK
Fig. 4: Transferencia de datos en TWI desde el AVR
1. Coloque datos de 8 bits en TWDR.
8 bits = dirección esclava de 7 bits + bit de dirección de datos (escritura = 0).
dos. Borre la bandera TWINT.
3. Establezca el bit TWEN para habilitar TWI.
4. Supervise el estado del indicador TWINT para completar la transmisión de datos.
5. Comprobar reconocimiento.
void TWI_write_data (datos de caracteres sin firmar)
{
TWDR=fecha; //poner datos en TWDR
TWCR=(1<<TWINT) (1<<TWEN); // Borrar el indicador de interrupción TWI, habilitar TWI
mientras (!(TWCR & (1<<TWINT))); // Espere hasta que se transmita el byte TWDR completo
mientras((TWSR y 0xF8) != 0x28); // Comprobar el acuse de recibo
}
Paso 5: Enviar la condición STOP

Fig.5: Bit de condición TWI STOP
Para enviar la condición de parada utilice TWSTO
1. Borre la bandera TWINT.
dos. Establecer VECE bits
3. Escriba uno lógico en el bit TWSTO para enviar la condición STOP en la línea SDA y SCL.
4. Supervise el estado del bit TWSTO, ya que borrar el bit TWSO significa que se ha transmitido la condición de parada.
anular TWI_stop(anular)
{
// Borrar el indicador de interrupción TWI, poner la condición de parada en SDA, habilitar TWI
TWCR= (1<<TWINT) (1<<TWEN) (1<<TWSTO);
mientras(!(TWCR & (1<<TWSTO))); // Esperar hasta que se transmita la condición de parada
}
Hasta ahora la transmisión de datos del lado esclavo está completa, el MAESTRO está funcionando en modo uno. Según el objetivo, los datos recibidos por MASTER se muestran en PORTB. A continuación se muestra el diagrama de flujo de MASTER como transmisor (modo uno).

Fig. 6: Diagrama de flujo de MASTER como transmisor en la interfaz TWI usando AVR
A partir de aquí el MASTER estaría trabajando en modo dos, es decir, el MASTER pasaría a ser un receptor. El AVR TWI funciona en modo 2.
Paso 6: Enviar la condición de INICIO en las líneas de autobús
Este paso es muy similar al anterior.
Nota : En el Paso 6, la condición de INICIO se envía después de la condición de PARADA. Si se envía una condición de inicio más antes de la condición de PARADA intermedia, se denomina condición de inicio repetida. La condición de inicio repetida es la misma que la condición de INICIO, pero la única diferencia está entre las confirmaciones. Para obtener más detalles sobre el arranque repetitivo, consulte la hoja de datos. Si los datos se envían continuamente en la misma dirección, no hay necesidad de una condición de inicio, un inicio repetitivo o una condición de parada intermedia. Los segundos datos se pueden transmitir inmediatamente después de recibir el acuse de recibo del primer byte de datos (como se muestra en el diagrama de flujo anterior).
Paso 7: enviar la dirección del esclavo y el bit de dirección de datos (lectura) y esperar la señal ACK
1. Coloque datos de 8 bits en TWDR.
8 bits = dirección esclava de 7 bits + bit de dirección de datos (lectura = 1).
dos. Borre la bandera TWINT.
3. Establezca el bit TWEN para habilitar TWI.
4. Supervise el estado del indicador TWINT para completar la transmisión de datos.
5. Comprobar reconocimiento.
void TWI_read_address (datos de caracteres sin firmar)
{
TWDR=fecha; // Dirección y lectura de instrucciones.
TWCR=(1<<TWINT) (1<<TWEN); // Borrar el indicador de interrupción TWI, habilitar TWI
mientras (!(TWCR & (1<<TWINT))); // Espere hasta que se reciba el byte TWDR completo
mientras((TWSR y 0xF8)!= 0x40); // Comprobar el acuse de recibo
}
Paso 8: leer datos del bus SDA
1. Borrar bandera TWINT
dos. Establezca el bit TWEN, habilite TWI
3. Supervise el estado del indicador TWINT, ya que el indicador TIWNT establecido indica que se ha recibido el valor en TWDR.
4. Comprobar reconocimiento. Si el maestro quiere recibir el último byte del esclavo, el estado del registro TWSR será 0x58. Después de recibir el último byte, el maestro emite una condición de inicio repetitiva para continuar la comunicación o el maestro debe dar una condición de parada para detener el proceso de comunicación. De lo contrario, si el maestro quiere seguir recibiendo más bytes del esclavo, el estado del registro TWSR será 0x50.
Para confirmar el guardado del último byte, se utiliza el bit TWEA durante la transmisión de datos. Si se establece el bit TWEA, la recepción será continua en el lado MAESTRO. Y si el bit TWEA está bajo, el MAESTRO ordena al esclavo que envíe el último byte.
5. Obtenga los datos recibidos. Y enviarlo a PORTB.
anular TWI_read_data (anular)
{
TWCR=(1<<TWINT) (1<<TWEN); // Borrar el indicador de interrupción TWI, habilitar TWI
mientras (!(TWCR & (1<<TWINT))); // Espere hasta que se transmita el byte TWDR completo
mientras((TWSR y 0xF8) != 0x58); // Comprobar el acuse de recibo
recv_data=TWDR;
PORTB=recv_data;
}
Paso 9: Enviar condición DETENER
La condición de parada ya ha sido explicada.

Fig. 7: Diagrama de flujo de MASTER como receptor en la interfaz TWI usando AVR
Explicación del código para el controlador SLAVE:
Paso 1: Inicializando el control Slave R
La inicialización del controlador esclavo se realiza asignando una dirección al esclavo. La dirección esclava de siete bits se completa en el Registro de direcciones esclavas TWI (TWAR). El LSB del TWAR, es decir, el bit TWGCE, se utiliza para permitir que el esclavo reconozca la dirección de llamada general (0x00).
void TWI_init_slave(void) // Función para inicializar el esclavo
{
TWAR=0x20; // Completa la dirección del esclavo en TWAR
}
Paso 2: Verifique el estado de registro de TWSR
Si el valor de TWSR es 0x60, significa que los datos enviados por el maestro en el siguiente paso deben ser leídos solo por este esclavo específico y el esclavo devuelve el acuse de recibo al maestro correspondiente a la operación de lectura. Si el estado de TWSR es 0x70, se solicita a SLAVE que lea los datos en la llamada general (0x00). En esta fase el ESCLAVO actúa como receptor. AVR TWI está funcionando en modo 3.
1. Borre la bandera TWIN.
dos. Habilite TWI.
3. Configure TEWA para recibir reconocimiento.
4. Supervise el estado de la bandera TWINT.
5. Coincide con el estado de TWSR. Si el estado es 0x60, lea los datos o salte a (1)
void TWI_match_read_slave(void) //Función para hacer coincidir la dirección del esclavo y el bit de dirección del esclavo (lectura)
{
while((TWSR & 0xF8)!= 0x60) // Bucle hasta que se haya recibido el reconocimiento correcto
{
// Obtener confirmación, habilitar TWI, borrar el indicador de interrupción TWI
TWCR=(1<<TWEA) (1<<TWEN) (1<<TWINT);
mientras (!(TWCR & (1<<TWINT))); //Esperar la bandera TWINT
}
}
Paso 3: leer los datos
Leer los datos enviados por MASTER.
1. Borre la bandera TWINT.
dos. Habilite TWI.
3. Configure TWEA para recibir ACK.
4. Obtenga el formulario de datos TWDR y muéstrelo en PORTB.