//Nomes: Dienifer E. Moraes e Kauana Fort
//projeto painel automotivo
#define __ATmega2560__
#define __AVR_ATmega2560__
#ifndef F_CPU
#define F_CPU 16000000UL
#endif
#include <stdint.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdbool.h>
#include <util/delay.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include "usart.h"
#include "lcd.h"
#define PI 3.14159
#define BETA 3950 //do sensor de temperatura
#define GAMMA 0.7 //do photoresistor
#define RL10 50 //photoresistor
#define THRESHOLD 853 //crepúsculo
#define FAROL PD7 //faróis
#define ar_ligado PG1 // led que indica se o ar condicionado está ligado
#define ligar_desligar_ar PC4
#define R 16 // Diâmetro do pneu em polegadas
#define MAX_VELOCIDADE 200.0 // Velocidade máxima permitida em km/h
#define SENSOR_RODA PJ1
#define recirculacao_sinal PC5
#define recirculacao_led PC1
volatile uint32_t tick, tick1, tick2, tick3, tick4, tick5, tick6;
volatile uint16_t timer, espera;
uint8_t estado_atual_chave_ar; // o estado da chave: valor da chave sem debounce
uint8_t estado_anterior_chave_ar; // armazena o estado anterior da chave
uint8_t leitura_atual_chave_ar; // a leitura atual do valor da chave
uint8_t leitura_anterior_chave_ar; // a leitura anterior do valor da chave
uint8_t chave_pressionada_ar; // 1 se é reconhecida uma borda de descida
uint8_t estado_atual_chave_recirc; // o estado da chave: valor da chave sem debounce
uint8_t estado_anterior_chave_recirc; // armazena o estado anterior da chave
uint8_t leitura_atual_chave_recirc; // a leitura atual do valor da chave
uint8_t leitura_anterior_chave_recirc; // a leitura anterior do valor da chave
uint8_t chave_pressionada_recirc; // 1 se é reconhecida uma borda de descida
volatile float velocidade, speed;
volatile float distancia = 0;
volatile float comprimento = 2 * PI / 8 * (0.0254 * R / 2);
uint8_t recirculando;
const int ac_max = 30;
const int ac_min = 17;
int ar_condicionado = 25;
// ISR para interrupção de mudança de pino
// ISR para a interrupção de mudança de pino para o sensor de velocidade
ISR(PCINT1_vect) {
if ((PINJ & (1 << PINJ1))) {
velocidade = comprimento * 1000000 / (tick * 512 + OCR1A * 0.5); // divide a distância pelo tempo (tick = 4096us e OCR1A = 4us)
velocidade = velocidade * 3.6; // transforma m/s para km/h
if (velocidade > MAX_VELOCIDADE) { // Limita a velocidade ao valor máximo permitido
velocidade = MAX_VELOCIDADE;
}
tick = 0; // zera a variável que mede o tempo
distancia += comprimento;
}
}
// Função para configurar o Timer1
void timer1_config(void) {
TCCR1A = 0; // Timer mode with no output
TCCR1B = (1 << CS11) | (1 << CS10); // Prescaler 64
TCNT1 = 0; // Initialize counter
OCR1A = 1023; // valor de TOP = 1023
TIMSK1 = (1 << TOIE1); // Enable overflow interrupt
}
void timer0_config(void) {
TCCR0A = 1; // Timer mode with no output
TCCR0B = 3; // Prescaler 64
TCNT0 = 0; // Initialize counter
OCR0A = 249; // valor de TOP = 1023
TIMSK0 = 2; // Enable overflow interrupt
}
// Função para configurar a interrupção externa
void external_interrupt_config(void) {
PCICR |= (1 << PCIE1); // Habilita interrupção do PCINT1
PCMSK1 |= (1 << PCINT10); // Habilita PCINT9 (PJ1)
}
// ISR para o Timer1 overflow
ISR(TIMER1_OVF_vect) {
tick++;
tick1++;
tick3++;
tick4++;
tick5++;
tick6++;
}
ISR(TIMER0_COMPA_vect) {
tick2++;
}
// Função para verificar o botão de recirculação
void verifica_botao_recirculacao() {
_delay_ms(10); // esperamos um intervalo de tempo maior que o intervalo de repique da chave
leitura_anterior_chave_recirc = leitura_atual_chave_recirc; // atualizamos a leitura anterior da chave
leitura_atual_chave_recirc = ((PINC & (1 << recirculacao_sinal)) == 0x01); // realizamos a leitura de PG0
estado_anterior_chave_recirc = estado_atual_chave_recirc; // atualiza o estado anterior da chave
if (leitura_atual_chave_recirc == leitura_anterior_chave_recirc) // se o sinal da chave permanece estável no intervalo
{
estado_atual_chave_recirc = leitura_atual_chave_recirc; // o estado da chave é igual ao valor da chave
}
// verificamos se a chave foi pressionada
chave_pressionada_recirc = (estado_anterior_chave_recirc == 0x01) && (estado_atual_chave_recirc == 0x00); // é uma borda de descida?
// Alteramos o estado de recirculação quando a chave é pulsada
if (chave_pressionada_recirc) {
recirculando = !recirculando;
}
// Ajustamos o LED de recirculação
if (recirculando == 1) {
PORTC |= (1 << recirculacao_led); // Liga o LED de recirculação
} else {
PORTC &= ~(1 << recirculacao_led); // Desliga o LED de recirculação
}
}
// Função para verificar o botão do ar condicionado
void verifica_botao_ar_condicionado() {
_delay_ms(10); // esperamos um intervalo de tempo maior que o intervalo de repique da chave
leitura_anterior_chave_ar = leitura_atual_chave_ar; // atualizamos a leitura anterior da chave
leitura_atual_chave_ar = ((PINC & (1 << ligar_desligar_ar)) == 0x01); // realizamos a leitura de PB0
estado_anterior_chave_ar = estado_atual_chave_ar; // atualiza o estado anterior da chave
if (leitura_atual_chave_ar == leitura_anterior_chave_ar) // se o sinal da chave permanece estável no intervalo
{
estado_atual_chave_ar = leitura_atual_chave_ar; // o estado da chave é igual ao valor da chave
}
// verificamos se a chave foi pressionada
chave_pressionada_ar = (estado_anterior_chave_ar == 0x01) && (estado_atual_chave_ar == 0x00); // é uma borda de descida?
// Complementamos o LED quando a chave é pulsada
if (chave_pressionada_ar) {
PORTG ^= (1 << ar_ligado); // Comuta o LED que indica se o ar condicionado está ligado
}
}
// Função para transmitir uma string pela USART
void transmiteString(const char *str) {
while (*str) {
USART0_transmite(*str); // Transmite um caractere
str++;
}
}
// Função para transmitir um número pela USART
void transmiteNum(int num) {
char buffer[16]; // Buffer para converter o número para string
sprintf(buffer, "%d", num); // Converte o número para string
transmiteString(buffer); // Usa transmiteString para enviar
}
// Função para inicializar o ADC
void adc_config(void) {
// Selecionar a referência de tensão(5V) para AVCC com um capacitor em AREF
ADMUX = (1 << REFS0);
// Configurar a prescaler para 128 para uma taxa de amostragem de 125 kHz com um clock de 16 MHz
ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
}
// Função para ler o canal ADC especificado
uint16_t ler_adc(uint8_t canal) {
// Certifique-se de que o canal está entre 0 e 7
if (canal > 7) {
return 0;
}
// Configurar o canal (limpando bits de canal, então definindo o canal desejado)
ADMUX = (ADMUX & 0xF0) | (canal & 0x07);
// Iniciar a conversão
ADCSRA |= (1 << ADSC);
// Esperar a conversão terminar (ADSC será limpo após a conclusão)
while (ADCSRA & (1 << ADSC));
// Retornar o valor convertido
return ADCW; // ADCW é o valor de 16 bits da conversão
}
// Configuração do ADC e da USART
void setup(void) {
adc_config(); // Configura o ADC para leitura do valor analógico
USART0_configura(); // Configura a USART para comunicação serial
DDRD |= (1 << FAROL); // Configura o pino do LED/luz como saída
LCD_Init(); // inicializa o LCD
timer1_config(); // Configura o Timer1
timer0_config(); // Configura o Timer1
external_interrupt_config(); // Configura a interrupção externa
sei(); // Habilita interrupções globais
DDRJ &= ~(1 << DDJ1); // Configura PJ1 como entrada
PORTJ |= (1 << PORTJ1); // Habilita pull-up em PJ1
// Configurações para a recirculação
DDRC &= ~(1 << recirculacao_sinal); // Configura PD3 como entrada
PORTC |= (1 << recirculacao_sinal); // Habilita pull-up em PD3
DDRC |= (1 << recirculacao_led); // Configura o pino do LED de recirculação como saída
DDRG |= (1 << ar_ligado); // Configura o pino do LED de recirculação como saída
DDRC &= ~(1 << ligar_desligar_ar); // Configura como entrada
PORTC |= (1 << ligar_desligar_ar); // Habilita pull-up
leitura_atual_chave_ar = ((PINC & (1 << ligar_desligar_ar)) == 0x01); // lemos o valor da chave
estado_atual_chave_ar = leitura_atual_chave_ar; // O estado inicial da chave é o valor da chave
leitura_atual_chave_recirc = ((PINC & (1 << recirculacao_sinal)) == 0x01); // lemos o valor da chave
estado_atual_chave_recirc = leitura_atual_chave_recirc; // O estado inicial da chave é o valor da chave
}
int main(void) {
setup();
char buffer[16];
while (1) {
sei();
if (tick2 >= 20) {
verifica_botao_recirculacao();
verifica_botao_ar_condicionado();
tick2 = 0;
}
}
return 0;
}