/**
* @file porta_complementa_led_com_debounce.c
* @author Giovani Baratto ([email protected])
* @brief Este programa complementa o estado de um LED em PB7, a cada pulso gerado
* por uma chave de pressionar (push-button) em PB0.
* @version 0.1
* @date 2023-04-17
*/
#include <stdint.h>
#define __AVR_ATmega2560__
#include <avr/io.h>
#ifndef F_CPU /* se não foi definida a frequência de relógio do microcontrolador */
#define F_CPU 16000000UL /* definimos a frequência de relógio da placa Arduino Mega: 16 MHz */
#endif /* F_CPU*/
#include <util/delay.h> /* usamos _delay_ms(double) */
int main(void)
{
// definição das variáveis do programa
uint8_t estado_atual_chave; // o estado da chave: valor da chave sem debounce
uint8_t estado_anterior_chave; // armazena o estado anterior da chave
uint8_t leitura_atual_chave; // a leitura atual do valor da chave
uint8_t leitura_anterior_chave; // a leitura anterior do valor da chave
uint8_t chave_pressionada; // 1 se é reconhecida uma borda de descida
// configuração do sistema
DDRB = DDRB | (1 << DDB7); // fazemos PB7 uma saída
DDRB = DDRB & (~(1 << DDB0)); // fazemos PB0 uma entrada
PORTB = PORTB | (1 << PORTB0); // adicionamos um resistor de pull-up interno a PB0
// configuração das variáveis para a leitura da chave em PB0 e estado LED
leitura_atual_chave = ((PINB & (1 << PINB0)) == 0x01); // lemos o valor da chave
estado_atual_chave = leitura_atual_chave; // O estado inicial da chave é o valor da chave
PORTB = PORTB & (~(1 << PORTB7)); // inicialmente o LED está apagado.
while (1) // laço infinito com o código principal do programa
{
// faz a leitura da chave eliminando o debounce
_delay_ms(10); // esperamos um intervalo de tempo maior que o intervalo de repique da chave
leitura_anterior_chave = leitura_atual_chave; // atualizamos a leitura anterior da chave
leitura_atual_chave = ((PINB & (1 << PINB0)) == 0x01); // realizamos a leitura de PB0
estado_anterior_chave = estado_atual_chave; // atualiza o estado anterior da chave
if (leitura_atual_chave == leitura_anterior_chave) // se o sinal da chave permanece estável no intervalo
{
estado_atual_chave = leitura_atual_chave; // o estado da chave é igual ao valor da chave
}
// verificamos se a chave foi pressionada
chave_pressionada = (estado_anterior_chave == 0x01) && (estado_atual_chave == 0x00); // é uma borda de descida?
// Complementamos o LED quando a chave é pulsada
if (chave_pressionada) // se a chave foi pressionada
{
PORTB = PORTB ^ (1 << PORTB7); // complementa o estado do LED em PB7
}
}
return 0; // o programa não deve executar esta instrução
}