Categorias: Circuitos de microcontrolador
Número de visualizações: 41940
Comentários sobre o artigo: 5

Métodos para ler e gerenciar portas de E / S do Arduino

 

Para interagir com o mundo exterior, você precisa configurar as saídas do microcontrolador para receber ou transmitir um sinal. Como resultado, cada pino funcionará no modo de entrada e saída. Há duas maneiras de fazer isso em todas as placas do Arduino que você adora, exatamente como você aprende neste artigo.

Métodos para ler e gerenciar portas de E / S do Arduino

Método um - a linguagem padrão para o IDE do Arduino

Todo mundo sabe disso Arduino Está programado em C ++ com algumas adaptações e simplificações para iniciantes. É chamado de fiação. Inicialmente, todas as portas do arduino são definidas como entradas e não é necessário especificar isso no código.

As portas geralmente são escritas na função de inicialização variável:

configuração nula ()
{
// código
}

O comando pinMode é usado para isso, possui uma sintaxe bastante simples, primeiro o número da porta é indicado e, em seguida, sua função é separada por vírgulas.

pinMode (nomer_porta, naznachenie)

Com este comando, o circuito interno do microcontrolador é configurado de uma maneira específica.

Existem três modos em que a porta pode funcionar: INPUT - entrada, neste modo ocorre lendo dados de sensores, status do botão, sinal analógico e digital. A porta está localizada no chamado estado de alta impedância, em palavras simples - a entrada possui alta resistência. Este valor é definido, por exemplo, 13 pinos da placa, se necessário, da seguinte maneira:

pinMode (13, INPUT);

SAÍDA - saída, dependendo do comando prescrito no código, a porta assume o valor de um ou zero. A saída se torna um tipo de fonte de energia controlada e produz uma corrente máxima (no nosso caso, 20 mA e 40 mA no pico) conectada à carga. Para atribuir uma porta como saída ao Arduino, é necessário digitar:

pinMode (13, SAÍDA);

INPUT_PULLUP - a porta funciona como uma entrada, mas a chamada se conecta a ela. Resistor de tração de 20 kΩ.

O circuito interno condicional da porta neste estado é mostrado abaixo. Uma característica desta entrada é que o sinal de entrada é percebido como invertido (a "unidade" na entrada é percebida pelo microcontrolador como "zero"). Neste modo, você não pode usar resistores pull-up externos ao trabalhar com botões.

pinMode (13, INPUT_PULLUP);

Resistor de pull-up de entrada

Os dados são recebidos das portas e transmitidos a eles pelos comandos:

  • digitalWrite (pino, valor) - converte o pino de saída em 1 ou 0 lógico, respectivamente, a tensão de 5V aparece ou desaparece na saída, por exemplo digitalWrite (13, HIGH) - fornece 5 volts (unidade lógica) a 13 pinos e digitalWrite (13, baixa ) - converte 13 pinos em um estado de zero lógico (0 volts);

  • digitalRead (pin) - lê o valor da entrada, por exemplo digitalRead (10), lê o sinal de 10 pinos;

  • analogRead (pin) - lê um sinal analógico de uma porta analógica; você obtém um valor no intervalo de 0 a 1023 (dentro de um ADC de 10 bits); um exemplo é analogRead (3).


Método dois - gerenciar portas através de registros Atmega e acelerar o código

É claro que esse controle é simples, mas nesse caso existem duas desvantagens - maior consumo de memória e baixo desempenho ao trabalhar com portas. Mas lembre-se do que é o Arduino, independentemente da placa opcional (uno, micro, nano)? Primeiro de tudo, isso família AVR de microcontrolador ATMEGA, recentemente usado MK atmega328.

No IDE do Arduino, você pode programar no idioma nativo para esta família de C AVR, como se estivesse trabalhando com um microcontrolador separado. Mas as primeiras coisas primeiro. Para gerenciar portas Arduino dessa maneira, primeiro você deve considerar cuidadosamente a ilustração a seguir.

Portas do microcontrolador Atmega168

Talvez alguém examine mais claramente as portas neste formulário (o mesmo na figura, mas em um design diferente):

Portas do microcontrolador Atmega328

Aqui você vê a correspondência das conclusões do Arduino e os nomes dos portos do Atmega. Então, nós temos 3 portas:

  • PORTB;

  • PORTC;

  • PORTD.

Com base nas imagens mostradas, compilei uma tabela de correspondência entre os portos do Arduino e do Atmega, que será útil para você no futuro.

Tabela de concordância dos portos Arduino e Atmega

A Atmega possui três registradores de 8 bits que controlam o estado das portas, por exemplo, a porta B descobrirá seu objetivo traçando analogias com as ferramentas de fiação padrão descritas no começo deste artigo:

  • PORTB - Gerenciar status da saída. Se o pino estiver no modo "Saída", 1 e 0 determinam a presença dos mesmos sinais na saída. Se o pino estiver no modo "Entrada", 1 conectará um resistor pull-up (o mesmo que o INPUT_PULLUP discutido acima), se 0 for um estado de alta impedância (análogo de INPUT);

  • PINB é um registro de leitura. Consequentemente, ele contém informações sobre o estado atual dos pinos da porta (unidade lógica ou zero).

  • DDRB - registro de direção da porta. Com ele, você indica ao microcontrolador qual é a porta como entrada ou saída, com "1" uma saída e "0" uma entrada.

Em vez da letra "B", pode haver qualquer outro de acordo com os nomes das portas, por exemplo, PORTD ou PORTC outros comandos funcionam de maneira semelhante.

Piscamos o LED, substituímos a função digitalWrite () padrão. Primeiro, vamos lembrar como é o exemplo original da biblioteca IDE do Arduino.

Código intermitente LED do Arduino

Este é o código do conhecido "piscar", que mostra o piscar do LED embutido na placa.

Gerenciamento de pinos

Os comentários explicam o código. A lógica deste trabalho é a seguinte.

O comando PORTB B00100000 coloca o PB5 no estado de uma unidade lógica, aparência e essas imagens e a tabela abaixo estão localizadas e vemos que o PB5 corresponde a 13 pinos da Arduina.

A letra "B" na frente dos números indica que estamos escrevendo os valores em formato binário. A numeração em binário vai da direita para a esquerda, ou seja, aqui a unidade está no sexto bit a partir da borda direita do bit, que informa ao microcontrolador sobre a interação com o estado do sexto bit do registro da porta B (PB5). A tabela abaixo mostra a estrutura da porta D, é semelhante e é fornecida como exemplo.

Estrutura da porta D

Você pode definir o valor não em binário, mas em formato hexadecimal, por exemplo, para isso, abrimos a calculadora do Windows e, no modo "VIEW", selecione a opção "Programmer".

Calculadora do Windows

Digite o número desejado:

Modo Calculadora Programador

E clique em HEX:

Tradução de números em uma calculadora

Nesse caso, transferimos tudo isso para o IDE do Arduino, mas em vez do prefixo "B" será "0x".

Transferência de número no IDE do Arduino

Mas com esta entrada, há um problema. Se houver algo conectado a outros pinos, digite um comando como B00010000 - você redefinirá todos os pinos, exceto 13 (PB5). Você pode inserir dados para cada pino individualmente. Ficará assim:

Inserindo dados em cada pino

Esse registro pode parecer incompreensível, vamos descobrir.

Analisando um registro

Esta é uma operação de adição lógica, | = significa adicionar algo ao conteúdo da porta.

Operação de adição lógica

Isso significa que você precisa adicionar uma palavra de 8 bits no registro com uma unidade deslocada em 5 bits - como resultado, se 11000010 for 110.110.010. Neste exemplo, pode-se observar que apenas o PB5 mudou, os bits restantes desse registro permaneceram inalterados, assim como O estado dos pinos do microcontrolador permaneceu inalterado.

Mas com a adição lógica, surge um problema - você não pode transformar a unidade em zero, porque:

0+0=1

1+0=1

0+1=1

A multiplicação e inversão lógica virão em nosso auxílio:

Multiplicação lógica e inversão

& = significa multiplicar o conteúdo da porta por um número específico.

 

Multiplicando o conteúdo da porta por um número

E este é o número pelo qual multiplicamos. O sinal “~” indica inversão. No nosso caso, a unidade invertida é zero. Ou seja, multiplicamos o conteúdo da porta por zero, deslocados por 5 bits. Por exemplo, era 10110001, tornou-se 10100001. Os bits restantes permaneceram inalterados.

Multiplique o conteúdo da porta por zero e deslocado por 5 bits

O mesmo pode ser feito usando a operação invertida (^):

Lendo de portas, o analógico de digitalRead () é realizado usando o registro PIN, na prática, é assim:

Ler a partir de portas

Aqui, verificamos se a expressão entre parênteses é igual ao estado real das portas, ou seja, Da mesma forma, se escrevemos if (digitalRead (12) == 1).


Conclusão

Por que existem dificuldades no gerenciamento de portas se você pode usar funções convenientes padrão? É tudo sobre velocidade e tamanho do código. Ao usar o segundo método, discutido no artigo, o tamanho do código é significativamente reduzido e a velocidade aumenta em várias ordens de magnitude. O digitalWrite () padrão foi executado em 1800 μs e gravando diretamente na porta em 0,2 μs, e digitalRead () em 1900 μs e também se tornou em 0,2 μs. Esse método de controle foi encontrado nos espaços abertos da rede e geralmente é encontrado no código. projetos finalizados.

Veja também em bgv.electricianexp.com:

  • Conectando e programando o Arduino para iniciantes
  • Como conectar o codificador incremental ao Arduino
  • Microcontroladores PIC para iniciantes
  • Microcontrolador Controle Remoto: IR Remote, Arduino, ESP8266, 433 ...
  • Medindo temperatura e umidade no Arduino - uma seleção de métodos

  •  
     
    Comentários:

    # 1 escreveu: Kipovets | [citação]

     
     

    "Mas com a adição lógica, surge um problema - você não pode transformar a unidade em zero, porque:

    0 + 0 = 1 "(c)

    Pequena supervisão: 0 + 0 = 0.

     
    Comentários:

    # 2 escreveu: chugou | [citação]

     
     

    Kipovets, ele provavelmente queria dizer:

    1 + 1 = 1

     
    Comentários:

    # 3 escreveu: | [citação]

     
     

    Kipovets,
    Erro de banal! Você vê como é bom que os especialistas estejam no nosso portal! Você precisa criar apenas conteúdo adequado!

     
    Comentários:

    # 4 escreveu: Serg | [citação]

     
     

    Na parte final, diz PORTB | = 1 << 5 ... if (digitalRead (12) == 1). Mas 5 pinos da porta B, são 13 pinos do arduino. Ou estou enganado ?!

     
    Comentários:

    # 5 escreveu: p-a-h-a | [citação]

     
     

    Se (PINB == B00010000) {} não estiversemelhante a se escrevemos if (digitalRead (12) == 1)
    bastante analógico
    (digitalRead (12) == 1) &&(digitalRead (13) == 1) &&(digitalRead (14) == 1) &&(digitalRead (15) == 1) &&(digitalRead (11) == 1) ... e mais 8 pinos de porta

    Aqui você precisa disso:
    se (
    ! (~ PORTB & (1 << PB4))) {} //retorna0 ou 1
    ou assim:
    se (PORTB & (1 << PB4)) {} // retorna a unidade deslocada = 16, DEC
    ou assim:
    se (
    bit_is_set (PORTB, 4)) {}// retorna a unidade deslocada = 16, DEC