#include <stdint.h>
#include <sys/types.h>
#include "usart.h" /* incluímos o arquivo cabeçalho com o protótipo dos procedimentos para a USART0 */
#define __AVR_ATmega2560__ /* programa para o microcontrolador ATmega2560 */
#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 <avr/io.h> /* definições das entradas e saídas */
#include <avr/pgmspace.h> /* usamos procedimentos que acessam a memória FLASH: pgm_read_byte()*/
#include <stdlib.h> /* usamos os procedimentos não padrão utoa e dtostre */
#include <util/delay.h> /* usamos _delay_ms(double) */
/*Conecte uma chave de pressionar (tipo push-button) em PB0. Escreva um programa que
envie pelo terminal serial USART0 uma mensagem para você entrar com o seu nome,
sempre que a chave tipo push-button é pressionada. Após você digitar em um terminal o
seu nome, será recebida a mensagem “Seu nome é: ”, seguido do nome que foi digitado.*/
/**
* @brief Este procedimento recebe uma string da USART0 até preenchermos um buffer.
A string é enviada pelo terminal quando pressionamos a tecla enter do
teclado, enviando o caractere nova linha, 0x0A.
*
* @param buffer Um ponteiro para um buffer. O buffer guarda os caracteres recebidos
* pela USART0 e o caractere nulo, '\0', marcando o final da string.
* @param tamanho Tamanho do buffer, em bytes.
*/
void USART0_recebe_string(uint8_t* buffer, uint8_t tamanho) {
char ch; // armazena o caractere lido da USART0
uint8_t* ptr_fim_buffer; // apontador para o final do buffer, antes do caractere nulo
ptr_fim_buffer = &buffer[tamanho - 1]; // apontamos para o último caratere do buffer antes do nulo
while (1) { // repita
ch = USART0_recebe(); // ch armazena um caractere lido da USART0
if (ch == 0x0A) { // se o caractere é um nova linha (tecla enter)
break; // termina o recebimento dos caracteres pela USART0
}
if (buffer < ptr_fim_buffer) { // enquando não chegamos no final do buffer
*buffer = ch; // adicione o caractere lido da USART0 no buffer
buffer++; // aponte para a próxima entrada do buffer
}
}
*buffer = '\0';
}
/**
* @brief Configuramos PB0 como uma entrada com resistor de pull-up
*/
void portas_configura(void) {
DDRB = DDRB & (~(1 << DDB0)); // fazemos PB0 uma saída
PORTB = PORTB | (1 << PORTB0); // Adicionamos um resistor de pull-up em PB0
}
void leia_envie_seu_nome_usart0(void) {
const uint8_t tamanho_buffer = 16; // tamanho do buffer
uint8_t buffer[tamanho_buffer]; // buffer para receber dados da USART0
USART0_transmite_string_FLASH(PSTR("Digite o seu nome: "));
USART0_recebe_string(buffer, tamanho_buffer);
USART0_transmite('\n');
USART0_transmite_string_FLASH(PSTR("Seu nome é: "));
USART0_transmite_string_RAM(buffer);
USART0_transmite('\n');
}
/**
* @brief
*
* @return int Este procedimento não retorna
*/
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
USART0_configura(); // configuramos a USART0 para transmitir a 57600 Baud, quadros 8N1, para um microcontrolador a 16 MHz
portas_configura(); // configuramos PB0 como uma entrada com resistor de pull-up
// 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
{
leia_envie_seu_nome_usart0();
}
}
return 0; // este procedimento não deve retornar
}