main.cpp
——————————————-
#include <Arduino.h>
#include <avr/io.h>
#include “led.h”
#include “switch.h”
#include “timer.h”
/*
* Define a set of states that can be used in the state machine using an enum
*/
typedef enum stateType_enum {
countSlow, pressSlow, countFast, pressFast
} stateType;
// typedef enum stateType_enum{
// waitPress, dbPress, waitRelease, dbRelease
// } stateType;
// volatile stateType state = waitPress;
// volatile int multiplier;
volatile stateType state = countSlow;
volatile int num = 0;
int main(){
initSwitchPB3();
initLED();
sei(); // enable global interrupts
Serial.begin(9600);
DDRB |= (1 << DDB7);
/*
* Implement a state machine in the while loop which achieves the assignment
* requirements.
*/
while(1){
/* After 100 ms, increment the binary number represented by the LEDs
*/
switch(state){
case countSlow:
Serial.println(“In state: countSlown”);
turnOnLEDWithChar(num);
_delay_ms(200);
break;
case pressSlow:
Serial.println(“In state: pressSlown”);
turnOnLEDWithChar(num);
_delay_ms(200);
break;
case countFast:
Serial.println(“In state: countFastn”);
turnOnLEDWithChar(num);
_delay_ms(100);
break;
case pressFast:
Serial.println(“In state: pressFastn”);
turnOnLEDWithChar(num);
_delay_ms(100);
break;
}
num++;
if(num == 16) {
num = 0;
}
}
return 0;
}
// while(1){
// switch(state){
// case waitPress:
// break;
// case dbPress:
// _delay_ms(50);
// state = waitRelease;
// break;
// case waitRelease:
// break;
// case dbRelease:
// _delay_ms(50);
// if(multiplier == 1){
// OCR1AH = 0xF4;
// OCR1AL = 0x24;
// multiplier = 2;
// }
// else{
// OCR1AH = OCR1AH >> 1;
// OCR1AL = OCR1AL >> 1;
// multiplier = 1;
// }
// state = waitPress;
// break;
// }
// }
//
// return 0;
// }
/* Implement an Pin Change Interrupt which handles the switch being
* pressed ant released. When the switch is pressed an released, the LEDs
* change at twice the original rate. If the LEDs are already changing at twice
* the original rate, it goes back to the original rate.
*/
// Interrupt Service Routine
ISR(TIMER1_COMPA_vect){
PORTB ^= (1 << PORTB7); // toggles the bit
_delay_ms(20);
}
ISR(PCINT0_vect){
// Serial.println(“Got a change.”);
// if(state == pressSlow){
// state = countFast;
// }
// else if(state == pressFast){
// state = countSlow;
// }
if(state == countSlow) {
_delay_ms(20);
state = pressSlow;
} else if(state == pressSlow) {
_delay_ms(20);
state = countFast;
} else if(state == countFast) {
_delay_ms(20);
state = pressFast;
} else {
_delay_ms(20);
state = countSlow;
}
}
————————————————————————–
led.cpp
———————————–
#include <avr/io.h>
#include <util/delay.h>
#include “led.h”
/* Initialize PA0, PA1, PA2, and PA3 to outputs
*/
void initLED(){
DDRA |= (1 << DDA0) | (1 << DDA1) | (1 << DDA2) | ( 1 << DDA3); // set LEDs to output
}
/* This must be one line of code.
* In this function you will be giving a number “num” which will be represented
* in binary by four LEDs. You must effectively assign the lowest four bits of
* “num” to the appropriate bits of PORTA.
*/
void turnOnLEDWithChar(unsigned char num) {
PORTA = (PORTA & 0xF0) | (num & 0x0F);
}
—————————————————————————-
led.h
—————————————-
#ifndef LED_H
#define LED_H
void initLED();
void turnOnLEDWithChar(unsigned char num);
#endif
————————————————————————–
timer.cpp
—————————————-
#include “timer.h”
/* Initialize timer 1, you should not turn the timer on here.
* You will need to use CTC mode
*/
void initTimer1(){
// set the timer mode to be “CTC”
TCCR1A &= ~(1 << WGM10 | 1 << WGM11);
TCCR1B &= ~(1 << WGM13);
TCCR1B |= (1 << WGM12);
}
/* This delays the program an amount specified by unsigned int delay.
* Use timer 1. Keep in mind that you need to choose your prescalar wisely
* such that your timer is precise to 1 millisecond and can be used for 125
* 100 milliseconds
*
* NOTE : USE 256
*/
void delayMs(unsigned int delay){
// set clock/prescalar for timer 0 to be clk/256
TCCR1B &= ~(1 << CS10 | 1 << CS11);
TCCR1B |= (1 << CS12);
// set the OCR1A to 62,500 – 1
// this counts up to approximately one second
if(delay == 1) {
OCR1AH = 0x18;
OCR1AL = 0x6A;
} else if(delay == 0){
OCR1AH = 0xC;
OCR1AL = 0x35;
}
//enable the interrupt for the COMPA event
TIMSK1 |= (1 << OCIE1A);
}
—————————————————————————————-
timer.h
———————————-
#ifndef TIMER_H
#define TIMER_H
#include <avr/io.h>
void initTimer1();
void delayMs(unsigned int delay);
#endif
————————————————————————————-
switch.cpp
———————————–
#include “switch.h”
#include <avr/io.h>
/*
* Initializes pull-up resistor on PB3 and sets it into input mode
*/
void initSwitchPB3(){
PORTB |= (1 << PORTB3);
DDRB &= ~(1 << DDB3);
// enable pin-change interrupts
PCICR |= (1 << PCIE0);
// enable interrupts on PB3
PCMSK0 |= ( 1 << PCINT2 | 1 << PCINT3);
}
———————————————————————————–
switch.h
————————————
#ifndef SWITCH_H
#define SWITCH_H
void initSwitchPB3();
#endif