//Nome: Kauana Quintana Fort
//Matrícula: 202110738
#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 <stdint.h>
#include <util/delay.h>
#include <stdint.h>
#include <stdlib.h>
#include <avr/interrupt.h>
#include "usart.h"
/*Use o circuito anterior. Usamos o conversor ADC para fazer
a leitura da tensão analógica no canal ADC1 (porta PF1), em intervalos de 1 s.
Quando a tensão lida for maior que o valor em PB[2:0], transmitimos pela USART0 a
mensagem “Tensão acima do permitido”2
. Deve ser enviada uma única mensagem,
cada vez que a tensão lida for maior que PB[2:0]. Se a tensão não retornar a um
valor menor que PB[2:0], depois de 5 s, o LED em PB7 acende. Ele é apagado quando
a tensão é menor ou igual a PB[2:0]. Use AVCC como tensão de referência. Escreva
o programa em C. Faça a simulação com o programa em https://wokwi.com.
Use um potenciômetro na entrada ADC1 para testar o circuito.*/
uint8_t estado_pin0 = 0; // valor do pino 0
uint8_t estado_pin1 = 0; // valor do pino 1
uint8_t estado_pin2 = 0; // valor do pino 2
float valor_pino0, valor_pino1, valor_pino2, valor_total_pinos; // valores dos pinos
float tensao_ADC = 0; // tensao do ADC
uint8_t contador1 = 0, contador2 = 0; // contadores
void configurar_pinos(void) {
DDRB |= (1 << DDB7); // PB7 é saída
PORTB &= ~(1 << PORTB7); // LED está apagado
DDRB &= ~(1 << DDB0); // PB0 é entrada
PORTB |= (1 << PORTB0); // resistor de pull-up interno em PB0
DDRB &= ~(1 << DDB1); // PB1 é entrada
PORTB |= (1 << PORTB1); // resistor de pull-up interno em PB1
DDRB &= ~(1 << DDB2); // PB2 é entrada
PORTB |= (1 << PORTB2); // resistor de pull-up interno em PB2
}
void configurar_ADC(void) {
ADCSRA = 0x87; // ADEN=1 ADSC=0 ADATE=0 ADIF=0 ADIE=0 ADPS[2:0]=111 N=128 para CLK_adc=125 kHz
ADCSRB = 0x00; // MUX[5]=0 ADTS[2:0]=000
ADMUX = 0x41; // REFS[1:0]=01 ADLAR=0 e MUX[4:0]=0001
}
void realizar_leitura_ADC(void) {
const float VREF = 5; // referência de tensão
ADCSRA |= (1 << ADSC); // nova conversão
while (ADCSRA & (1 << ADSC)) {} // espera a conversão
tensao_ADC = ADC * (VREF / 1024.0); // cálculo da tensão convertida
}
int main(void) {
configurar_pinos();
configurar_ADC();
USART0_configura();
while (1) {
_delay_ms(1000); // faz a leitura a cada 1 segundo
estado_pin0 = PINB & (1 << PINB0); // leitura do PB0
estado_pin1 = PINB & (1 << PINB1); // leitura do PB1
estado_pin2 = PINB & (1 << PINB2); // leitura do PB2
// Verificar se os botões estão pressionados
valor_pino0 = (estado_pin0 == 0x00) ? 0x01 : 0x00;
valor_pino1 = (estado_pin1 == 0x00) ? 0x02 : 0x00;
valor_pino2 = (estado_pin2 == 0x00) ? 0x04 : 0x00;
valor_total_pinos = valor_pino0 + valor_pino1 + valor_pino2; // soma dos valores dos pinos
realizar_leitura_ADC(); // leitura do ADC
if ((tensao_ADC > valor_total_pinos) && (contador1 == 0)) {
USART0_transmite_string_FLASH(PSTR("Tensão acima do permitido \n")); // transmite pela USART
contador1 = 0x01;
} else {
if (tensao_ADC > valor_total_pinos) {
contador2++;
} else {
contador1 = 0;
contador2 = 0;
}
}
if (contador2 >= 5) {
PORTB |= (1 << PORTB7); // liga o LED
} else {
PORTB &= ~(1 << PORTB7); // desliga o LED
}
}
return 0;
}