Este artigo explora a interface TWI entre dois controladores ATmega32. Os leitores são aconselhados a consultar o TWI Communication e os registros TWI do ATmega32 antes de prosseguir.
O TWI funciona em quatro modos:
1. MESTRE como transmissor.
2. MESTRE como receptor.
3. SLAVE como receptor.
4. SLAVE como transmissor.
Geralmente os modos 1 e 3 e os modos 2 e 4 são usados juntos. Este artigo explica o uso desses quatro modos em um experimento.
Objetivo: Estabelecer a comunicação entre dois ATmega32 utilizando interface TWI. Primeiro o Mestre começa enviando dados e depois o escravo transmite o complemento dos dados recebidos ao mestre. Quando o Mestre recebe os dados complementados, ele desloca os dados originais para a esquerda. Este processo de transmissão e recepção continua. À medida que o valor dos dados atinge 0x80, todo o processo é repetido. No início, o valor dos dados originais é 0x01. O valor recebido é exibido no PORTB em ambas as extremidades.
Descrição do circuito:
Faça as conexões conforme mostrado no diagrama de circuito.
Explicação do código para o controlador MASTER:
Passo 1: Inicialização do mestre.
A inicialização do MASTER significa definir a frequência do clock TWI (SCL). Isso é feito definindo a taxa de bits no TWBR e os bits pré-escaladores no TWSR.
Fig. 2: Equação da frequência do clock TWI para inicializar o mestre no AVR
void TWI_init_master(void) // Function to initialize master
{
TWBR=0x01; // Bit rate
TWSR=(0<<TWPS1) (0<<TWPS0); // Setting prescalar bits
// SCL freq= F_CPU/(16+2(TWBR).4^TWPS)
}
Etapa 2: enviar condição inicial
A condição inicial no TWI foi explicada anteriormente. O microcontrolador AVR possui registradores integrados que tornam esse trabalho muito mais fácil.
1. Limpe o sinalizador TWINT escrevendo um lógico nele.
2. Defina o bit TWSTA para enviar a condição de início.
3. Defina o bit TWEN para inicializar o TWI.
4. Monitore o status do sinalizador TWINT.
5. Verifique o byte ACK (usando a condição while, pois a frequência SCL é muito pequena em comparação com a frequência do clock do microcontrolador). O byte ACK pode ser comparado monitorando o status do TWSR.
void TWI_start(void)
{
// Clear TWI interrupt flag, Put start condition on SDA, Enable TWI
TWCR= (1<<TWINT) (1<<TWSTA) (1<<TWEN);
while(!(TWCR & (1<<TWINT))); // Wait till start condition is transmitted
while((TWSR & 0xF8)!= 0x08); // Check for the acknowledgement
}
Passo 3: Envie o endereço do escravo, bit de direção de dados (gravação) e aguarde o sinal ACK
Fig. 3: Bit de condição inicial no TWI
Esses três processos são controlados pelos registradores TWI do AVR.
1. Coloque o endereço escravo de sete bits e o bit de controle de direção no TWDR.
2. Limpe o sinalizador TWINT.
3. Habilite o TWI escrevendo a lógica um no bit TWEN.
4. Monitore o status do sinalizador TWINT, o sinalizador TWINT será limpo quando os dados no TWDR forem transmitidos.
5. Verifique o reconhecimento correto.
void TWI_read_address(unsigned char data)
{
TWDR=data; // Address and read instruction
TWCR=(1<<TWINT) (1<<TWEN); // Clear TWI interrupt flag,Enable TWI
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte received
while((TWSR & 0xF8)!= 0x40); // Check for the acknoledgement
}
Passo 4: Envie os dados de 8 bits e aguarde o ACK
Fig. 4: Transferência de dados em TWI do AVR
1. Coloque os dados de 8 bits em TWDR.
8 bits = endereço escravo de 7 bits + bit de direção de dados (gravação = 0).
2. Limpe o sinalizador TWINT.
3. Defina o bit TWEN para ativar o TWI.
4. Monitore o status do sinalizador TWINT para concluir a transmissão de dados.
5. Verifique o reconhecimento.
void TWI_write_data(unsigned char data)
{
TWDR=data; // put data in TWDR
TWCR=(1<<TWINT) (1<<TWEN); // Clear TWI interrupt flag,Enable TWI
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte transmitted
while((TWSR & 0xF8) != 0x28); // Check for the acknoledgement
}
Etapa 5: Envie a condição STOP
Fig.5: Bit de condição TWI STOP
Para enviar a condição de parada use TWSTO
1. Limpe o sinalizador TWINT.
2. Definir bit TWEN
3. Escreva a lógica um no bit TWSTO para enviar a condição STOP na linha SDA e SCL.
4. Monitore o status do bit TWSTO, pois a limpeza do bit TWSO significa que a condição de parada foi transmitida.
void TWI_stop(void)
{
// Clear TWI interrupt flag, Put stop condition on SDA, Enable TWI
TWCR= (1<<TWINT) (1<<TWEN) (1<<TWSTO);
while(!(TWCR & (1<<TWSTO))); // Wait till stop condition is transmitted
}
Até aqui a transmissão de dados do lado escravo está completa, o MASTER está trabalhando no modo um. De acordo com o objetivo os dados recebidos pelo MASTER são exibidos no PORTB. O fluxograma do MASTER como transmissor (modo um) é fornecido abaixo.
Fig. 6: Fluxograma do MASTER como transmissor na interface TWI usando AVR
A partir daqui o MASTER estaria trabalhando no modo dois, ou seja, o MASTER se tornaria um receptor. O AVR TWI funciona no modo 2.
Passo 6: Envie a condição START nas linhas de ônibus
Esta etapa é tão semelhante à anterior.
Observação: No Passo 6 a condição START é enviada após a condição STOP. Se mais uma condição de partida for enviada antes da condição de PARADA intermediária, ela será chamada de condição de partida repetitiva. A condição de início repetitivo é igual à condição de INÍCIO, mas a única diferença está entre as confirmações. Para mais detalhes sobre partida repetitiva consulte a folha de dados. Se os dados forem enviados continuamente na mesma direção, não haverá necessidade de condição de início, início repetitivo ou condição de parada intermediária. Os segundos dados podem ser transmitidos logo após receber a confirmação do primeiro byte de dados (conforme mostrado no fluxograma acima).
Passo 7: Envie o endereço do escravo e o bit de direção dos dados (leitura) e aguarde o sinal ACK
1. Coloque os dados de 8 bits no TWDR.
8 bits = endereço escravo de 7 bits + bit de direção de dados (leitura = 1).
2. Limpe o sinalizador TWINT.
3. Defina o bit TWEN para ativar o TWI.
4. Monitore o status do sinalizador TWINT para concluir a transmissão de dados.
5. Verifique o reconhecimento.
void TWI_read_address(unsigned char data)
{
TWDR=data; // Address and read instruction
TWCR=(1<<TWINT) (1<<TWEN); // Clear TWI interrupt flag,Enable TWI
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte received
while((TWSR & 0xF8)!= 0x40); // Check for the acknoledgement
}
Etapa 8: Leia os dados do barramento SDA
1. Limpar sinalizador TWINT
2. Defina o bit TWEN, habilite TWI
3. Monitore o status do sinalizador TWINT, pois o sinalizador TIWNT definido indica que o valor em TWDR foi recebido.
4. Verifique o reconhecimento. Caso o mestre queira receber o último byte do escravo, o status do registrador TWSR será 0x58. Depois de receber o último byte, uma condição de início repetitiva é emitida pelo mestre para continuar a comunicação ou uma condição de parada deve ser dada pelo mestre para interromper o processo de comunicação. Caso contrário, se o mestre quiser continuar recebendo mais bytes do escravo, o status do registro TWSR será 0x50.
Para confirmar o salvamento do último byte, o bit TWEA é usado durante a transmissão dos dados. Se o bit TWEA estiver definido, a recepção será contínua do lado MASTER. E se o bit TWEA estiver baixo, o MASTER ordena ao escravo que envie o último byte.
5. Obtenha os dados recebidos. E envie no PORTB.
void TWI_read_data(void)
{
TWCR=(1<<TWINT) (1<<TWEN); // Clear TWI interrupt flag,Enable TWI
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte transmitted
while((TWSR & 0xF8) != 0x58); // Check for the acknoledgement
recv_data=TWDR;
PORTB=recv_data;
}
Etapa 9: Enviar condição STOP
A condição de parada já foi explicada.
Fig. 7: Fluxograma do MASTER como receptor na interface TWI usando AVR
Explicação do código para o controlador SLAVE:
Passo 1: Inicialização do controle SlaveR
A inicialização do controlador escravo é feita atribuindo um endereço ao escravo. O endereço escravo de sete bits é preenchido no TWI slave Address Register (TWAR). O LSB do TWAR, ou seja, o bit TWGCE é usado para permitir que o escravo reconheça o endereço de chamada geral (0x00).
void TWI_init_slave(void) // Function to initilaize slave
{
TWAR=0x20; // Fill slave address to TWAR
}
Passo 2: Verifique o status do registro TWSR
Se o valor de TWSR for 0x60, significa que os dados enviados pelo mestre na próxima etapa devem ser lidos apenas por este escravo específico e o escravo envia de volta a confirmação ao mestre correspondente à operação de leitura. Se o status do TWSR for 0x70 o SLAVE é solicitado a ler os dados na chamada geral (0x00). Nesta fase o SLAVE atua como receptor. O AVR TWI está funcionando no modo 3.
1. Limpe a bandeira TWIN.
2. Habilite o TWI.
3. Configure TEWA para receber reconhecimento.
4. Monitore o status do sinalizador TWINT.
5. Combine o status do TWSR. Se o status for 0x60 leia os dados ou pule para (1)
void TWI_match_read_slave(void) //Function to match the slave address and slave dirction bit(read)
{
while((TWSR & 0xF8)!= 0x60) // Loop till correct acknoledgement have been received
{
// Get acknowlegement, Enable TWI, Clear TWI interrupt flag
TWCR=(1<<TWEA) (1<<TWEN) (1<<TWINT);
while (!(TWCR & (1<<TWINT))); // Wait for TWINT flag
}
}
Etapa 3: ler os dados
Leia os dados enviados pelo MASTER.
1. Limpe o sinalizador TWINT.
2. Habilite o TWI.
3. Configure TWEA para receber ACK.
4. Obtenha o formulário de dados TWDR, exiba-o no PORTB.