Como leio a entrada digital no ATmega16?

18

O que preciso fazer para ler uma entrada digital (botão) no ATmega16 ? Preciso habilitar resistores de pullup ou posso usar um de 10 kohm? Qual seria um código simples? Apenas um simples "acenda o LED quando estiver pressionado".

Existe um tutorial para iniciantes? Eu tentei pesquisar no Google e no AVR Freaks , mas tudo acaba evoluindo para uma luta lá e não recebo minha resposta. Eu realmente não encontrei nenhum tutorial sobre esse assunto. Toneladas de coisas específicas, mas nada simples sobre o meu microcontrolador AVR ...

curioso
fonte
4
Isso seria respondido em praticamente qualquer tutorial para iniciantes, e temo que uma resposta completa aqui prejudique sua compreensão mais do que ajuda. Que esforço prévio você fez para aprender?
precisa
Não tenho certeza se você viu meu post ou consegue vê-lo (desculpe, ainda que meio confuso sobre este site ...) Mas eu sei o código, digamos que minha pergunta é: basta conectar um pino ao GND e está baixo?
curioso
2
Por que não editar sua postagem para refletir isso com mais precisão e incluir também a postagem abaixo na postagem original.
Amos
Experimente o Tutorial do AVR do zero a partir desta página do AVR Freaks. Você encontrará muito mais coisas lá.
Leon Heller

Respostas:

24

Saudações brasileiras!

Antes de tudo, agradeça a Joby pelo seu exemplo. Em segundo lugar, seu exemplo tem apenas um pequeno erro. O número 0x20 não está correto. Deve ser 0x04. Além disso, apenas como sugestão, eu não usaria números hexadecimais como 0xFB, 0x20 ou 0x04 no código. Eu sugeriria usar as definições de porta PIN encontradas no io.he outras referenciadas pelo arquivo de cabeçalho. Reescrevi o exemplo de Joby abaixo, com alguns comentários para os iniciantes.

# include <avr/io.h>

int main (void)
{
    // set all pins on PORTB for output
    DDRB = 0xFF;

    // set port pin PORTD2 as input and leave the others pins 
    // in their originally state (inputs or outputs, it doesn't matter)
    DDRD &= ~(1 << PD2);        // see comment #1

    while (1) 
    {
        if (PIND & (1<<PD2))    // see comment #2
            PORTB |= (1<<PB2);  // see comment #3
        else
            PORTB &= ~(1<<PB2); // see comment #4
    }
    return 0;
}

/ *

comentários para iniciantes

comentário # 1: (1 << PD2) gera o binário 00000100. A operação "~" inverte todos os dígitos, ou seja, o binário agora é 11111011. Finalmente, o & = aplica a lógica "AND" entre DDRD e 11111011 e o resultado é colocado novamente na memória DDRD. Nota: O que o operador "AND" faz é para cada bit na memória DDRD, comparado com o número binário acima. Se o bit no DDRD for 0 e o bit no binário na mesma posição da picada for 1, o bit resultante será 0, se o DDRD for 1 e o bit no binário for 1, o bit resultante será 1 e se o bit no DDRD é 1 ou 0 e o bit no binário é 0, o bit resultante é sempre 0. Em resumo, o comando DDRD & = ~ (1 << PD2) altera apenas o bit PD2 para zero e deixa os outros (zeros ou uns) intocados. Parece um pouco complicado, mas depois que você se acostuma, é a melhor maneira de mudar um pouco sem alterar os outros bits.

comentário nº 2 : (1 << PD2) gera o 00000100 binário. Usando a mesma lógica "AND" descrita no comentário nº 1, o comando "PIND & 0000100" verifica apenas se o PIND2 (nosso pino de entrada onde o botão está conectado para) está definido como alto ou não. Todos os outros pinos serão FALSE, pois os bits binários estão definidos como 0 e, como o bit binário # 2 está definido como 1, a instrução IF será TRUE somente se a entrada PD2 estiver definida como alta ou FALSE se a entrada PD2 for definido para baixo.

comentário 3 : Seguindo a lógica explicada no comentário 1, este comando define o pino de saída PINB2 na porta PORTB para alta tensão. Se o seu LED estiver correto conectado a essa porta de pinos com um resistor de ~ 300 ohms e esse resistor estiver conectado ao terra, o LED deverá acender.

comentário nº 4 : O LED deve desligar pelos mesmos motivos explicados nos comentários anteriores.

Considerações finais:

a) Para evitar oscilação de tensão no pino de entrada PD2 quando o botão não é pressionado (circuito aberto), recomendo colocar um resistor de pull-down (1 kOhm ou superior), para que o LED não acenda acidentalmente devido a essa oscilação aleatória de tensão.

b) Uma nota de isenção de responsabilidade: As idéias descritas aqui devem ser usadas apenas como educacionais e NÃO devem ser usadas em nenhum sistema real antes de consultar um especialista em eletrônica.

* /

Comunidade
fonte
3
Não recomendo que você forneça seu email porque a correspondência por email torna a comunicação privada. Então ninguém mais pode se beneficiar. Mas se você realmente deseja fornecer seu email para comunicações privadas, o melhor lugar para fazer isso é no seu perfil.
Daniel Grillo
Não é vice-versa - # 3 desliga o led, # 4 liga o led?
sitilge
2

https://www.mainframe.cx/~ckuethe/avr-c-tutorial/

https://www.mainframe.cx/~ckuethe/avr-c-tutorial/#digital-in

#include <avr/io.h>

/*
 * Assumptions:
 *  - LED connected to PORTB.2
 *  - Switch connected to PORTD.2
 */

int main (void)
{
    /* set PORTB for output*/
    DDRB = 0xFF;
    /* set PORTD for input*/
    DDRD &= 0xFB;
    PORTD |= 0x04;

    while (1) {
        if (PIND & 0x04)
            PORTB &= ~0x20;
        else
            PORTB |= 0x20;
    }
    return 0;
}
Toby Jaffey
fonte
Agradeço a @joby Taffey pelo link fornecido. Eu estava procurando por funções EEPROM e recebi muita ajuda de: mainframe.cx/~ckuethe/avr-c-tutorial/lesson11.c Muito obrigado.
Bishal Paudel 18/10/11
0

Outra coisa a considerar ao lidar com uma entrada digital de um comutador mecânico é o retorno dos contatos - mudando o que deve ser um único botão para o que se parece com vários toques.

Para algo como acender um LED quando o botão é pressionado, você provavelmente não precisa se preocupar com a devolução. Para algo um pouco mais complicado (como alternar o LED no pressionamento de botão), a renúncia é uma obrigação.

Jack Ganssle tem um bom Guia para Debouncing

Mike
fonte