Sei sulla pagina 1di 4

#define F_CPU 16000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdbool.h>

void Interrupt_INIT(void);
void scanKeypad(void);
int findKey(int, int);
void debounce_timer_name(void);
void timer_name(int);

volatile short int key;


volatile int flagVariable;

int main(void)
{
Interrupt_INIT();
debounce_timer_name();

while(1)
{
if(flagVariable == 1)
{
_delay_ms(50); // Debounce delay
scanKeypad();

flagVariable = 0; // Resets flag


_delay_ms(50);
}
}
}

void Interrupt_INIT() // Initialization for this lab


{
TCCR0A |= (1 << WGM01);
TCCR0B |= (1 << CS02 | 1 << CS00); // Sets the pre-scaler to 1024

// Given from TA Email //


cli();
PCICR |= (1 << PCIE0); // Turns on Pin Change Interrupts
PCMSK0 |= (1 << PCINT7); // Push-button
sei();
}

void scanKeypad(void)
{
// (Similar to Lab 3 Keypad Scanning, sets up for scanning the keypad's keys)
//
DDRB &= (1 << DDB0) | (1 << DDB1) | (1 << DDB2) | (1 << DDB3); // Columns are
inputs
DDRD |= (1 << DDD4) | (1 << DDD5) | (1 << DDD6) | (1 << DDD7); // Rows are
outputs
DDRB |= (1 << DDB5);
PORTB = 0x0F;

PORTB = 0x0F;
int i = 0; // Columns
int j = 0; // Rows

for(i = 0; i < 4; i++)


{
PORTD &= ~(1 << (i + 4)); // First it checks rows (i)

for(j = 0; j < 4; j++)


{
PORTB = 0x0F;
if(!(PINB & (1 << j))) // Then it checks the column to find the
specific key (j)
{
key = findKey(i, j);

// Controlling Output Votlage using Keypad Scanning //

if(key == 0)
timer_name(0);

else if(key == 1)
timer_name(200);

else if(key == 2)
timer_name(300);

else if(key == 3)
timer_name(400);

else if(key == 4)
timer_name(500);

else if(key == 5)
timer_name(600);

else if(key == 6)
timer_name(700);

else if(key == 7)
timer_name(800);

else if(key == 8)
timer_name(900);

else if(key == 9)
timer_name(1000);
}
}

PORTD |= (1 << 4 | 1 << 5 | 1 << 6 | 1 << 7);


}

PORTD |= (1 << 4 | 1 << 5 | 1 << 6 | 1 << 7);


}

int findKey(int i, int j) // Returns key pressed to scanKeypad to determine


timer_name's input value //
{
// Checks rows then columns (i is rows left to right then j is columns top to
bottom) //
if(i == 0 && j == 0)
return 1;

else if(i == 0 && j == 1)


return 2;

else if(i == 0 && j == 2)


return 3;

else if(i == 1 && j == 0)


return 4;

else if(i == 1 && j == 1)


return 5;

else if(i == 1 && j == 2)


return 6;

else if(i == 2 && j == 0)


return 7;

else if(i == 2 && j == 1)


return 8;

else if(i == 2 && j == 2)


return 9;

else if(i == 3 && j == 1)


return 0;
}

void debounce_timer_name()
{
OCR0A = 78; // Debounce (every 5ms)
TIMSK0 |= (1 << OCIE0A);
}

void timer_name(int dutyCycle)


{
OCR1A = 1200; // Max value for duty cycle
OCR1B = dutyCycle;
TCCR1B |= (1 << WGM12 | 1 << CS10); // Enables CTC mode without Pre-scaler
TIMSK1 |= (1 << OCIE1A | 1 << OCIE1B); // Enables compare match for A and B
interrupts
}

ISR(TIMER0_COMPA_vect) // Disables debounce timer and sets flag to 1


{
TCCR0B &= ~(1 << CS00 | 1 << WGM02);
flagVariable = 1;
}

ISR(TIMER1_COMPA_vect) // Compare Match A interrupt


{
if(key == 0) // LED Brightness changing
PORTB &= (0 << PORTB5); // LED Off if 0 is pressed
else
PORTB |= (1 << PORTB5);
}

ISR(TIMER1_COMPB_vect) // Compare Match B interrupt


{
PORTB &= (0 << PORTB5); // LED off
}

ISR(PCINT0_vect) // Push-button toggle


{
TCCR1B &= ~(1 << CS00); // Timer 1 gets paused
PORTB &= (0 << PORTB5); // Toggling LED
}

Potrebbero piacerti anche