Como usar I2C / TWI (interface de dois fios) no AVR ATmega32- (Parte 36/46)

Como usar I2C / TWI (interface de dois fios) no AVR ATmega32- (Parte 36/46)

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.

Equação da frequência do clock TWI para inicializar o mestre no AVR

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
Bit de condição inicial no TWI
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
Transferência de dados em TWI do AVR
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

Bit de condição TWI 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.

Fluxograma do MASTER como transmissor na interface TWI usando AVR

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.

Fluxograma do MASTER como receptor na interface TWI usando AVR

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.

 

vazio TWI_read_slave(vazio)
{
// Limpa sinalizador de interrupção TWI, obtém reconhecimento, habilita TWI
TWCR= (1< enquanto (!(TWCR & (1< enquanto((TWSR & 0xF8)!=0x80); //Aguarda confirmação
recv_data=TWDR; // Obtém valor do TWDR
PORTB=recv_dados; // envia o valor recebido em PORTB
}

Escravo como receptor na interface TWI usando AVR
Fig. 8: Escravo como receptor na interface TWI usando AVR
A partir daqui, o escravo se torna um transmissor a pedido do mestre para enviar dados. O AVR TWI funciona no modo 4.
Passo 4: Verifique o status do registro TWSR
Se o valor de TWSR for 0xA8, significa que o mestre deseja receber dados do escravo específico e o escravo envia de volta a confirmação ao mestre correspondente à operação de escrita.
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 0xA8 envie dados ou então pule para (1)
void TWI_match_write_slave(void) //Function to match the slave address and slave dirction bit(write) 
{
    while((TWSR & 0xF8)!= 0xA8)    // 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 5: Escreva os dados no barramento SDA
1. Coloque os dados no TWDR.
2. Habilite o TWI.
3. Cole a bandeira TWINT.
4. Monitore o sinalizador TWINT. À medida que é limpo, significa que os dados foram enviados.
5. Verifique o ACK. Como o bit TWEA não foi setado durante a escrita dos dados no barramento SDA, significa que o mestre é o último dado a ser enviado e por sua vez recebe um NOT ACK e o status do TWSR passa a ser 0xC0. E se o bit TWEA foi setado durante a transmissão de dados ele recebe um ACK e o status do TWSR passa a ser 0xB8. Para mais detalhes consulte a ficha técnica.

 

void TWI_write_slave(void) // Função para escrever dados
{
TWDR= dados_gravação; // Preenche o cadastro TWDR com os dados a serem enviados
TWCR= (1< enquanto((TWSR & 0xF8) != 0xC0); //Aguarde o reconhecimento
}

Escravo como Transmissor e Interface TWI usando AVR

Fig. 9: Escravo como Transmissor na Interface TWI usando AVR

Código-fonte do projeto

###


//Programa para Modo Master
// Verifica Code2 para programa em modo escravo #incluir #incluir #incluir void TWI_start(void); void TWI_repeated_start(void); void TWI_init_master(void); void TWI_write_address(caractere não assinado); void TWI_read_address(caractere não assinado); void TWI_write_data(caractere não assinado); void TWI_read_data(void); void TWI_stop(void); endereço de caractere não assinado = 0x20, leitura = 1, gravação = 0; caractere não assinado write_data = 0x01, recv_data; int principal(vazio) { _atraso_ms(2000); DDRB=0xff; TWI_init_master ; //Função para inicializar o TWI enquanto(1) { if(escrever_dados==0x00) escrever_dados=1; TWI_start ; //Função para enviar condição de início TWI_write_address(endereço+escrever); //Função para escrever bit(write) de endereço e direção de dados no SDA TWI_write_data(escrever_dados); //Função para escrever dados no escravo TWI_stop ; //Função para enviar condição de parada _atraso_ms(10); // Atraso de 10 mili segundos TWI_start ; TWI_read_address(endereço+leitura); //Função para escrever endereço e bit de direção de dados (leitura) no SDA TWI_read_data ; //Função para ler dados do escravo TWI_stop ; _atraso_ms(1000); escrever_dados = escrever_dados * 2; } } void TWI_init_master(void) // Função para inicializar o mestre { TWBR=0x01; //Taxa de bits TWSR=(0< //Configurando bits pré-escalares // Frequência SCL= F_CPU/(16+2(TWBR).4^TWPS) } vazio TWI_start(vazio) { // Limpa o sinalizador de interrupção do TWI, coloca a condição de início no SDA, habilita o TWI TWCR= (1< enquanto(!(TWCR & (1< enquanto((TWSR & 0xF8)!= 0x08); //Verifica o reconhecimento } vazio TWI_repeated_start(void) { // Limpa o sinalizador de interrupção do TWI, coloca a condição de início no SDA, habilita o TWI TWCR= (1< enquanto(!(TWCR & (1< enquanto((TWSR & 0xF8)!= 0x10); //Verifica o reconhecimento } void TWI_write_address (dados de caracteres não assinados) { TWDR=dados; //Endereça e escreve instrução TWCR=(1< enquanto (!(TWCR & (1< enquanto((TWSR & 0xF8)!= 0x18); //Verifica o reconhecimento } void TWI_read_address (dados de caracteres não assinados) { TWDR=dados; // Endereço e instrução de leitura TWCR=(1< enquanto (!(TWCR & (1< enquanto((TWSR & 0xF8)!= 0x40); //Verifica o reconhecimento } void TWI_write_data (dados de caracteres não assinados) { TWDR=dados; //coloca os dados no TWDR TWCR=(1< enquanto (!(TWCR & (1< enquanto((TWSR & 0xF8) != 0x28); //Verifica o reconhecimento } vazio TWI_read_data(void) { TWCR=(1< enquanto (!(TWCR & (1< enquanto((TWSR & 0xF8) != 0x58); //Verifica o reconhecimento recv_data=TWDR; PORTB=recv_dados; } vazio TWI_stop(vazio) { // Limpa flag de interrupção TWI, coloca condição de parada no SDA, habilita TWI TWCR= (1< enquanto(!(TWCR & (1< }

###

Código-fonte do projeto

###



//Programa para modo escravo
#incluir #incluir void TWI_init_slave(void); void TWI_match_read_slave(void); void TWI_read_slave(void); void TWI_match_write_slave(void); vazio TWI_write_slave(void); caractere não assinado write_data,recv_data; int principal(vazio) { DDRB=0xff; TWI_init_slave ; //Função para inicializar o escravo enquanto(1) { TWI_match_read_slave ; //Função para combinar o endereço do escravo e o bit de direção do escravo (leitura) TWI_read_slave ; //Função para ler dados write_data=~recv_data; // Alterna os dados recebidos TWI_match_write_slave ; //Função para combinar o endereço do escravo e o bit de direção do escravo (gravação) TWI_write_slave ; //Função para gravar dados } } void TWI_init_slave(void) // Função para inicializar o escravo { TWAR=0x20; //Preenche o endereço do escravo para TWAR } void TWI_write_slave(void) // Função para escrever dados { TWDR= dados_gravação; // Preenche o cadastro TWDR com os dados a serem enviados TWCR= (1< enquanto((TWSR & 0xF8) != 0xC0); //Aguarde o reconhecimento } void TWI_match_write_slave(void) //Função para combinar o endereço do escravo e o bit de direção do escravo(write) { enquanto((TWSR & 0xF8)!= 0xA8) // Loop até que o reconhecimento correto seja recebido { // Obtém reconhecimento, habilita TWI, limpa sinalizador de interrupção TWI TWCR=(1< enquanto (!(TWCR & (1< } } vazio TWI_read_slave(vazio) { // Limpa sinalizador de interrupção TWI, obtém reconhecimento, habilita TWI TWCR= (1< enquanto (!(TWCR & (1< //Aguarde pela flag TWINT enquanto((TWSR & 0xF8)!=0x80); //Aguarda confirmação recv_data=TWDR; // Obtém valor do TWDR PORTB=recv_dados; // envia o valor recebido em PORTB } void TWI_match_read_slave(void) //Função para combinar o endereço do escravo e o bit de direção do escravo(read) { while((TWSR & 0xF8)!= 0x60) // Loop até que o reconhecimento correto seja recebido { // Obtém reconhecimento, habilita TWI, limpa sinalizador de interrupção TWI TWCR=(1< enquanto (!(TWCR & (1< } }

###

Diagramas de circuito

Diagrama de circuito de como usar-I2C-TWI-Interface de dois fios em-AVR-ATmega32

Componentes do Projeto

  • ATmega32
  • LIDERADO

Vídeo do projeto

Conteúdo Relacionado

A Infineon Technologies AG apresenta os novos MOSFETs CoolSiC...
Uma rede de sensores é incorporada em todos os...
O controlador do motor é um dos componentes mais...
ESP32-CAM é um módulo de câmera compacto que combina...
A evolução dos padrões USB foi fundamental para moldar...
A SCHURTER anuncia um aprimoramento para sua conhecida série...
A Sealevel Systems anuncia o lançamento da Interface Serial...
A STMicroelectronics introduziu Diodos retificadores Schottky de trincheira de...
Determinar uma localização precisa é necessário em várias indústrias...
O novo VIPerGaN50 da STMicroelectronics simplifica a construção de...
A Samsung Electronics, fornecedora de tecnologia de memória avançada,...
O mercado embarcado tem uma necessidade de soluções de...
Quando você explora a área de Controle V/F dos...
Você provavelmente já se deparou com o termo 'arrastar'...
Você provavelmente tem um Isolador de suporte Se você...
Vissza a blogba

Hozzászólás írása

Felhívjuk a figyelmedet, hogy a hozzászólásokat jóvá kell hagyni a közzétételük előtt.