Uso de registradores na IDE Arduino

Uso de registradores na IDE Arduino 7

A linguagem Wiring, utilizada para programação na IDE Arduino, traz diversos comandos que facilitam a configuração e uso de pinos. Neste artigo, iremos mais a fundo com uso de registradores, que trazem algumas otimizações para os códigos e execução de comandos.

Lista de materiais

Pinos do Arduino Uno

O cérebro do Arduino é o seu microcontrolador, no caso do Arduino Uno, é o ATMega328p. É ele que armazena os programas, contém a memória e possui os pinos de entrada/saída que utilizamos na placa.

Estes pinos de entrada/saída também são conhecidos como GPIO (sigla para General Purpose Input Output ou entrada/saída de uso geral). Cada microcontrolador contém um número de GPIOs que podem ser utilizadas para diversos propósitos, conforme programação.

A placa Arduino Uno possui os pinos digitais identificados de 0 a 13 e analógicos de A0 a A5. Mas a arquitetura do microcontrolador pode dar outra nomenclatura aos pinos que conhecemos. Confira a placa Arduino Uno em detalhes conforme a próxima figura.

Uso de registradores na IDE Arduino

Repare na figura acima que os pinos que conhecemos como digitais estão como Dx (digitais) ou Ax (analógicos), sendo x um número. Porém, ao lado de cada pino há uma outra nomenclatura para acessar os mesmos pinos.

Os microcontroladores podem ter seus GPIOs divididos em ports, um conjunto de pinos que podem ser configurados ou acessados de uma só vez. O ATMega328p possui três conjuntos:

  • PORTB: PB0 a PB5 (8 a 13)
  • PORTC: PC0 a PC5 (A0 a A5)
  • PORTD: PD0 a PD7 (0 a 7)

Então, para acessar/configurar o pino 9 digital do ATMega328p, utilizamos a nomenclatura PB1. Este acesso ou configuração é feito a partir dos registradores.

OBS: Cada microcontrolador possui diferentes conjuntos de ports e quantidade de GPIOs. Portanto, outras versões de Arduino como Mega 2560, Leonardo e outras placas não coincidem com as nomenclaturas dos pinos do Arduino Uno. Consulte na internet o microcontrolador da placa que você fará uso.

Configuração por registradores

Os comandos para registradores são baseados na linguagem C. Fazem um outro caminho para configurar pinos, diferente dos comandos já utilizados em Wiring. Eles realizam esta configuração de forma mais segura e rápida. Utilizaremos três tipos específicos de registradores:

  • PORTx: registrador de dados, usado para escrever no port ou pino em específico. x representa os ports disponíveis no microcontrolador, que no caso do ATMega328p, são os ports B, C e D;
  • DDRx: registrador de direção, usado para ler a entrada de um port ou pino em específico. No caso do ATMega328p, x representa os ports B, C e D;
  • PINx: endereço de entrada do pino, usado para configurar um port inteiro ou pino será entrada ou saída.

Usando os registradores, podemos substituir alguns comandos em Wiring, tornando nosso código mais rápido e mais leve.

DDRx PORTxn Comando Wiring Versão registradores
0 0 pinMode(pino, INPUT); DDRx = DDRx &~ (1<<DDxn);

PORTx = PORTx &~ (1 << Pxn);

0 1 pinMode(pino, INPUT_PULLUP); DDRx = DDRx &~ (1<<DDxn);

PORTx = PORTx | (1 << Pxn);

1 pinMode(pino, OUTPUT); DDRx = DDRx | (1<<DDxn);
0 ou ≠0 Y = digitalRead(pino); Y = PINn & (1 << Pxn);
1 1 digitalWrite (pino, HIGH); PORTx = PORTx | (1 << Pxn);
1 0 digitalWrite (pino, LOW); PORTx = PORTx &~ (1 << Pxn);

Onde:

x: letra referente ao port;

n: número do pino do port (conjunto);

Y = variável qualquer para armazenar dado.

Os comandos na versão registradores possuem a característica de trabalhar por operadores de bits, ou seja, manipulam 0 e 1. As operações realizadas nos comandos são:

  • | (barra horizontal): operador OU, no caso dos registradores ativa o bit em nível 1 (HIGH);
  • & (E comercial): operador E, no caso dos registradores desativa o bit em nível 0 (LOW);
  • ~ (til): operador NÃO, realiza o complemento de bits. O que era 1 vira 0 e vice-versa;
  • ^ (circunflexo): operador OU EXCLUSIVO, no caso dos registrado serve para inversão de alguns bits;
  • >> (dois sinais de maior): deslocamento de bits para a direita, insere zeros à esquerda;
  • << (dois sinais de menor): deslocamento de bits para a esquerda, insere zeros à direita.

Exemplo 1:

Para configurar o pino 7 do Arduino Uno como saída, precisamos encontrar a nomenclatura usada pelo microcontrolador.

Uso de registradores na IDE Arduino

O nome do pino 7 do Arduino é PD7. Então, o comando usando registrador é:

DDRD = DDRD |(1 << DDD7);

No comando acima foi usado o registrador de direção DDR no port D em PD7. É equivalente ao comando pinMode(7, OUTPUT);

Exemplo 2:

Para escrever LOW pino 12 do Arduino Uno, mais uma vez vamos encontrar a nomenclatura equivalente do microcontrolador:

Uso de registradores na IDE Arduino

O nome do pino 12 do Arduino é PB4. Então, o comando usando registrador é:

PORTB = PORTB &~ (1<< PB4);

No comando acima foi usado o registrador de dados PORT no port B em PB4. É equivalente ao comando digitalWrite(12, LOW);

Exemplo 3:

Faremos de forma visual a comparação entre os comandos usados em Wiring e os registradores em C usando um osciloscópio. No sketch de exemplo, faremos uso do pino A3 como digital 17.

Uso de registradores na IDE Arduino

O pino digital 17 vai oscilar entre LOW e HIGH duas vezes usando registradores e também com o comando digitalWrite, sem uso de delay, para vermos o tempo de execução de cada um. Utilize o código abaixo:

// Comparação entre Wiring e registradores em C
void setup() {
  // Habilita porta PC3 como saída
  DDRC = DDRC |(1 << DDC3);
  // Habilita porta PC3 em nível HIGH
  PORTC = PORTC | (1<< PC3);
}
void loop() {
  // Comandos para pino A3 (ou D17) com registradores 
  PORTC = PORTC | (1<< PC3); // Nível HIGH
  PORTC = PORTC &~ (1<< PC3); // Nível LOW
  PORTC = PORTC | (1<< PC3);
  PORTC = PORTC &~ (1<< PC3);
  // Comandos Wiring para pino A3 (D17)
  digitalWrite(17, HIGH); // Nível HIGH
  digitalWrite(17, LOW); // Nível LOW
  digitalWrite(17, HIGH);
  digitalWrite(17, LOW);
} // Fim do sketch

Realize a montagem conforme figura a seguir:

Uso de registradores na IDE Arduino

Configurações do osciloscópio:

CH1 (canal 1): 2V/div.

Horizontal: 1.00 μs/div.

Coloque a ponta de prova nos jumpers e encaixe no Arduino. A ponta de prova utilizada possui um “gancho” na sonda de prova (pino A3) e uma garra jacaré no GND (terra).

Uso de registradores na IDE Arduino

Para melhor visualização, a imagem foi pausada no osciloscópio usando o botão RUN/STOP, conforme figura a seguir:

Uso de registradores na IDE Arduino

Na tela é possível verificar uma onda quadrada com uma rápida oscilação. Na figura seguinte estão em destaque os tempos utilizados com uso de digitalWrite e registradores:

Uso de registradores na IDE Arduino

Para executar um dos digitalWrite do código, o Arduino levou mais de 3 μs (conforme quantidade de quadrados na horizontal). Já a execução com uso de registradores levou aproximadamente um quinto da escala horizontal, estimadamente 200 ns ou 0,2 μs.

Mais vantajoso configurar e escrever diretamente nos pinos usando estes comandos nos registradores para otimização de projetos. Apesar dos comandos serem mais difíceis de lembrar do que os conhecidos digitalWrite e pinMode, vimos no exemplo anterior que o tempo para execução do comando é bem maior se comparar com a execução dos comandos nos registradores.

Gostou de conhecer sobre o uso de registradores no Arduino? O seu sketch pode ser muito mais rápido e leve com a utilização destes comandos em C. Deixe seu comentário logo abaixo se gostou do artigo.

Faça seu comentário

Acesse sua conta e participe

7 Comentários

  1. E se fosse para leitura de uma entrada analogica como ficaria?

    1. Olá Eduardo,

      Não temos ainda em nosso blog conteúdo sobre a leitura analógica, mas ela é um pouco mais complexa. Aqui um vídeo (em inglês) mostrando como ela funciona: https://www.youtube.com/watch?v=ettV5zorZfQ

      Abraços!
      Vinícius – Equipe MakerHero

  2. Parabéns!! Ainda sinto muita dificuldade em trabalhar com registradores, mas é algo que me fascina. Excelente artigo.

  3. Excelente artigo! Muito útil e eficaz! Com certeza vai ajudar muita gente pois quase ninguém explica bem e de forma tão clara e objetiva assim esses assuntos. Já ouvi muito sobre os registradores mas nunca tinha parado para estudar eles. Com esse artigo será um excelente pontapé inicial. Obrigado!

  4. Parabéns… quem precisa de agilidade e aproveitar ao máximo o clock é uma excelente saída.

  5. Muito interessante, embora já ter usado sem o menor menor conhecimento quando programei em ladder para executar no arduíno.
    Legal, parabéns.

  6. Amei o artigo, bom didática