#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/interrupt.h>
// Configuracao dos ponteiros para os registradores do Temporizador 2
unsigned char *p_tccr2a = (unsigned char *)0xB0;
unsigned char *p_tccr2b = (unsigned char *)0xB1;
unsigned char *p_timsk2 = (unsigned char *)0x70;
// Configuracao dos ponteiros para os registradores da UART
unsigned char *p_ubrr0h = (unsigned char *)0xC5;
unsigned char *p_ubrr0l = (unsigned char *)0xC4;
unsigned char *p_ucsr0a = (unsigned char *)0xC0;
unsigned char *p_ucsr0b = (unsigned char *)0xC1;
unsigned char *p_ucsr0c = (unsigned char *)0xC2;
unsigned char *p_udr0 = (unsigned char *)0xC6;
// Variaveis relacionadas à temporizacao, à comunicacao serial e ao armazenamento das medidas de temperatura e umidade
volatile unsigned char uart_disponivel = 1;
volatile unsigned int indice_msg = 0;
volatile unsigned int base_de_tempo = 0;
unsigned char umidade = 99;
unsigned char temperatura = 10;
char msg_medidas[] = "Umidade: %\nTemperatura: °C\n\n";
char digitos[2];
// Funcao para conversao do valor da medida para a cadeia de caracteres que a representa
void num_to_ascii(unsigned char valor) {
unsigned char unidade;
unsigned char dezena;
unidade = (valor % 10) + 48;
dezena = ((valor / 10) % 10) + 48;
digitos[0] = dezena;
digitos[1] = unidade;
}
// Funcao para configuracao da UART
void config_uart(void) {
*p_ubrr0h = 0;
*p_ubrr0l = 8; // 115.200
*p_ucsr0a &= ~3;
*p_ucsr0b = 0x08;
*p_ucsr0c = 0x26;
}
// Funcao para configuracao do Temporizador 2
void config_timer2(void) {
// Temporizador 2
// Modo normal
// Prescaler = 1024 -> Faixa = 256*1024/16e6 = 16,384 ms
// Interrupcoes de overflow
// TIMSK2 – Timer/Counter2 Interrupt Mask Register
// - - - - - OCIE2B OCIE2A TOIE2
// - - - - - 0 0 1
*p_timsk2 = 1;
// TCCR2A - Timer/Counter Control Register A
// COM2A1 COM2A0 COM2B1 COM2B0 - - WGM21 WGM20
// 0 0 0 0 - - 0 0
*p_tccr2a = 0;
// TCCR2B - Timer/Counter Control Register B
// FOC2A FOC2B - - WGM22 CS02 CS01 CS00
// 0 0 - - 0 1 1 1
*p_tccr2b = 7;
}
// Rotina de servico de interrupcao que trata o evento de overflow do Temporizador 2
ISR(TIMER2_OVF_vect){
base_de_tempo++;
}
// Rotina de servico de interrupcao que trata o evento de buffer vazio da UART
ISR(USART_UDRE_vect) {
if (msg_medidas[indice_msg] != '\0') {
*p_udr0 = msg_medidas[indice_msg];
indice_msg++;
} else {
indice_msg = 0;
uart_disponivel = 1;
*p_ucsr0b &= ~0x20;
}
}
// Configuracoes iniciais
void configuracoes(void) {
cli();
config_timer2();
config_uart();
sei();
}
int main(void) {
configuracoes();
while (1) {
if ((base_de_tempo >= 305)&&(uart_disponivel == 1)) {
base_de_tempo = 0;
// ATUALIZE OS VALORES DAS VARIAVEIS umidade E temperatura COM A MEDIDA FORNECIDA PELO DHT11. USE APENAS A PARTE INTEIRA DO VALOR, SEM A PARTE FRACIONARIA.
// atualiza a mensagem para exibicao da umidade
num_to_ascii(umidade);
msg_medidas[9] = digitos[0];
msg_medidas[10] = digitos[1];
// atualiza a mensagem para exibicao da temperatura
num_to_ascii(temperatura);
msg_medidas[26] = digitos[0];
msg_medidas[27] = digitos[1];
uart_disponivel = 0;
*p_ucsr0b |= 0x20; // inicia o envio da mensagem com as medidas de umidade e temperatura mais atuais
}
}
return 0;
}