Source code #undef F_CPU #define F_CPU 8000000UL #include <avr/io.h> #include <avr/delay.h> #include <string.h> #include <avr/eeprom.h> #define LCD_DATA_PORT #define LCD_DATA_DDR #define LCD_DATA_PIN PORTA DDRA PINA #define LCD_RS_PIN 1 #define LCD_RW_PIN 2 #define LCD_ENABLE_PIN 3 #define LCD_7_PIN 7 #define LCD_6_PIN 6 #define LCD_5_PIN 5 #define LCD_4_PIN 4 void LCD_goto(unsigned char y, unsigned char x); unsigned char hexbreaker(unsigned char c, int i); void LCD_print(char *string); double ReadDoubleFromEeprom(void); unsigned char bestmean; unsigned int random; double newround(void); double mean; double best;
double highscore; double EEMEM EEVar; void main(void){ setddr(); highscore = ReadDoubleFromEeprom(); LCDinit(); standby(); // Sätter spelet i vänteläge och printar welcome samt bästa tiden, som hämtas från eepromen void standby(void){ LCD_clear(); random = 0; LCD_goto(0,0); LCD_print("Welcome! Start->"); LCD_goto(1,0); LCD_print("Best:"); LCD_print(dtostrf(highscore)); led_standby(); unsigned char t = 0x11; while(t!= 0x00){ unsigned char u = PINA; t = u << 7; randomtick();
newgame(); // Sparar bästa tid (double) på eepromen void WriteDoubleToEeprom(double x){ eeprom_write_block((const void*)&x, (void*)&eevar, sizeof(double)); // Hämtar bästa tid (double) från eepromen double ReadDoubleFromEeprom(void){ double temp; eeprom_read_block((void*)&temp, (const void*)&eevar, sizeof(double)); return(temp); // Startar en ny omgång om 10 spelomgångar. Hålller även koll på // tiderna mean och best från spelomgången. void newgame(void){ mean = 0; best = 5000; led_allgreen();
LCD_clear(); LCD_goto(0,0); LCD_print("3 "); _delay_ms(1000); LCD_print("2 "); _delay_ms(1000); LCD_print("1 "); _delay_ms(1000); LCD_clear(); LCD_goto(0,0); LCD_print("Game on!"); for(int k = 0; k < 10; k++){ randomtick(); unsigned int temp = newround(); mean = mean + temp; if(temp < best) { best = temp; mean = mean/10; if(mean < highscore highscore == 0){ highscore = mean; gameover(); standby();
// Visar bästa tid och medelvärdestid från spelomgången. void gameover(void) { WriteDoubleToEeprom(highscore); LCD_clear(); led_standby(); LCD_goto(0,0); LCD_print("Fastest: "); LCD_print(dtostrf(best)); LCD_goto(1,0); LCD_print("Mean: "); LCD_print(dtostrf(mean)); while((pinb & (1<<4))){ // 0xE7 PINB!= 0xEF) { randomtick(); // Skapar en ny runda (anropas av newgame). Returnerar hur lång tid // rundan tog. double newround(void){ int time = 0; _delay_ms(random*1000 + 500);
randomtick(); if(random == 0) { led_northred(); while((pinb & (1<<4))) { time = time + 1; randomtick(); led_allgreen(); return time; if(random == 1) { led_westred(); while(pinb!= 0x7F) { time = time + 1; randomtick(); led_allgreen(); return time; if(random == 2) { led_eastred(); while(pinb!= 0xBF) {
time = time + 1; randomtick(); led_allgreen(); return time; if(random == 3) { led_southred(); while(pinb!= 0xDF) { time = time + 1; randomtick(); led_allgreen(); return time; // Genererar ett tal mellan 0 och 3. void randomtick(void){ if(random == 3){ random = 0;
else{ random ++; // Initialisering av LCD-displayen. void LCDinit(void){ _delay_ms(16); LCD_send_command8(0x30); // setup _delay_ms(5); LCD_send_command8(0x30); // setup _delay_us(100); LCD_send_command8(0x30); // setup LCD_send_command8(0x20); // setup LCD_send_command8(0x20); // LCD_send_command8(0x80); // 4bit interface, dual line // LCD_send_command8(0x00); // LCD_send_command8(0xC0); // Display on, cursor on, blink off E0 //
LCD_send_command8(0x00); // LCD_send_command8(0x10); // Display clear LCD_send_command8(0x00); // LCD_send_command8(0x60); //I/D, S // LCD_send_command8(0xF0); //DCB isch, Får den att skriva i rätt riktning LCD_send_command8(0x02); // DB7, DB6, RS. Write data to CG/DD RAM // Initialisering av DDR (sätter outputs). void setddr(void) { DDRA = 0xFE; DDRC = 0xC3; DDRD = 0xFF; DDRB = 0x00; PORTC = 0xC3; PORTD = 0xFF;
// Alla LED lyser blått. void led_standby(void){ PORTC = 0x83; PORTD = 0x6D; // Alla LED lyser grönt. void led_allgreen(void){ PORTC = 0xC1; PORTD = 0xB6; // Norra lampan lyser rött, resterande grönt. void led_northred(void){ PORTC = 0xC2; PORTD = 0xB6; // Västra lampan lyser rött, resterande grönt. void led_westred(void){ PORTC = 0xC1;
PORTD = 0xBA; // Östra lampan lyser rött, resterande grönt. void led_eastred(void){ PORTC = 0xC1; PORTD = 0xD6; // Södra lampan lyser rött, resterande grönt. void led_southred(void){ PORTC = 0x41; PORTD = 0xB7; // Bestämmer vart på LCD:n man ska skriva. // y = 0 -> rad 1 // y = 2 -> rad 2 // x anger kolonn, mellan 0-15 void LCD_goto(unsigned char y, unsigned char x) {
unsigned char firstaddress[] = {0x80,0xC0; //0x80 0xC0 LCD_send_command4(firstAddress[y] + x); // Skickar ett kommando till displayen. void LCD_send_command8(unsigned char cmnd){ LCD_DATA_PORT &= ~(1<<LCD_ENABLE_PIN); LCD_DATA_PORT = cmnd; LCD_DATA_PORT = (1<<LCD_ENABLE_PIN); _delay_us(5); LCD_DATA_PORT &= ~(1<<LCD_ENABLE_PIN); // Skickar ett kommando till displayen, i två omgångar (fyra-bitars // kommunikation. void LCD_send_command4(unsigned char cmnd){ unsigned char cmnd1 = hexbreaker(cmnd,1);
unsigned char cmnd2 = hexbreaker(cmnd,0); LCD_DATA_PORT &= ~(1<<LCD_ENABLE_PIN); LCD_DATA_PORT &= ~(1<<LCD_RW_PIN); LCD_DATA_PORT &= ~(1<<LCD_RS_PIN); unsigned char temp = 0x0F; unsigned char temp2 = LCD_DATA_PORT & temp; LCD_DATA_PORT = cmnd1 temp2; LCD_DATA_PORT = (1<<LCD_ENABLE_PIN); _delay_us(5); LCD_DATA_PORT &= ~(1<<LCD_ENABLE_PIN); temp2 = LCD_DATA_PORT & temp; LCD_DATA_PORT = cmnd2 temp2; LCD_DATA_PORT = (1<<LCD_ENABLE_PIN); _delay_us(5); LCD_DATA_PORT &= ~(1<<LCD_ENABLE_PIN); // Stödfunktion för fyra-bitars kommunikation med skärmen. unsigned char hexbreaker(unsigned char c, int i){ if(i == 1){ c = c & 0xF0; // ABCD EFGH --> ABCD 0000
return c; else{ c = (c<<4); //vänsterställer 4 steg ABCD EFGH --> EFGH 0000 return c; // Skriver ut en sträng på skärmen. void LCD_print(char *string){ unsigned char i; i = 0; while(string[i]!= 0) { LCD_send_data(string[i]); i++; // Skriver ut ett tecken på skärmen. void LCD_send_data(unsigned char c) { unsigned char data1 = hexbreaker(c,1); unsigned char data2 = hexbreaker(c,0); LCD_DATA_PORT &= ~(1<<LCD_ENABLE_PIN); LCD_DATA_PORT &= ~(1<<LCD_RW_PIN); LCD_DATA_PORT = (1<<LCD_RS_PIN);
unsigned char temp = 0x0F; unsigned char temp2 = LCD_DATA_PORT & temp; LCD_DATA_PORT = data1 temp2; LCD_DATA_PORT = (1<<LCD_ENABLE_PIN); _delay_us(5); LCD_DATA_PORT &= ~(1<<LCD_ENABLE_PIN); _delay_us(5); temp2 = LCD_DATA_PORT & temp; LCD_DATA_PORT = data2 temp2; LCD_DATA_PORT = (1<<LCD_ENABLE_PIN); _delay_us(5); LCD_DATA_PORT &= ~(1<<LCD_ENABLE_PIN); _delay_us(5); // Rensar skärmen, void LCD_clear(void) { LCD_goto(0,0);
LCD_print(" "); LCD_goto(1,0); LCD_print(" ");