#include <avr/io.h>
#include <avr/interrupt.h>
#include "UART.h"
#define SWITCH PA0
#define LED_ROJO PA2
#define LED_VERDE PA1
volatile uint32_t cnTcero = 0;
volatile uint32_t cnTuno = 0;
void GPIO_Ini(void)
{
// Botones
// ponemos PA0 como entrada
DDRA &= ~(1 << PA0);
// ponemos PA0 como PULL-UP
PORTA |= (1 << PA0);
// LEDs
// Ponemos PA1 y PA2 como salida
DDRA |= (1 << PA1) | (1 << PA2) | (1 << PA3);
// Ponemos PA2 como PULL-UP
PORTA |= 1 << PA2;
}
static long holdrand = 1L;
void srand(unsigned int seed)
{
holdrand = (long)seed;
}
int rand(void)
{
return (((holdrand = holdrand * 214013L + 2531011L) >> 16) & 0x7fff);
}
int random_time(void)
{
// número aleatorio entre 1 - 10
return rand() % 10 + 1;
}
void Timer0_Ini(void)
{
// (16MHz / (64 * 1000) - 1) para 1ms
OCR0A = 249;
// ponemos modo CTC
TCCR0A = (1 << WGM01);
// usamos prescalador a 64
TCCR0B = (1 << CS01) | (1 << CS00);
// Interrupcion por comparacion con el canal A
TIMSK0 = (1 << OCIE0A);
// interrupciones globales
sei();
}
ISR(TIMER0_COMPA_vect)
{
// Incrementa contador de milisegundos
cnTcero++;
}
void Timer1_Ini()
{
// (16MHz / (64 * 1000) - 1) 1ms
OCR1A = 249;
// Ponemos modo CTC
TCCR1A = (1 << WGM11);
// Ponemos prescalador a 64
TCCR1B = (1 << CS11) | (1 << CS10);
// Habilito la interrupcion
TIMSK1 = (1 << OCIE1A);
}
ISR(TIMER1_COMPA_vect)
{
// Incrementa contador por desbordamiento
cnTuno++;
}
void delayRand(uint8_t Rand)
{
// Reiniciar el contador y el indicador de desbordamiento
TCNT1 = 0;
cnTuno = 0;
//mientras el desbordamiento sea menor a Rand*500 (numero aleatorio)
while (cnTuno < Rand * 500)
;
}
int main(void)
{
GPIO_Ini();
Timer0_Ini();
Timer1_Ini();
UART0_Ini(0, 9600, 8, 0, 2);
char cad[20];
uint32_t lapse = 0;
while (1)///= Main Loop =/
{
// Esperar un tiempo aleatorio
delayRand(random_time());
// Encender LED verde
PORTA |= 1 << LED_VERDE;
// Iniciamos el contador
TCNT0 = 0;
cnTcero = 0;
// Esperar a que el usuario presione el botón
UART0_puts("Presiona el boton para reaccionar en cuanto encienda el LED VERDE\r\n");
while (PINA & (1 << SWITCH))
;
// Apagar LED verde
PORTA &= ~(1 << LED_VERDE);
if (cnTcero > 1000)
{
// Prender LED rojo
PORTA &= ~(1 << LED_ROJO);
// Esperar 2sec
delayRand(2);
//Convertimos el lapso de tiempo tardado a cadena para imprimirlo
lapse = cnTcero;
itoa(cad, lapse, 10);
UART0_puts("Oops, te tardaste ");
UART0_puts(cad);
UART0_puts(" milisegundos\r\n");
UART0_puts("\r\n");
// Apagar LED rojo
PORTA |= 1 << LED_ROJO;
}
else
UART0_puts("BIEN HECHO\r\n");
}
return 0;//<= no llega aqui
}