Índice:

Microcontrolador AVR. Alterne os LEDs usando um botão de pressão. Botão Debouncing: 4 etapas
Microcontrolador AVR. Alterne os LEDs usando um botão de pressão. Botão Debouncing: 4 etapas

Vídeo: Microcontrolador AVR. Alterne os LEDs usando um botão de pressão. Botão Debouncing: 4 etapas

Vídeo: Microcontrolador AVR. Alterne os LEDs usando um botão de pressão. Botão Debouncing: 4 etapas
Vídeo: AVR Microcontroller. Toggle LED’s using a Push Button Switch. Push Button Debouncing. 2024, Julho
Anonim
Image
Image

Nesta seção, aprenderemos como fazer o código do programa C para ATMega328PU para alternar o status dos três LEDs de acordo com a entrada de uma chave de botão. Além disso, exploramos uma solução para o problema de ‘Switch Bounce’. Como de costume, vamos montar o circuito elétrico na base do AVR ATmega328 para verificar o funcionamento do código do programa.

Etapa 1: Escrevendo e construindo um aplicativo de microcontrolador AVR em código C usando a plataforma de desenvolvimento integrada Atmel Studio 7

Escrevendo e construindo um aplicativo de microcontrolador AVR em código C usando a plataforma de desenvolvimento integrada Atmel Studio 7
Escrevendo e construindo um aplicativo de microcontrolador AVR em código C usando a plataforma de desenvolvimento integrada Atmel Studio 7
Escrevendo e construindo um aplicativo de microcontrolador AVR em código C usando a plataforma de desenvolvimento integrada Atmel Studio 7
Escrevendo e construindo um aplicativo de microcontrolador AVR em código C usando a plataforma de desenvolvimento integrada Atmel Studio 7
Escrevendo e construindo um aplicativo de microcontrolador AVR em código C usando a plataforma de desenvolvimento integrada Atmel Studio 7
Escrevendo e construindo um aplicativo de microcontrolador AVR em código C usando a plataforma de desenvolvimento integrada Atmel Studio 7

Se você não tem o Atmel Studio, deve baixá-lo e instalá-lo.

www.microchip.com/mplab/avr-support/atmel-studio-7

Nas primeiras linhas, temos algumas definições do compilador.

F_CPU define a frequência do clock em Hertz e é comum em programas que usam a biblioteca avr-libc. Nesse caso, ele é usado pelas rotinas de atraso para determinar como calcular os atrasos de tempo.

#ifndef F_CPU

#define F_CPU 16000000UL // informando a frequência de cristal do controlador (16 MHz AVR ATMega328P) #endif

#include // cabeçalho para habilitar o controle do fluxo de dados sobre os pinos. Define pinos, portas, etc.

O primeiro arquivo de inclusão é parte do avr-libc e será usado em praticamente qualquer projeto AVR em que você trabalhar. io.h determinará a CPU que você está usando (é por isso que você especifica a parte ao compilar) e, por sua vez, inclui o cabeçalho de definição de IO apropriado para o chip que estamos usando. Ele simplesmente define as constantes para todos os seus pinos, portas, registros especiais, etc.

#include // cabeçalho para habilitar a função de atraso no programa

A biblioteca util / delay.h contém algumas rotinas para pequenos atrasos. A função que usaremos é _delay_ms ().

Usamos define para declarar nosso botão e portas e pinos de LED. Usar as instruções define como essa nos permite modificar apenas 3 linhas fáceis de localizar se movermos o LED para um pino de E / S diferente ou usarmos um AVR diferente.

# define BUTTON1 1 // botão interruptor conectado à porta B pino 1

# define LED1 0 // Led1 conectado na porta B pino 0 # define LED2 1 // Led2 conectado na porta C pino 1 # define LED3 2 // Led3 conectado na porta D pino 2

As duas últimas definem os tempos de configuração das declarações, em milissegundos, para eliminar o switch e o tempo de espera antes de permitir outro pressionamento do botão. O tempo de debounce precisa ser ajustado para o tempo que leva para a mudança passar de um digital alto para um digital baixo após todo o salto. O comportamento de salto difere de switch para switch, mas 20-30 milissegundos normalmente é suficiente.

#define DEBOUNCE_TIME 25 // tempo para esperar enquanto o botão "de-bouncing"

#define LOCK_INPUT_TIME 300 // tempo para esperar após um pressionamento de botão

void init_ports_mcu ()

{

Esta função é chamada apenas uma vez no início do nosso programa para inicializar os pinos de entrada e saída que iremos usar.

Para o botão, usaremos os registradores PORT e PIN para escrita e leitura. Com AVRs, lemos um pino usando seu registro PINx e gravamos em um pino usando seu registro PORTx. Precisamos escrever no registrador do botão para habilitar os pull-ups.

Para o LED, só precisamos usar o registrador PORT para gravar, no entanto, também precisamos do registrador de direção de dados (DDR), pois os pinos de E / S são configurados como entradas por padrão.

Primeiro, estamos configurando os pinos de E / S do LED como uma saída usando seu registrador de direção de dados.

DDRB = 0xFFu; // Defina todos os pinos da PORTB como saída.

Em seguida, defina explicitamente o pino do botão como uma entrada.

DDRB & = ~ (1 <

Em seguida, os pinos PORTB são definidos como altos (+5 volt) para ligá-lo. Os pinos de saída são inicialmente altos e, como nosso LED está com a fiação ativo-alto, ele será ligado, a menos que o desligemos explicitamente.

E, finalmente, habilitamos o resistor pull-up interno no pino de entrada que estamos usando para o nosso botão. Isso é feito simplesmente enviando um para a porta. Quando configurado como uma entrada, isso resulta na ativação de pull-ups e, quando configurado como uma saída, isso simplesmente geraria uma alta tensão.

PORTB = 0xFF; // Defina todos os pinos do PORTB como HIGH. Led aceso, // também o resistor pull up interno do primeiro pino PORTB está habilitado. DDRC = 0xFFu; // Defina todos os pinos do PORTC como saída. PORTC = 0x00u; // Defina todos os pinos de PORTC para baixo, o que o desliga. DDRD = 0xFFu; // Defina todos os pinos do PORTD como saída. PORTD = 0x00u; // Defina todos os pinos de PORTD baixos, o que o desliga. }

unsigned char button_state ()

{

Esta função retorna um valor booleano indicando se o botão foi pressionado ou não. Este é o bloco de código com o qual está continuamente sendo executado no loop infinito e, portanto, está pesquisando o estado do botão. É aqui também que eliminamos o switch.

Agora, lembre-se de que quando pressionamos o botão, o pino de saída de entrada é puxado para o solo. Portanto, estamos esperando que o pino abaixe.

/ * o botão é pressionado quando o bit BUTTON1 é limpo * /

if (! (PINB & (1 <

Fazemos isso verificando se o bit está claro. Se o bit estiver limpo, indicando que o botão está pressionado, primeiro atrasamos a quantidade de tempo definida por DEBOUNCE_TIME que é 25ms e, em seguida, verificamos o estado do botão novamente. Se o botão for pressionado após os 25ms, o switch é considerado como depurado e pronto para acionar um evento e, portanto, retornamos 1 à nossa rotina de chamada. Se o botão não estiver pressionado, retornamos 0 à nossa rotina de chamada.

_delay_ms (DEBOUNCE_TIME);

if (! (PINB & (1 <

int main (vazio)

{

Nossa principal rotina. A função principal é única e diferenciada de todas as outras funções. Cada programa C deve ter exatamente uma função main (). main é onde o AVR começa a executar seu código quando a energia é ligada pela primeira vez, então é o ponto de entrada do programa.

caractere sem sinal n_led = 1; // inicialmente o número do LED está ligado agora

Chamada da função para inicializar os pinos de I / O que estão sendo usados:

init_ports_mcu ();

loop infinito onde nosso programa é executado:

enquanto (1)

{

Quando o button_state retorna um indicando que o botão foi pressionado e depurado, alternando o status atual dos LEDs por sua vez de acordo com o parâmetro n_led.

if (button_state ()) // Se o botão for pressionado, alterna o estado do LED e o retardo por 300ms (#define LOCK_INPUT_TIME)

{switch (n_led) {case 1: PORTB ^ = (1 << LED1); PORTC ^ = (1 << LED2); pausa;

Essas instruções usam operadores C bit a bit. Desta vez, ele está usando o operador OR exclusivo. Quando você XOR a PORTA com o valor do bit do bit que deseja alternar, esse bit é alterado sem afetar os outros bits.

caso 2:

PORTC ^ = (1 << LED2); PORTD ^ = (1 << LED3); pausa; caso 3: PORTD ^ = (1 << LED3); PORTB ^ = (1 << LED1); n_led = 0; // redefine a quebra do número do LED; } n_led ++; // próximo LED é ligado _delay_ms (LOCK_INPUT_TIME); }} return (0); }

Portanto, agora, ao executar este programa, você poderá pressionar o botão de pressão para que os LEDs se alternem. Devido ao nosso atraso definido por LOCK_INPUT_TIME, você pode pressionar e segurar o botão que fará com que os LEDs desliguem e liguem em uma taxa consistente (pouco mais do que a cada 275ms).

A programação está completa.

O próximo passo é construir o projeto e programar o arquivo hexadecimal no microcontrolador usando o programa avrdude.

Você pode baixar o arquivo main.c com o programa no código c:

Etapa 2: Transferir o arquivo HEX do programa para a memória flash do chip

Transferindo o arquivo HEX do programa para a memória flash do chip
Transferindo o arquivo HEX do programa para a memória flash do chip
Transferindo o arquivo HEX do programa para a memória flash do chip
Transferindo o arquivo HEX do programa para a memória flash do chip

Baixe e instale o AVRDUDE. A última versão disponível é 6.3: Baixe o arquivo zip

Primeiro, copie o arquivo hexadecimal do programa para o diretório AVRDUDE. No meu caso é ButtonAVR.hex

Em seguida, digite na janela do prompt do DOS o comando: avrdude –c [nome do programador] –p m328p –u –U flash: w: [nome do arquivo hexadecimal].

No meu caso é: avrdude –c ISPProgv1 –p m328p –u –U flash: w: ButtonAVR.hex

Este comando grava o arquivo hexadecimal na memória do microcontrolador.

Assista ao vídeo com uma descrição detalhada da gravação da memória flash do microcontrolador:

Gravando memória flash do microcontrolador …

OK! Agora, o microcontrolador funciona de acordo com as instruções do nosso programa. Vamos dar uma olhada!

Etapa 3: Debouncing de troca de hardware

Hardware Switch Debouncing
Hardware Switch Debouncing

Além de debouncing de switch de software, podemos usar a técnica de debouncing de switch de hardware. A ideia básica por trás dessa técnica é usar um capacitor para filtrar mudanças rápidas no sinal de comutação.

Qual valor de capacitor deve ser selecionado? Em última análise, isso dependerá do desempenho insatisfatório do botão em relação a esse problema específico. Alguns botões podem exibir um comportamento de salto tremendo, mas outros terão muito pouco. Um valor baixo de capacitor como 1,0 nanofarads vai reagir muito rapidamente, com pouco ou nenhum efeito no salto. Por outro lado, um valor de capacitor mais alto, como 220 nanofarads (que ainda é muito pequeno em termos de capacitores), fornecerá uma transição lenta da tensão inicial para a tensão final (5 volts a 0 volts). A transição vista com uma capacidade de 220 nanofarads ainda é muito rápida no sentido do mundo real e, portanto, pode ser usada em botões de baixo desempenho.

Etapa 4: Circuito Elétrico

Circuito elétrico
Circuito elétrico
Circuito elétrico
Circuito elétrico
Circuito elétrico
Circuito elétrico

Conecte os componentes de acordo com o diagrama esquemático.

Recomendado: