- O que é o protocolo de comunicação I2C?
- Como funciona a comunicação I2C?
- Onde usar a comunicação I2C?
- I2C no Nuvoton N76E003 - Requisito de Hardware
- Interface de AT24LC64 com Nuvoton N76E003 - Diagrama de Circuito
- Pinos I2C no Nuvoton N76E003
- Comunicação I2C em N76E003
- Programando N76E003 para comunicação I2C
- Piscando o código e a saída
No vasto sistema de aplicativos embarcados, nenhum microcontrolador pode realizar todas as atividades sozinho. Em algum momento, ele precisa se comunicar com outros dispositivos para compartilhar informações, existem diversos tipos de protocolos de comunicação para compartilhar essas informações, mas os mais usados são USART, IIC, SPI e CAN. Cada protocolo de comunicação tem suas próprias vantagens e desvantagens. Vamos nos concentrar na parte da IIC por enquanto, pois é isso que aprenderemos neste tutorial. Se você é novo aqui, dê uma olhada nos Tutoriais da Nuvoton, onde discutimos todos os periféricos do Microcontrolador N76E003 desde o tutorial básico de introdução. Se você quiser aprender a usar I2C com outros microcontroladores, pode verificar os links abaixo.
- Como usar I2C no Arduino: comunicação entre duas placas Arduino
- Comunicação I2C com Microcontrolador PIC PIC16F877
- Interface LCD 16X2 com ESP32 usando I2C
- Comunicação I2C com MSP430 Launchpad
- Interface de LCD com NodeMCU sem usar I2C
- Como lidar com múltiplas comunicações (I2C SPI UART) em um único programa do Arduino
I2C é um protocolo de comunicação importante desenvolvido pela Philips (agora NXP). Usando este protocolo I2C, um MCU pode ser conectado a vários dispositivos e iniciar a comunicação. I2C funciona com apenas dois fios, ou seja, SDA e SCL. Onde SDA significa Serial data e SCL significa Serial Clock. No entanto, esses dois pinos requerem resistores pull-up para o nível de tensão VCC e com um resistor pull-up adequado, o barramento pode suportar 127 dispositivos com um endereço exclusivo.
O que é o protocolo de comunicação I2C?
O termo IIC significa “ Inter Integrated Circuits ”. Normalmente é denotado como I2C ou I ao quadrado C ou mesmo como protocolo de interface de 2 fios (TWI) em alguns lugares, mas significa o mesmo. I2C é um protocolo de comunicação síncrona, o que significa que ambos os dispositivos que estão compartilhando as informações devem compartilhar um sinal de relógio comum. Ele tem apenas dois fios para compartilhar informações, dos quais um é usado para o sinal de clock e o outro é usado para enviar e receber dados.
Como funciona a comunicação I2C?
A comunicação I2C foi introduzida pela primeira vez por Phillips. Como disse anteriormente, ele tem dois fios, esses dois fios serão conectados em dois dispositivos. Aqui, um dispositivo é chamado de mestre e o outro dispositivo é chamado de escravo. A comunicação deve e sempre ocorrerá entre dois, um Mestre e um Escravo. A vantagem da comunicação I2C é que mais de um escravo pode ser conectado a um mestre.
A comunicação completa ocorre por meio desses dois fios, a saber, Serial Clock (SCL) e Serial Data (SDA).
Serial Clock (SCL): Compartilha o sinal de clock gerado pelo mestre com o escravo
Serial Data (SDA): Envia os dados de e para o mestre e o escravo.
A qualquer momento, apenas o mestre poderá iniciar a comunicação. Como há mais de um escravo no barramento, o mestre deve referir-se a cada escravo usando um endereço diferente. Quando endereçado, apenas o bálsamo com aquele endereço específico responderá de volta com a informação enquanto os outros ficam calados. Dessa forma, podemos usar o mesmo barramento para nos comunicarmos com vários dispositivos.
Onde usar a comunicação I2C?
A comunicação I2C é usada apenas para comunicação de curta distância. É certamente confiável até certo ponto, pois tem um pulso de relógio sincronizado para torná-lo inteligente. Este protocolo é usado principalmente para se comunicar com o sensor ou outros dispositivos que precisam enviar informações a um mestre. É muito útil quando um microcontrolador precisa se comunicar com muitos outros módulos escravos usando, no mínimo, fios. Se você estiver procurando por comunicação de longo alcance, deve tentar o RS232 e, se estiver procurando por uma comunicação mais confiável, deve tentar o protocolo SPI.
I2C no Nuvoton N76E003 - Requisito de Hardware
Como o requisito deste projeto é aprender a comunicação I2C usando N76E003, usaremos uma EEPROM que será conectada com a linha de dados I2C. Iremos armazenar alguns dados na EEPROM e também ler os mesmos e exibi-los usando a tela UART.
Como o valor armazenado será impresso no UART, qualquer tipo de conversor USB para UART é necessário. Você também pode verificar o tutorial sobre UART com Nuvoton se for novo na comunicação UART no N76E003. Para a nossa aplicação, usaremos o conversor CP2102 UART para USB. Além do acima, também exigimos os seguintes componentes-
- EEPROM 24C02
- Resistores 2pcs 4,7k
Sem mencionar que, além dos componentes acima, precisamos de uma placa de desenvolvimento baseada em microcontrolador N76E003, bem como do programador Nu-Link. Além disso, a placa de ensaio e os fios de conexão também são necessários para conectar todos os componentes.
Interface de AT24LC64 com Nuvoton N76E003 - Diagrama de Circuito
Como podemos ver no esquema abaixo, a EEPROM está conectada na linha I2C junto com dois resistores pull up. Na extrema esquerda, a conexão da interface de programação é mostrada.
Usei uma placa de ensaio para o IC AT24LC64 e conectei o IC à minha placa de programador Nuvoton usando fios de jumper. Minha configuração de hardware junto com o programador nu-ink é mostrada abaixo.
Pinos I2C no Nuvoton N76E003
O diagrama de pinos do N76E003 pode ser visto na imagem abaixo
Como podemos ver, cada pino possui especificações diferentes e cada pino pode ser usado para diversos fins. No entanto, o pino 1.4 é usado como um pino I2C SDA, ele perderá o PWM e outras funcionalidades. Mas isso não é um problema, pois outra funcionalidade não é necessária para este projeto. O mesmo acontecerá com o P1.3 é o pino SCL do I2C.
Como os pinos I2C atuam como GPIO, eles precisam ser configurados. Todos os pinos GPIO podem ser configurados no modo descrito abaixo.
De acordo com a folha de dados, PxM1.n e PxM2. n são dois registradores que são usados para determinar a operação de controle da porta de E / S. Na folha de dados, é declarado que para usar a funcionalidade I2C, os modos de E / S precisam ser usados como dreno aberto para comunicações relacionadas a I2C.
Comunicação I2C em N76E003
O periférico I2C é uma coisa importante para qualquer unidade de microcontrolador que suporte recursos I2C. Muitos tipos de microcontroladores diferentes vêm com um periférico I2C embutido. No entanto, em alguns casos, I2C pode ser configurado manualmente usando o controle de software onde o suporte de hardware relacionado a I2C não está disponível (por exemplo, muitos microcontroladores 8051). No entanto, o Nuvoton N76E003 vem com suporte para periféricos I2C.
O M76E003 suporta quatro tipos de operações nos modos I2C - Transmissor Mestre, Receptor Mestre, Transmissor Escravo e Receptor Escravo. Ele também suporta velocidades padrão (100kbps) e rápidas (até 400kbps) para a linha I2C. I2C funciona com algumas regras genéricas nas linhas de sinal SCL e SDA.
Condição de início e parada:
É uma coisa importante na comunicação I2C. Quando os dados são transferidos para a linha I2C, eles começam com uma condição de início e terminam com uma condição de parada.
A condição de início é a transição de alto para baixo no SDA quando a linha SCL está alta e a condição de parada é a transição de baixo para alto no SDA quando a linha SCL está alta. Essas duas condições são geradas pelo mestre (O MCU ou qualquer coisa que esteja controlando os outros dispositivos escravos). A linha de ônibus permanece ocupada neste estado quando a condição de partida é iniciada e permanece livre novamente quando a condição de parada é iniciada.
A condição de partida e parada é mostrada de forma excelente na perspectiva do sinal na folha de dados do N76E003-
Endereço de 7 bits com formato de dados:
N76E003 suporta um endereço de 7 bits e formato de dados. Após o início da condição de inicialização, o dispositivo mestre precisa enviar os dados para a linha I2C. Os primeiros dados são importantes. Se esses dados não forem criados ou transmitidos corretamente, o dispositivo conectado não será identificado e outras comunicações não poderão ser feitas.
Os dados consistem em um endereço escravo de 7 bits, denotado como SLA. Este endereço de 7 bits deve ser exclusivo para cada dispositivo, se vários dispositivos estiverem conectados no barramento. Após o endereço de 7 bits, o 8º bit é o bit de direção dos dados. Isso significa que, dependendo do 8º bit, o mestre envia a informação ao dispositivo escravo sobre se os dados serão gravados no dispositivo escravo ou se os dados serão lidos no dispositivo escravo. O 8º bit é o bit R / W conhecido como notificador de leitura ou gravação. Como todos sabemos, as informações de 8 bits podem ser de 128 tipos, suportando assim 128 dispositivos, mas I2C suporta 127 tipos de dispositivos no mesmo barramento, mas não 128. Porque o endereço 0x00 é um endereço reservado que é chamado de endereço de chamada geral. Se o mestre quiser enviar informações para todos os dispositivos,ele endereçará 0x00 e cada dispositivo será reproduzido da mesma maneira que as configurações de software individuais.
Assim, a transmissão de dados parece abaixo-
Reconhecer:
Na imagem de endereço de dados acima, o nono bit seguido pelo bit R / W é chamado de bit de reconhecimento. É importante porque usando este bit, o mestre ou escravo responde ao transmissor de dados puxando a linha SDA para baixo. Para obter o bit de reconhecimento, o transmissor precisa liberar a linha SDA.
Programando N76E003 para comunicação I2C
O programa completo usado neste tutorial pode ser encontrado na parte inferior desta página. A explicação de segmentos importantes no código é a seguinte-
Defina os pinos como dreno aberto e configure-os para I2C:
Vamos começar com a seção de pinos I2C primeiro. Conforme descrito antes, as portas I2C SCL e SDA precisam ser configuradas e definidas como a configuração de dreno aberto. Para fazer isso, nós estamos usando um arquivo de cabeçalho I2C.h juntamente com um arquivo de origem I2C.c . O snippet de código se parece com isto-
faça {P13_OpenDrain_Mode; P14_OpenDrain_Mode; clr_I2CPX;} enquanto (0)
O código acima está configurando P13 e P14 como pino de dreno aberto e clr_I2CPX é usado para selecionar o P13 e P14 como pino SCL em P1.3 e pino SDA em P1.4.
Este I2CPX é o 0º bit do registro de controle I2C I2CON. Se este I2C_PX for definido como 1, os pinos são alterados para P0.2 como SCL e P1.6 como SDA. No entanto, usaremos P13 e P14. Pinos alternativos não são usados aqui.
Registro de controle I2C I2CON:
O registro de controle I2C I2CON é usado para controlar as operações I2C. O primeiro bit é o bit de seleção de pino I2C. Ajustá-lo em 0 configura o pino I2C como P13 e P14.
O bit AA é o sinalizador de confirmação de reconhecimento, se o sinalizador AA for definido, um ACK será retornado durante o pulso de reconhecimento de clock da linha SCL. Se for apagado, um NACK (alto nível no SDA) será retornado durante o pulso de clock reconhecido da linha SCL.
O próximo bit é SI, que é a interrupção de status I2C. Se a interrupção de status I2C estiver habilitada, o usuário deve verificar o registro I2STAT para determinar qual etapa foi aprovada e deve executar a ação.
O STO é o sinalizador STOP sendo definido no modo mestre. STO é apagado automaticamente pelo hardware assim que a condição STOP for detectada.
O próximo bit é o bit STA. Se este sinalizador for definido, I2C gerará uma condição de INÍCIO se o barramento estiver livre. Se o barramento estiver ocupado, o I2C espera por uma condição de PARADA e gera uma condição de PARTIDA em seguida. Se STA for definido enquanto o I2C já está no modo mestre e um ou mais bytes foram transmitidos ou recebidos, o I2C gera uma condição de INÍCIO repetida. O STA precisa ser apagado manualmente pelo software.
O último, I2CEN, é o bit de habilitação ou desabilitação do barramento I2C.
EEPROM 24C02:
Agora, chegando ao 24C02. O pacote de suporte da placa do N76E003 possui um código I2C para o 24LC64 e pode ser modificado facilmente. No entanto, usaremos um método simples para entender a função I2C.
Se alguém quiser usar uma interface detalhada com EEPROM 24C02, então o programa EEPROM no BSP pode ser usado.
Só conectaremos o 24C02 em I2C onde o N76E003 será mestre e o EEPROM será escravo. Assim, iremos escrever quaisquer dados no endereço EEPROM e ler o mesmo.
A pinagem EEPROM 24C02 é mostrada abaixo-
A0, A1 e A2 são três pinos de seleção de endereço. Os pinos WP são pinos protegidos contra gravação e precisam ser conectados ao VSS para permitir a gravação na EEPROM.
A funcionalidade de gravação de bytes é mostrada na imagem abaixo
O ciclo completo de gravação acontece com um bit de início. Depois disso, o byte de controle precisa ser enviado. No byte de controle, as seguintes coisas são necessárias-
Após o bit de início, consiste no endereço do escravo. 1010 é o estático e A0, A1 e A2 são o endereço baseado na conexão de hardware. Se os três pinos estiverem conectados com GND ou VSS, será lido como 0. Caso contrário, se conectado com VCC, será lido como 1. Em nosso caso, todos A0, A1 e A2 estão conectados com VSS. Portanto, todos esses serão 0.
Gastos na condição de leitura ou gravação. O valor do endereço com o bit de leitura ou gravação será - 0xA0 para gravação e 0xA1 para leitura. Em seguida vem o bit de Reconhecimento e em seguida será transmitido um endereço de 8 bits onde os dados devem ser armazenados e, por fim, os dados que serão armazenados no respectivo local. Essas coisas são feitas em um formato passo a passo na função principal.
Função principal e loop while:
void main (void) {char c = 0x00; InitialUART0_Timer3 (115200); TI = 1; // Importante, use a função prinft deve definir TI = 1; I2C_init (); enquanto (1) {EEPROM_write (1,0x55); c = EEPROM_read (1); printf ("\ n O valor lido é% x", c & 0xff); }; }
A função principal é simples, é continuamente escrever valores para a EEPROM no endereço 1 e ler os dados. Os dados estão sendo impressos usando a função printf. O printf está imprimindo o valor em hexadecimal.
A função de gravação da EEPROM consiste nas seguintes coisas que foram descritas na seção EEPROM-
void EEPROM_write (endereço de caracter não assinado, valor de caracter não assinado) {I2C_start (); I2C_write (0xA0); I2C_write (endereço); I2C_write (valor); I2C_stop (); }
A função de início I2C consiste nas seguintes coisas-
void I2C_start (void) {tempo int assinado = tempo limite; set_STA; clr_SI; enquanto ((SI == 0) && (tempo> 0)) {tempo--; }; }
Nesta função, o status do SI está sendo verificado junto com o período de tempo limite predefinido (definido em I2C.h onde o tempo predefinido é definido como 1000). A função de início começa com a configuração de STA e limpar o SI.
void I2C_stop (void) {tempo int assinado = tempo limite; clr_SI; set_STO; enquanto ((STO == 1) && (tempo> 0)) {tempo--; }; }
Da mesma forma que a função Iniciar, parar é usada. A função de parada é iniciada configurando o STO seguido pela limpeza do SI. A função abaixo é a função de leitura I2C-
não assinado char I2C_read (unsigned char ack_mode) {assinado int tempo = tempo limite; valor de caracteres sem sinal = 0x00; set_AA; clr_SI; enquanto ((SI == 0) && (t> 0)) {tempo--; }; valor = I2DAT; if (ack_mode == I2C_NACK) {t = timeout_count; clr_AA; clr_SI; enquanto ((SI == 0) && (t> 0)) {tempo--; }; } valor de retorno; }
O ack_mode e I2C_NACK , ambos são definidos no arquivo de cabeçalho I2C como 0 e 1 respectivamente.
Da mesma forma, a função de gravação é criada-
void I2C_write (valor de caractere sem sinal) {tempo int com sinal = tempo limite; I2DAT = valor; clr_STA; clr_SI; enquanto ((SI == 0) && (tempo> 0)) {tempo--; }; }
Piscando o código e a saída
O código retornou 0 aviso e 0 erros e foi exibido usando o método de flash padrão do Keil. Se você for novo, verifique o tutorial de introdução ao nuvoton para entender como fazer upload do código. As informações de compilação do código podem ser encontradas abaixo.
Destino de compilação 'I2C_EEPROM' compilando I2C_EEPROM.c… compilando I2C.c… vinculando… Tamanho do programa: dados = 59,2 xdata = 0 code = 2409 criando arquivo hexadecimal de ". \ Output \ I2C_EEPROM"…. \ Output \ I2C_EEPROM "- 0 Erro (s), 0 Aviso (s). Tempo de compilação decorrido: 00:00:04 Resumo da compilação em lote: 1 bem-sucedido, 0 falhou, 0 ignorado - Tempo decorrido: 00:00:04
O hardware está sendo configurado em uma placa de ensaio e está funcionando conforme o esperado. Como você pode ver na imagem abaixo, conseguimos escrever um valor na EEPROM e lê-lo da memória e exibi-lo no monitor serial.
Confira o vídeo abaixo para uma demonstração completa de como a placa funciona para este código. Espero que você tenha gostado do tutorial e aprendido algo útil se tiver alguma dúvida, deixe-os na seção de comentários abaixo. Você também pode usar nossos fóruns para postar outras questões técnicas.