Mikrokontrolery - Jak zacząć?

... czyli zbiór praktycznej wiedzy dot. mikrokontrolerów.

niedziela, 20 marca 2011

DIY: Gra REFLEX na ATmega16 - terminal PuTTY + VT100


Autor: MODSezam
Redakcja: Dondu

Witam, chciałem przedstawić swój projekt. Jest nim gra, która oryginalnie nazywa się „REFLEX” :).

Jak sama nazwa wskazuje gra ma za zadanie badać czas reakcji na naciśnięcie odpowiedniego przycisku po pojawieniu się danej postaci. Dla utrudnienia postać którą trzeba wybrać może pojawić się losowo u góry na dole bądź po lewej lub prawej stronie.

Po 3 trafieniach przechodzimy level do góry co skutkuje zmniejszeniem maksymalnego czasu na reakcje. Najlepsze wyniki zapisywane są w pamięci EEPROM i wczytywane są po ponownym uruchomieniu.





Ekran startowy gry, wyświetlany na monitorze przedstawia się następująco:



Ekran startowy gry


Mikrokontroler podłączony jest poprzez układ ft232 do gniazda usb komputera, obraz wyświetlany jest za pośrednictwem terminala PuTTY (link Wikipedia) używając komend standardu VT100.

Schematy

Schemat części wykonawczej jest bardzo prosty. Składa się z czterech switch-y oraz czterech diod LED.


Schemat części wykonawczej


Układ przycisków i diod polutowany został na płytce uniwersalnej i został połączony za pomocą tasiemki do płytki uruchomieniowej. Schemat całego układu przedstawia się następująco.


Schemat całego układu


Następny obrazek przedstawia zmontowany układ podłączony do płytki uruchomieniowej:


Zmontowany układ

Układ ft232 instaluje się nam w komputerze jako port com. Za pomocą PuTTY łączymy używając portu rs 232, wybieramy szybkość polaczenia 230400 kb/s. Wysyłana ramka składa się 8 bitów danych, 1 bitu stopu bez bitu parzystości. Pozostaje wybrać jeszcze kodowanie UTF-8 (Window/Translation/Character set) by móc używać rozszerzonej tablicy ASCII inaczej pojawią nam się w niektórych miejscach krzaczki.


Terminal & VT100

Obraz wyświetlany jest w terminalu, ale dla lepszego efektu, użyłem kodów sterujących vt100. Elementy wyświetlane na terminalu wysyłane są przez uart mikrokontrolera. By zmienić położenie bądź kolor tekstu wstawiane są przed wysyłanymi danymi odpowiednie znaki sterujące:

Czyszczenie ekranu:
"\x1b[2J"   //<ESC>[2J
Ukrycie kursora:
"\x1b[?25l"   //<ESC>[?25l
Pokazanie kursora:
"\x1b[?25h"   //<ESC>[?25h
 Ustawienie kursora w pozycji y,x:
"\x1b[y;xH"   //<ESC>[<y>;<x>H
 Ustawienie koloru czcionki:
"\x1b[37m"   //biały <ESC>[<color>m
zmienna kolor przyjmuje wartości dla danego koloru:
//30 – BLACK, 31 – RED, 32 GREEN, 33 – YELLOW, 34 – BLUE, 35 – MAGNETA, 36 – CYAN, 37 – WHITE
Odtworzenie wybranego dźwięku
"\x1b\x07" //<ESC><BELL>
By wybrać jak dźwięk ma być odtwarzny w PuTTY w opcjach wchodzimy do Terminal/Bell wybieramy wybraną akcję dla polecenia <BEL>. Ja wybrałem „Beep using the PC speaker”. Pozostaje jeszcze odznaczyć „Bell is temporanly disabled when over-used”.

W grze dźwięk odtwarzany jest w przypadku nieprawidłowego trafienia postaci oraz gdy spóźnimy się z wyborem. Natomiast gdy wybór jest prawidłowy, w odpowiednim czasie, zapalają się wszystkie diody.

Wyżej przedstawiono tylko kody VT100, które użyto w grze. Jest ich o wiele więcej, nie ma sensu ich tu wypisywać ale po wpisaniu w google „vt100 code” możemy znaleźć inne ciekawe opcje.

Użycie terminala w połączeniu z VT100 możemy wykorzystać do wizualizacji naszych projektów, możemy wyświetlać zmienne np. w tabelkach, można zrobić proste menu i wiele innych ciekawych rzeczy.




UART

Trzeba również zwrócić uwagę na szybkość transmisji danych. Co prawda wysyłanie przez uart realizowane jest w przerwaniu, ale rysowanie np. postaci lewej przy 19,600 kb/s realizowane jest przez 382 ms. Człowiek natomiast jest w stanie wytrenować reakcję nawet w okolicy 100 ms, co prawda jest to reakcja na bodziec, a w grze trzeba dodatkowo wybrać wyświetlaną postać. Dlatego by czas reakcji nie był zbyt długi dodano odliczanie przed pojawieniem się postaci.

Każda postać posiada inną ilość znaków z której się składa dlatego rysuje się w innym czasie. Poniższa tabelka obrazuje czas rysowania poszczególnych postaci przy różnych szybkościach uart. Została ona wypełniona wartościami rzeczywistymi zmierzonymi przez licznik mikrokontrolera. Można również obliczyć czas rysowania postaci znając ilość jej znaków, ilość znaków kodów sterujących oraz uwzględniając, że do każdej ramki 8 bit-ów w tym przypadku należy dodać bit startu i stopu co zmniejsza efektywną transmisję danych do 80%.


Czas rysowania postaci

Poszczególna postać losowana jest za pomocą funkcji pseudolosowej random, obliczając modulo 4. Dodatkowo jako ziarno funkcji wpisywana jest wartość z przetwornika analogowo-cyfrowego ADC z niepodłączonego pinu PA1.

Timery

Cały szkielet programu opiera się na sprzętowych timerach (1A i 2) w trybie CTC (Clear on Timer Compare) wspomaganych przez timery programowe.

W tym trybie wartość timera sprzętowo porównywana jest z zadaną wartością (w tym przypadku odpowiednio z rejestrami OCR1A oraz OCR2) i następuje przerwanie, które aktywujemy ustawiając stan wysoki w rejestrze TIMSK na bicie OCIE1A dla timera1A oraz OCIE2 dla timera2.

Po aktywacji przerwania timer zostaje zresetowany.

W przerwaniu timera realizowane zostały timery programowe.





Uproszczony algorytm gry


Algorytm gry




Podsumowanie

  • Mikrokontroler: ATmega16
  • Fuse bits: LOW 0xFF, HIGH 0xD9
  • Kwarc: 11,0592 MHz
  • Program: 11394 bytes (70.0% Full)
  • Data: 310 bytes (31.6% Full)
  • EEPROM: 6 bytes (1.2% Full)



Do pobrania




Przydatne linki




Dziękuję za oddany głos w konkursie!
Pozdrawiam
Marcin





Program


main.c

/*
 * main.c
 *
 *  Created on: 21-02-2014
 *      Author: MODSezam
 */


#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <stdlib.h>

#include "uart_vt100.h"
#include "ascii.h"
#include "extended.h"

#define REF_VCC (1<<REFS0)

uint8_t rnd, rnd2; //zmienne losowe
uint8_t start_gry, start_gry2, start_gry3;
uint8_t koniec_gry; //zmienna koniec gry
uint8_t przyc_wl; //zmienna przyciski włączone
uint8_t wcis_przyc = 4;
uint8_t level = 1; //zmienna level
uint8_t trafione; //zmienna trafione
uint16_t czas_reakcji; //zmienna czas reakcji
uint16_t czas_reakcji_konc; // zmienna czas reakcji dla ostatniej postaci
uint16_t czas_reakcji_max; // maksymalny czas reakcji dla danego levelu
uint16_t czas_reakcji_temp; // wartosc tymczasowa maksymalna licznika Reaction
uint8_t flag_czas_reakcji; // flaga czas reakcji

uint16_t ram_min_cz_re; //minimalny czas reakcji
uint16_t ram_min_cz_re_old; //minimalny czas reakcji stary wynik
uint16_t eep_min_cz_re EEMEM; //minimalny czas reakcji w pamięci eeprom
uint16_t ram_max_lev; //maksymalny level
uint16_t ram_max_lev_old; //maksymalny level stary wynik
uint16_t eep_max_lev EEMEM; //maksymalny level w pamięci eeprom
uint16_t ram_max_traf; //maksymalny ilosc trafien
uint16_t ram_max_traf_old; //maksymalny ilosc trafien stary wynik
uint16_t eep_max_traf EEMEM; //maksymalny ilosc trafien w pamięci eeprom

uint8_t ram_flag;

uint16_t adc_rand( uint8_t kanal );
void rys_wyp_tab (void);

int main( void ) {

 DDRC |= (LED0|LED1|LED2|LED3); //diody LED0, LED1, LED2, LED3 jako wyjscie
 DDRC &= ~(KEY0|KEY1|KEY2|KEY3); // KEY0, KEY1, KEY2, KEY3 jako wejscie
 PORTC |= KEY0|KEY1|KEY2|KEY3; //podciagniecie KEY0, KEY1, KEY2, KEY3 do VCC

 //ustawienie nieużywanych pinów B jako wejscie
 DDRB &= ~((1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4));
 //podciagniecie nieużywanych pinów B do VCC
 PORTB |= ((1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4));

 //ustawienie nieużywanych pinów D jako wejscie
 DDRD &= ~((1<<PD2)|(1<<PD3)|(1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7));
 //podciagniecie nieużywanych pinów D do VCC
 PORTD |= ((1<<PD2)|(1<<PD3)|(1<<PD4)|(1<<PD5)|(1<<PD6)|(1<<PD7));

 LED_OFF();

 //inicjalizacja ADC
 ADCSRA |= (1<<ADEN); // włącz ADC
 ADCSRA |= (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
 ADMUX |= REF_VCC;



 // inicjalizacja timera, taktowanie 11.0592Mhz
 //ustawienie TIMER1 w tryb CTC
 TCCR1B |= (1<<WGM12);           //tryb CTC
 TCCR1B |= (1<<CS12)|(1<<CS10);  //preskaler = 1024
 OCR1A = 107;              //100Hz 10ms (11059200/1024/107=100Hz)
 TIMSK |= (1<<OCIE1A);           //compare flag

 //inicjalicaja timera 2 tryb CTC
 TCCR2 |= (1<<WGM21);    //tryb CTC
 TCCR2 |= (1<<CS22);     //preskaler 64
 OCR2 = 171;       //11059200/64/125=1000Hz
 TIMSK |= (1<<OCIE2);    //compare flag

 //initializacja uart
 uart_tx_initialize(__UBRR);

 sei();  //aktywacja przerwań

 srand(adc_rand(PA1)); // ziarno funkcji random
 ADCSRA &= ~(1<<ADEN); // wyłącz ADC

 L_Load = 555;

 while(1) {

  rnd = rand()%4;

  //start_gry = 2;
  //key_short(&PINC, KEY0, &L_Key0, LED0_XOR);

  if (start_gry == 0){
   // start gry
   //////////////////////////////////////
   //////////// pokaz loading////////////
   //////////////////////////////////////

   if (L_Load == 554){
    vt100_cls(); //czyć ekran
    vt100_cur_off(1); //ukrycie kursora
   }
   rysuj_loading(22,55); //animacja loading


   if (L_Load == 410) erase_load(22,55); // zmazanie loading
   if (L_Load == 400){
    //rysowanie postaci
    rysuj_postac3 (15,5); //postac lewa
    rysuj_postac4 (15,83);//postac prawa
    rysuj_postac1 (3,49); //postac gorna
    rysuj_postac2 (23,50); //postac dolna
    vt100_col(WHITE);
    //rysowanie pozostalych rzeczy na ekranie startowym
    rysuj_okno(16, 45); //rysowanie tabelki1
    rysuj_okno(22, 45); //rysowanie tabelki2
    rysuj_tab_wyn(3,88); //rysowanie tabelki wyniki
    vt100_col(RED); //ustawienie koloru tekstu na RED
    rysuj_hiscore(5, 90); //rysowanie pionowego napisu hi score
    rysuj_logo(17, 50); //rysowanie logo
    uart_tx_vt100_yx_col_string(25, 51, 0, \
    "WCIŚNIJ DOWOLNY PRZYCISK");

    uart_tx_vt100_yx_col_string(37, 9, RED, \
    "www.mikrokontrolery.blogspot.com");

    //odczyt czas reakcji z eeprom
    ram_min_cz_re = eeprom_read_word(&eep_min_cz_re);
    //odczyt max nr level z eeprom
    ram_max_lev = eeprom_read_word(&eep_max_lev);
    //odczyt max traf z eeprom
    ram_max_traf = eeprom_read_word(&eep_max_traf);

    //wpisanie zmiennych w tabelke
    //domylna wartosć bajtu w pamięci eeprom wynosi 0xFF
    //sprawdzenie czy pamiec eeprom pusta
    if (ram_min_cz_re == 0xFFFF){
     uart_tx_vt100_yx_col_string(12, 109, 0, "brak");
     ram_min_cz_re_old = 2000; //ustawienie wartoci domylnych
     ram_min_cz_re = 2000;  //ustawienie wartoci domylnych
    } else { //jeżli pamięć eeprom nie jest pusta
     vt100_yx_col(12, 110, 0);
     uart_tx_int(ram_min_cz_re);
     //zapamiętanie starej zmiennej
     ram_min_cz_re_old = ram_min_cz_re;
    }
    //sprawdzenie czy pamiec eeprom pusta
    if (ram_max_lev == 0xFFFF){
     uart_tx_vt100_yx_col_string(9, 109, 0, "brak");
     ram_max_lev_old = 1; //ustawienie wartoci domylnych
     ram_max_lev = 1; //ustawienie wartoci domylnych
    } else { //jeżli pamięć eeprom nie jest pusta
     vt100_yx_col(9, 110, 0);
     uart_tx_int(ram_max_lev);
     //zapamiętanie starej zmiennej
     ram_max_lev_old = ram_max_lev;
    }
    //sprawdzenie czy pamiec eeprom pusta
    if (ram_max_traf == 0xFFFF) {
     uart_tx_vt100_yx_col_string(6, 109, 0, "brak");
     ram_max_traf_old = 0; //ustawienie wartoci domylnych
     ram_max_traf = 0; //ustawienie wartoci domylnych
    } else { //jeżli pamięć eeprom nie jest pusta
     vt100_yx_col(6, 111, 0);
     uart_tx_int(ram_max_traf);
     //zapamiętanie starej zmiennej
     ram_max_traf_old = ram_max_traf;
    }
    // ustawienie ram_flag do wpisania wart. pierwszej gry do ram_
    ram_flag = 1;
    //vt100_yx_col(1,1,RED), uart_tx_int(L_Load); // test
   }


   if (L_Load == 370) przyc_wl = 1, start_gry = 1;
  }

  if (przyc_wl == 1){
   //sprawdzenie przycisków
   key_short(&PINC, KEY0, &L_Key0, przyc0_kr);
   key_short(&PINC, KEY1, &L_Key1, przyc1_kr);
   key_short(&PINC, KEY2, &L_Key2, przyc2_kr);
   key_short(&PINC, KEY3, &L_Key3, przyc3_kr);
   //jeżeli jaki przycisk wcinieto ustawienie flag
   //przycisk lewy
   if (flag_przyc0_kr == 1)flag_przyc0_kr = 0, wcis_przyc = 0;
   //przycisk prawy
   if (flag_przyc1_kr == 1)flag_przyc1_kr = 0, wcis_przyc = 1;
   //przycisk gorny
   if (flag_przyc2_kr == 1)flag_przyc2_kr = 0, wcis_przyc = 2;
   //przycisk dolny
   if (flag_przyc3_kr == 1)flag_przyc3_kr = 0, wcis_przyc = 3;
  }
  if (wcis_przyc < 4 && start_gry3 == 0){
   start_gry3 = 1; //jednorazowe przypisanie start_gry2 = 1
   start_gry2 = 1;
  }
  //////////////////////////////////////
  //////////// start gry ///////////////
  //////////////////////////////////////
  if (start_gry == 1){
   //sprawdzenie zyc i start gry
   if (koniec_gry < 3 && start_gry2 > 0){
    if (start_gry2 == 1){
     przyc_wl = 0; // wylaczenie przyciskow
     //zerowanie flagi nacisnietego przycisku (0-3)
     wcis_przyc = 4;
     start_gry2 = 2; // jednorazowe wykonanie tego if-a
     flag_czas_reakcji = 0; // flaga czas reakcji
     L_Main = 1000; //ustawienie poczatkowe licznika Main
     L_Reaction = 40000; //ustawienie poczatkowe licznika Reaction
     //przypisanie zmiennej pseudolosowej dla jednej rozgrywki
     rnd2 = rnd;
     vt100_cls(); // czyszczenie ekranu
     vt100_col(CYAN); //color tekstu CYAN
     //wartosc równa początkowej wartoci licznika Reaction
     czas_reakcji_temp = 3000;
     // sprawdznie czy nie zwiekszyć levelu
     if (trafione < 3) level = 1;
     if (trafione >= 3 && trafione < 6) level = 2;
     if (trafione >= 6 && trafione < 9) level = 3;
     if (trafione >= 9 && trafione < 12) level = 4;
     if (trafione >= 12 && trafione < 15) level = 5;
     if (trafione >= 15 && trafione < 18) level = 6;
     if (trafione >= 18 && trafione < 21) level = 7;
     if (trafione >= 21 && trafione < 24) level = 8;
     if (trafione >= 24 && trafione < 27) level = 9;
     if (trafione >= 27 && trafione < 30) level = 10;
     if (trafione >= 30) level = 11;

     //ustawienie maksymalnego czasu reakcji dla danego levelu
     if (level == 1) czas_reakcji_max = czas_reakcji_temp - 2000;
     if (level == 2) czas_reakcji_max = czas_reakcji_temp - 1500;
     if (level == 3) czas_reakcji_max = czas_reakcji_temp - 1000;
     if (level == 4) czas_reakcji_max = czas_reakcji_temp - 900;
     if (level == 5) czas_reakcji_max = czas_reakcji_temp - 800;
     if (level == 6) czas_reakcji_max = czas_reakcji_temp - 700;
     if (level == 7) czas_reakcji_max = czas_reakcji_temp - 600;
     if (level == 8) czas_reakcji_max = czas_reakcji_temp - 500;
     if (level == 9) czas_reakcji_max = czas_reakcji_temp - 400;
     if (level == 10) czas_reakcji_max = czas_reakcji_temp - 300;
     //jeżeli level = 11 - koniec gry, wyłączenie przycisków
     if (level == 11) koniec_gry = 4, L_Main = 701, przyc_wl = 0;
    }
    // odliczanie 3
    if (L_Main == 990) vt100_col(GREEN), rysuj_liczba3(20, 60);
    // odliczanie 2
    if (L_Main == 930) vt100_col(GREEN), rysuj_liczba2(20, 60);
    // odliczanie 1
    if (L_Main == 870) vt100_col(GREEN), rysuj_liczba1(20, 60);
    if (L_Main == 810){
     vt100_cls(); //czyszczenie ekranu
     // początkowa wartosc licznika Reaction decrementowana
     L_Reaction = 3000;
     //narysowanie wylosowanej postaci
     przyc_wl = 1; // aktywacja przyciskow
     if (rnd2 == 0) rysuj_postac3 (15,5); //postac lewa
     if (rnd2 == 1) rysuj_postac4 (15,83); //postac prawa
     if (rnd2 == 2) rysuj_postac1 (3,49); //postac gorna
     if (rnd2 == 3) rysuj_postac2 (23,50); //postac dolna

    }
    if (L_Main < 810 && L_Reaction >= czas_reakcji_max){
     //jeżeli wcinieto przycisk i flaga = 0
     if (wcis_przyc < 4 && flag_czas_reakcji == 0){
      przyc_wl = 0; // wyłączenie przycisków
      // wartosc licznika Reaction dla danej postaci
      czas_reakcji_konc = L_Reaction;
      // flaga czasu reakci dla jednorazowgo wykonania if-a
      flag_czas_reakcji = 1;
      //przejcie do pokazania wyników
      L_Reaction = czas_reakcji_max;
     }
    }
    if (L_Reaction == czas_reakcji_max - 10){
     L_Main = 500; //ustawienie licznika Main na 500 * 10 ms

     //sprawdzenie czy wybrano odpowiednia postac
     if (wcis_przyc == rnd2){
      trafione++; //zwiekszenie wartoci trafione o 1
      // oblicznie czasu reakci
      czas_reakcji = czas_reakcji_temp - czas_reakcji_konc;

      vt100_col(GREEN); //ustawienie koloru
      rysuj_okno(18, 45); // rysowanie ramki
      //wysłanie trafiłes
      uart_tx_vt100_yx_col_string(21, 58, 0, "TRAFILES");
      LED_ON(); // zapalenie diod led
      rys_wyp_tab();// rysowanie tabelki wyniki
      vt100_yx_col(12, 110, 0);
      uart_tx_int(czas_reakcji); // wypełnienie czas reakcji
      vt100_yx_col(13, 110, CYAN);
      uart_tx_vt100_yx_col_string(13, 105, WHITE, \
      "max       ms");
      //wypełnienie maksymalnego czasu reakcji
      vt100_yx_col(13, 110, CYAN);
      uart_tx_int(czas_reakcji_temp - czas_reakcji_max);
      // przy pierwszej grze zapisanie wartoci do ram_
      if (ram_flag == 1){
       ram_flag = 0; // wyłączenie flagi
       //zapisanie czas reakci do zmiennej ram_
       ram_min_cz_re = czas_reakcji;
       //zapisanie trafione do zmiennej ram_
       ram_max_traf = trafione;
       //zapisanie level do zmiennej ram_
       ram_max_lev = level;
      }
      //aktualizacja czas reakcji
      if (czas_reakcji < ram_min_cz_re) \
        ram_min_cz_re = czas_reakcji;
      //aktualizacja max trafionych
      if (trafione > ram_max_traf) ram_max_traf = trafione;
      //aktualizacja zmiennej level
      if (level > ram_max_lev) ram_max_lev = level;

     }
     // jeżeli wybrano inną postać
     if (wcis_przyc != rnd2 && wcis_przyc < 4){
      koniec_gry++;
      vt100_col(RED);
      rysuj_okno(18, 45);
      uart_tx_vt100_yx_col_string(21, 55, 0, "NIE TRAFIŁES");
      vt100_bell(); //odtworznie dzwięku
      // rysowanie tabelki wyniki i jej wypelnienie
      rys_wyp_tab();
      uart_tx_vt100_yx_col_string(12, 109, RED, "brak");
      uart_tx_vt100_yx_col_string(13, 105, WHITE, \
        "max       ms");
      vt100_yx_col(13, 110, CYAN);
      uart_tx_int(czas_reakcji_temp - czas_reakcji_max);
     }
     if (wcis_przyc == 4){ // jeżeli nie nacinięto przycisku
      koniec_gry++;
      vt100_col(YELLOW);
      rysuj_okno(18, 45);
      uart_tx_vt100_yx_col_string(21, 59, 0, "ZA PÓŹNO");
      vt100_bell(); //odtworznie dzwięku
      // rysowanie tabelki wyniki i jej wypelnienie
      rys_wyp_tab();
      vt100_yx_col(12, 110, 0);
      uart_tx_int(czas_reakcji_temp - czas_reakcji_max);
      uart_tx_vt100_yx_col_string(12, 105, WHITE, "max");
     }
    }
    //(500 - 250)*10ms
    //czas wyswietlania wyników i zaczęcia nowego odliczna, led off
    if (L_Main == 250) start_gry2 = 1, LED_OFF();

   }//end if (koniec_gry < 3 && start_gry2 > 0)


   //////////////////////////////////////
   //////////// koniec gry///////////////
   //////////////////////////////////////
   if (koniec_gry == 3){
    //jednorazowe wykonanie instrukcji w warunku - ust. flagi na 4
    koniec_gry = 4;
    przyc_wl = 0; // wylaczanie przyciskow
    L_Main = 1000; // ustawienie licznika na 1000
   }
   if (koniec_gry == 4){
    if (L_Main == 700){
     koniec_gry = 5; //ustawienie flagi koniec gry na 5
     vt100_cls();
     vt100_col(WHITE);
     rysuj_okno(18, 45);
     if (level < 11){
      uart_tx_vt100_yx_col_string(21, 58, RED, "GAME OVER");
     }
     if (level == 11){
      uart_tx_vt100_yx_col_string(21, 58, GREEN, "WYGRAŁEŚ");
     }
     vt100_col(WHITE);
     rysuj_tab_wyn(3,88);
     vt100_col(RED);
     //rysownie i wypełnienie hiscore
     rysuj_hiscore(4, 90);
     uart_tx_vt100_yx_col_string(4, 95, 0, " ");
     uart_tx_vt100_yx_col_string(5, 95, 0, " ");
     vt100_yx_col(6, 111, 0);
     uart_tx_int(ram_max_traf);
     vt100_yx_col(9, 111, 0);
     uart_tx_int(ram_max_lev);
     vt100_yx_col(12, 110, 0);
     uart_tx_int(ram_min_cz_re);
     vt100_col(WHITE);
     rysuj_tab_wyn(15,88);
     vt100_col(RED);
     rysuj_hiscore(17, 90);

     // jeżeli nowa wartoć większa od starej - max trafien
     if (ram_max_traf > ram_max_traf_old){
      uart_tx_vt100_yx_col_string(22, 58, GREEN, \
        "NOWY REKORD");
      vt100_yx_col(18, 111, 0);
      // wyswietlanie na zielono max trafien
      uart_tx_int(ram_max_traf);
      vt100_yx_col(19, 111, RED);
      // wyswietlanie na czerwono max trafien stara wartosc
      uart_tx_int(ram_max_traf_old);
      //zapis nowej wartoci do eeprom
      eeprom_write_word (&eep_max_traf, ram_max_traf);
     }else{ //jezeli mniejsza
      vt100_yx_col(18, 111, 0);
      uart_tx_int(ram_max_traf_old); //wyslij starą wartosć
     }
     // jeżeli nowa wartoć większa od starej - level
     if (ram_max_lev > ram_max_lev_old){
      uart_tx_vt100_yx_col_string(22, 58, GREEN, \
        "NOWY REKORD");
      vt100_yx_col(21, 111, 0);
      // wyswietlanie na zielono max level
      uart_tx_int(ram_max_lev);
      vt100_yx_col(22, 111, RED);
      // wyswietlanie na czerwono max level stara wartosc
      uart_tx_int(ram_max_lev_old);
      //zapis nowej wartoci do eeprom
      eeprom_write_word (&eep_max_lev, ram_max_lev);
     }else{ //jezeli mniejsza
      vt100_yx_col(21, 111, RED);
      uart_tx_int(ram_max_lev_old); //wyslij starą wartosć
     }
     // jeżeli nowa wartoć większa od starej
     // - minimalny czas reakcji
     if (ram_min_cz_re < ram_min_cz_re_old){
      uart_tx_vt100_yx_col_string(22, 58, GREEN, \
        "NOWY REKORD");
      vt100_yx_col(24, 110, 0);
      // wyswietlanie na zielono min czas reakcji
      uart_tx_int(ram_min_cz_re);
      vt100_yx_col(25, 110, RED);
      //wyswietlanie na czerwono min czas reakcji stara wartosc
      uart_tx_int(ram_min_cz_re_old);
      //zapis nowej wartoci do eeprom
      eeprom_write_word (&eep_min_cz_re, ram_min_cz_re);
     }else{ //jezeli mniejsza
      vt100_yx_col(24, 110, RED);
      uart_tx_int(ram_min_cz_re_old); //wyslij starą wartosć
     }
     vt100_col(GREEN);
     rysuj_logo(7, 50);

    }
   }

  }//end if (start_gry == 1)

 } //while end
} //main end


uint16_t adc_rand( uint8_t kanal ) {

 ADMUX = (ADMUX & 0b11110000) | kanal;
 ADCSRA |= (1<<ADSC);  // start konwersji
 while( ADCSRA & (1<<ADSC) );
 return ADCW;
}

void rys_wyp_tab (void){
 // rysowanie tabelki wyniki i jej wypelnienie
 vt100_col(WHITE);
 rysuj_tab_wyn(3,88);
 uart_tx_vt100_yx_col_string(4, 91, 0, "ILOŚĆ ŻYC:");
 vt100_yx_col(6, 111, RED);
 uart_tx_int(trafione);
 vt100_yx_col(9, 111, 0);
 uart_tx_int(level);
 //rysuj ilosc zyc
 if (koniec_gry == 0) rysuj_liczba3(6, 92);
 if (koniec_gry == 1) rysuj_liczba2(6, 92);
 if (koniec_gry == 2) rysuj_liczba1(6, 92);
 if (koniec_gry == 3) rysuj_liczba0(6, 92);
}




extended.c

/*
 * extended.c
 *
 *  Created on: 27-02-2014
 *      Author: MODSezam
 */


#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>

#include "extended.h"

//deklaracje zmiennych
volatile uint16_t L_Main; // zmienna licznikowa main
volatile uint16_t L_Load; // zmienna licznikowa load
volatile uint8_t L_Main_Key; //zmienna licznikowa key
volatile uint16_t L_Reaction; //zmienna licznikowa reakcja

//zmiana flagi flag_przyc0_kr na negacje
void przyc0_kr(){
 if (flag_przyc0_kr == 0){
  flag_przyc0_kr = 1;
 }
 else flag_przyc0_kr = 0;
}

//zmiana flagi flag_przyc1_kr na negacje
void przyc1_kr(){
 if (flag_przyc1_kr == 0){
  flag_przyc1_kr = 1;
 }
 else flag_przyc1_kr = 0;
}

//zmiana flagi flag_przyc2_kr na negacje
void przyc2_kr(){
 if (flag_przyc2_kr == 0){
  flag_przyc2_kr = 1;
 }
 else flag_przyc2_kr = 0;
}

//zmiana flagi flag_przyc3_kr na negacje
void przyc3_kr(){
 if (flag_przyc3_kr == 0){
  flag_przyc3_kr = 1;
 }
 else flag_przyc3_kr = 0;
}

//obsługa klawisza
void key_short(volatile uint8_t *PIN, uint8_t key, uint8_t *L_Key, void \
 (*funkcja)(void)) {
        if (!(*PIN&key)){
                if(!L_Main_Key){
                        if(*L_Key<255) ++*L_Key;
                        if(*L_Key==1){                   //1 ms
                                funkcja();
                        }
                }
        } else *L_Key=0;


} //end key_short

// zgaszenie wszystkich led
//ustawienie stanu wysokiego
void LED_OFF (void){
  PORTC |= LED0;
  PORTC |= LED1;
  PORTC |= LED2;
  PORTC |= LED3;
}
// zapalenie szystkich led
//ustawienie stanu niskiego
void LED_ON (void){
  PORTC &= ~LED0;
  PORTC &= ~LED1;
  PORTC &= ~LED2;
  PORTC &= ~LED3;
}

// wektor timera 1A
ISR(TIMER1_COMPA_vect){
  uint16_t n;
  n = L_Load;   //licznik Load
  if (n) L_Load = --n;
  n = L_Main;   //licznik Main
  if (n) L_Main = --n;
}

// wektor timera 2
ISR(TIMER2_COMP_vect){
 uint16_t n;
 n = L_Reaction;  // licznik reakcji
 if (n) L_Reaction = --n;
 n = L_Main_Key;   //licznik przycisków
 if (n) L_Main_Key = --n;
}



extended.h

/*
 * extended.h
 *
 *  Created on: 27-02-2014
 *      Author: MODSezam
 */

#ifndef EXTENDED_H_
#define EXTENDED_H_

//definicje zmiennnych
#define KEY0 (1<<PC4)   //klawisz0
#define KEY1 (1<<PC5)   //klawisz1
#define KEY2 (1<<PC6)   //klawisz2
#define KEY3 (1<<PC7)   //klawisz3

#define LED0 (1<<PC0) //LED0
#define LED1 (1<<PC1) //LED1
#define LED2 (1<<PC2) //LED2
#define LED3 (1<<PC3) //LED3

extern volatile uint16_t L_Main;
extern volatile uint16_t L_Load; //timer load
extern volatile uint16_t L_Reaction;

uint8_t L_Key0, L_Key1, L_Key2, L_Key3; //zmienna dla KEY0
uint8_t flag_przyc0_kr, flag_przyc1_kr, flag_przyc2_kr, flag_przyc3_kr;
uint8_t flag_przyc0_dl, flag_przyc1_dl, flag_przyc2_dl, flag_przyc3_dl;

//deklaracje funkcji
void przyc0_kr( void );
void przyc1_kr( void );
void przyc2_kr( void );
void przyc3_kr( void );

void key_short(volatile uint8_t *PIN, uint8_t key, uint8_t *L_Key, void \
  (*funkcja)(void));

void LED_OFF (void);
void LED_ON (void);

#endif /* EXTENDED_H_ */



ascii.c

/*
 * ascii.c
 *
 *  Created on: 21-02-2014
 *      Author: MODSezam
 */

#include <avr/io.h>
#include <avr/pgmspace.h>

#include "uart_vt100.h"
#include "extended.h"

//tablice znaków w pamięci flash - load
const char LOAD1[] PROGMEM = { "▓▓▒▒" };
const char LOAD2[] PROGMEM = { "LOADING      0%" };
const char LOAD3[] PROGMEM = { "░░░░░░░░░░░░░░░" };
//tablice znaków w pamięci flash - postać 1
const char POSTAC1_1[] PROGMEM = { "d8888o8888b"};
const char POSTAC1_2[] PROGMEM = { "88888888888"};
const char POSTAC1_3[] PROGMEM = { "d88888888888b"};
const char POSTAC1_4[] PROGMEM = { "`-..____HHHHHHHHHHHHH____.,-'"};
const char POSTAC1_5[] PROGMEM = { "/___, : .___\\"};
const char POSTAC1_6[] PROGMEM = { "_) >=-( )-=< (_"};
const char POSTAC1_7[] PROGMEM = { "( (    / \\    ) )"};
const char POSTAC1_8[] PROGMEM = { "\\_\\  ((_))  /_/"};
const char POSTAC1_9[] PROGMEM = { "|)/  :  \\(|"};
const char POSTAC1_10[] PROGMEM = { "|(,-----.)|"};
const char POSTAC1_11[] PROGMEM = { "\\   '\"`   /"};
const char POSTAC1_12[] PROGMEM = { "|`---\"---'|"};
const char POSTAC1_13[] PROGMEM = { "_______|   `-'   |_______"};
const char POSTAC1_14[] PROGMEM = { "/                         \\"};
const char POSTAC1_15[] PROGMEM = { "|                           |"};
const char POSTAC1_16[] PROGMEM = { "|     /               \\     |"};
const char POSTAC1_17[] PROGMEM = { "|     |               |     |"};
const char POSTAC1_18[] PROGMEM = { "|     |               |     |"};
//tablice znaków w pamięci flash - postać 2
const char POSTAC2_1[] PROGMEM = { ".-'--."};
const char POSTAC2_2[] PROGMEM = { ".'      '."};
const char POSTAC2_3[] PROGMEM = { "/     _    `-."};
const char POSTAC2_4[] PROGMEM = { "/      .\\-     \\,  ,"};
const char POSTAC2_5[] PROGMEM = { ";       .-|-'    \\####,"};
const char POSTAC2_6[] PROGMEM = { "|,       .-|-'    ;####"};
const char POSTAC2_7[] PROGMEM = { ",##         `     ,|###\""};
const char POSTAC2_8[] PROGMEM = { "#,####, \"#,        ,#|^;#"};
const char POSTAC2_9[] PROGMEM = { "`######  `#####,|##\" |`)|"};
const char POSTAC2_10[] PROGMEM = { "`#####    ```o\\`\\o_.| ;\\"};
const char POSTAC2_11[] PROGMEM = { "(-`\\#,    .-'` |`  : `;"};
const char POSTAC2_12[] PROGMEM = { "`\\ ;\\#,         \\   \\-'"};
const char POSTAC2_13[] PROGMEM = { ")( \\#    C,_   \\   ;"};
const char POSTAC2_14[] PROGMEM = { "(_,  \\  /   `'./   |"};
const char POSTAC2_15[] PROGMEM = { "\\  / | .-`'--'`. |"};
const char POSTAC2_16[] PROGMEM = { "| ( \\   ,  /_,  |"};
const char POSTAC2_17[] PROGMEM = { "\\    `   ``     /"};
const char POSTAC2_18[] PROGMEM = { "'-.__     // .'"};
const char POSTAC2_19[] PROGMEM = { "`'`.__.'"};
//tablice znaków w pamięci flash - postać 3
const char POSTAC3_1[] PROGMEM = { ".sSs."};
const char POSTAC3_2[] PROGMEM = { ".sSSSSSSSSSSs."};
const char POSTAC3_3[] PROGMEM = { ".sSS&$$$$$$$$$$&SSs."};
const char POSTAC3_4[] PROGMEM = { "sSS&$$$$$$$$$$$$$$&SSs."};
const char POSTAC3_5[] PROGMEM = { "sSS&$$$88P^\"  \"^T88$$$&SSs"};
const char POSTAC3_6[] PROGMEM = { "sSS$$8P\"            \"T8$$SSs"};
const char POSTAC3_7[] PROGMEM = { "sSSS$$'.gfbn._  _.nfbs.'$$$SSs"};
const char POSTAC3_8[] PROGMEM = { "sSSS&$8 ...__      __... 8$$SSSs"};
const char POSTAC3_9[] PROGMEM = { "!SSS&$$8 '. o :    : o .' 8$$$SSS!"};
const char POSTAC3_10[] PROGMEM = { "sSS&$$$8   \"-'   '  '-\"   8$$$$SSs"};
const char POSTAC3_11[] PROGMEM = { "!SS&$$$$!         :        !$$$$$SS!"};
const char POSTAC3_12[] PROGMEM = { "sSS&$$$8'          .       '8$$$&SSs"};
const char POSTAC3_13[] PROGMEM = { "!SSS$$$$8        ._ '        8$$$$SSS!"};
const char POSTAC3_14[] PROGMEM = { "sSS&$$$$8                    8$$$$&SSs"};
const char POSTAC3_15[] PROGMEM = { "SSS&$$$8!       .=-._        !8$$$&SSS"};
const char POSTAC3_16[] PROGMEM = { "!SS&$$$88a       \".-\"\"        e88$$$&SS!"};
const char POSTAC3_17[] PROGMEM = { "sSS&$$P888p.-._          _.-.g888T$$&SSs"};
const char POSTAC3_18[] PROGMEM = { "SSS$$88888P''-.\"--.__.--\".-''T8888$$$&SS"};
const char POSTAC3_19[] PROGMEM = { "SSg$$88P^\"     '-.____.-'     \"^T88$$&SS"};
//tablice znaków w pamięci flash - postać 4
const char POSTAC4_1[] PROGMEM = { "____"};
const char POSTAC4_2[] PROGMEM = { "_.' :  `._"};
const char POSTAC4_3[] PROGMEM = { ".-.'`.  ;   .'`.-."};
const char POSTAC4_4[] PROGMEM = { "__      / : ___\\ ;  /___ ; \\      __"};
const char POSTAC4_5[] PROGMEM = { ",'_ \"\"--.:__;\".-.\";: :\".-.\":__;.--\"\" _`,"};
const char POSTAC4_6[] PROGMEM = { ":' `.t\"\"--.. '<@.`;_  ',@>` ..--\"\"j.' `;"};
const char POSTAC4_7[] PROGMEM = { "`:-.._J '-.-'L__ `-- ' L_..-;'"};
const char POSTAC4_8[] PROGMEM = { "\"-.__ ;  .-\"  \"-.  : __.-\""};
const char POSTAC4_9[] PROGMEM = { "L ' /.------.\\ ' J"};
const char POSTAC4_10[] PROGMEM = { "\"-.   \"--\"   .-\""};
const char POSTAC4_11[] PROGMEM = { "__.l\"-:_JL_;-\";.__"};
const char POSTAC4_12[] PROGMEM = { ".-j/'.;  ;\"\"\"\"  / .'\\\"-."};
const char POSTAC4_13[] PROGMEM = { ".' /:`. \"-.:     .-\" .';  `."};
const char POSTAC4_14[] PROGMEM = { ".-\"  / ;  \"-. \"-..-\" .-\"  :    \"-."};
const char POSTAC4_15[] PROGMEM = { ".+\"-.  : :      \"-.__.-\"      ;-._   \\"};
const char POSTAC4_16[] PROGMEM = { ";    `.; ;                    :   \"+. ;"};
const char POSTAC4_17[] PROGMEM = { ":      ; ;                    :      \\:"};
const char POSTAC4_18[] PROGMEM = { ";      ; :                    ;        :"};
const char POSTAC4_19[] PROGMEM = { "; :                    ;"};
//tablice znaków w pamięci flash - 0
const char LICZBA0_1[] PROGMEM = { "00000000"};
const char LICZBA0_2[] PROGMEM = { "00    00"};
const char LICZBA0_3[] PROGMEM = { "00    00"};
const char LICZBA0_4[] PROGMEM = { "00    00"};
const char LICZBA0_5[] PROGMEM = { "00    00"};
const char LICZBA0_6[] PROGMEM = { "00    00"};
const char LICZBA0_7[] PROGMEM = { "00000000"};
//tablice znaków w pamięci flash - 1
const char LICZBA1_1[] PROGMEM = { "     11 "};
const char LICZBA1_2[] PROGMEM = { "   1111 "};
const char LICZBA1_3[] PROGMEM = { " 11  11 "};
const char LICZBA1_4[] PROGMEM = { "     11 "};
const char LICZBA1_5[] PROGMEM = { "     11 "};
const char LICZBA1_6[] PROGMEM = { "     11 "};
const char LICZBA1_7[] PROGMEM = { "     11 "};
//tablice znaków w pamięci flash - 2
const char LICZBA2_1[] PROGMEM = { "22222222"};
const char LICZBA2_2[] PROGMEM = { "      22"};
const char LICZBA2_3[] PROGMEM = { "      22"};
const char LICZBA2_4[] PROGMEM = { "22222222"};
const char LICZBA2_5[] PROGMEM = { "22      "};
const char LICZBA2_6[] PROGMEM = { "22      "};
const char LICZBA2_7[] PROGMEM = { "22222222"};
//tablice znaków w pamięci flash - 3
const char LICZBA3_1[] PROGMEM = { "33333333"};
const char LICZBA3_2[] PROGMEM = { "      33"};
const char LICZBA3_3[] PROGMEM = { "      33"};
const char LICZBA3_4[] PROGMEM = { "  333333"};
const char LICZBA3_5[] PROGMEM = { "      33"};
const char LICZBA3_6[] PROGMEM = { "      33"};
const char LICZBA3_7[] PROGMEM = { "33333333"};
//tablice znaków w pamięci flash - tabelka 1
const char OKNO_1[] PROGMEM = { "╔════════════════════════════════════╗"};
const char OKNO_2[] PROGMEM = { "║                                    ║"};
const char OKNO_3[] PROGMEM = { "║                                    ║"};
const char OKNO_4[] PROGMEM = { "║                                    ║"};
const char OKNO_5[] PROGMEM = { "║                                    ║"};
const char OKNO_6[] PROGMEM = { "║                                    ║"};
const char OKNO_7[] PROGMEM = { "╚════════════════════════════════════╝"};
//tablice znaków w pamięci flash - tabelka wyniki
const char TAB_WYN_1[] PROGMEM = { "╔══════════════╤═══════════════╗"};
const char TAB_WYN_2[] PROGMEM = { "║              │               ║"};
const char TAB_WYN_3[] PROGMEM = { "║              │  TRAFIONYCH:  ║"};
const char TAB_WYN_4[] PROGMEM = { "║              │               ║"};
const char TAB_WYN_5[] PROGMEM = { "║              │               ║"};
const char TAB_WYN_6[] PROGMEM = { "║              │     LEVEL:    ║"};
const char TAB_WYN_7[] PROGMEM = { "║              │               ║"};
const char TAB_WYN_8[] PROGMEM = { "║              │               ║"};
const char TAB_WYN_9[] PROGMEM = { "║              │ CZAS REAKCJI: ║"};
const char TAB_WYN_10[] PROGMEM = {"║              │   <       ms  ║"};
const char TAB_WYN_11[] PROGMEM = {"║              │               ║"};
const char TAB_WYN_12[] PROGMEM = {"╚══════════════╧═══════════════╝"};
//tablice znaków w pamięci flash - logo gry
const char REFLEX_1[] PROGMEM = { " ___ ___  ___  _    _____ __"};
const char REFLEX_2[] PROGMEM = { "| o \\ __|| __|| |  | __\\ V /"};
const char REFLEX_3[] PROGMEM = { "|   / _| | _| | |_ | _| ) ("};
const char REFLEX_4[] PROGMEM = { "|_|\\\\___||_|  |___||___/_n_\\"};
const char REFLEX_5[] PROGMEM = { "by MODSezam             v0.9"};
//tablice znaków w pamięci flash - hiscore
const char HI_SCORE_1[] PROGMEM = { "     H      "};
const char HI_SCORE_2[] PROGMEM = { "     I      "};
const char HI_SCORE_3[] PROGMEM = { "     S      "};
const char HI_SCORE_4[] PROGMEM = { "     C      "};
const char HI_SCORE_5[] PROGMEM = { "     O      "};
const char HI_SCORE_6[] PROGMEM = { "     R      "};
const char HI_SCORE_7[] PROGMEM = { "     E      "};
//funkcja animująca loading
void rysuj_loading(uint8_t y, uint8_t x){

 if (L_Load == 550){
  uart_tx_vt100_yx_col_string_PROG(y, x, WHITE, LOAD2 );
  uart_tx_vt100_yx_col_string_PROG(y+1, x, RED, LOAD3 );
 }
 if (L_Load == 540){
  uart_tx_vt100_yx_col_string(y, x+11, WHITE, " 13%" );
  uart_tx_vt100_yx_col_string(y+1, x, RED, "▒▒" );
 }
 if (L_Load == 530){
  uart_tx_vt100_yx_col_string(y, x+12, WHITE, "25%" );
  uart_tx_vt100_yx_col_string_PROG(y+1, x, RED, LOAD1 );
 }
 if (L_Load == 520){
  uart_tx_vt100_yx_col_string(y, x+12, WHITE, "37%" );
  uart_tx_vt100_yx_col_string_PROG(y+1, x+1, RED, LOAD1 );
 }
 if (L_Load == 510){
  uart_tx_vt100_yx_col_string(y, x+12, WHITE, "50%" );
  uart_tx_vt100_yx_col_string_PROG(y+1, x+3, RED, LOAD1 );
 }
 if (L_Load == 500){
  uart_tx_vt100_yx_col_string(y, x+12, WHITE, "63%" );
  uart_tx_vt100_yx_col_string_PROG(y+1, x+5, RED, LOAD1 );
 }
 if (L_Load == 490){
  uart_tx_vt100_yx_col_string(y, x+12, WHITE, "75%" );
  uart_tx_vt100_yx_col_string_PROG(y+1, x+7, RED, LOAD1 );
 }
 if (L_Load == 480){
  uart_tx_vt100_yx_col_string(y, x+12, WHITE, "87%" );
  uart_tx_vt100_yx_col_string_PROG(y+1, x+9, RED, LOAD1 );
 }
 if (L_Load == 470){
  uart_tx_vt100_yx_col_string(y, x+11, WHITE, "100%" );
  uart_tx_vt100_yx_col_string_PROG(y+1, x+11, RED, LOAD1 );
 }
 if (L_Load == 460){
  uart_tx_vt100_yx_col_string(y+1, x+13, 0, "▓▓" );
 }
}

//funkcja czyszcząca loading
void erase_load (uint8_t y, uint8_t x){
 uart_tx_vt100_yx_col_string(y, x, 0, "               " );
 uart_tx_vt100_yx_col_string(y+1, x, 0, "               " );
}
//funkcja rysująca postać 1
void rysuj_postac1(uint8_t y, uint8_t x){
 uart_tx_vt100_yx_col_string_PROG(y, x+9, CYAN, POSTAC1_1);
 uart_tx_vt100_yx_col_string_PROG(y+1, x+9, 0, POSTAC1_2);
 uart_tx_vt100_yx_col_string_PROG(y+2, x+8, 0, POSTAC1_3);
 uart_tx_vt100_yx_col_string_PROG(y+3, x, 0, POSTAC1_4);
 uart_tx_vt100_yx_col_string_PROG(y+4, x+8, 0, POSTAC1_5);
 uart_tx_vt100_yx_col_string_PROG(y+5, x+7, 0, POSTAC1_6);
 uart_tx_vt100_yx_col_string_PROG(y+6, x+6, 0, POSTAC1_7);
 uart_tx_vt100_yx_col_string_PROG(y+7, x+7, 0, POSTAC1_8);
 uart_tx_vt100_yx_col_string_PROG(y+8, x+9, 0, POSTAC1_9);
 uart_tx_vt100_yx_col_string_PROG(y+9, x+9, 0, POSTAC1_10);
 uart_tx_vt100_yx_col_string_PROG(y+10, x+9, 0, POSTAC1_11);
 uart_tx_vt100_yx_col_string_PROG(y+11, x+9, 0, POSTAC1_12);
 uart_tx_vt100_yx_col_string_PROG(y+12, x+2, 0, POSTAC1_13);
 uart_tx_vt100_yx_col_string_PROG(y+13, x+1, 0, POSTAC1_14);
 uart_tx_vt100_yx_col_string_PROG(y+14, x, 0, POSTAC1_15);
 uart_tx_vt100_yx_col_string_PROG(y+15, x, 0, POSTAC1_16);
 uart_tx_vt100_yx_col_string_PROG(y+16, x, 0, POSTAC1_17);
 uart_tx_vt100_yx_col_string_PROG(y+17, x, 0, POSTAC1_18);
}
//funkcja rysująca postać 2
void rysuj_postac2(uint8_t y, uint8_t x){
 uart_tx_vt100_yx_col_string_PROG(y, x+8, MAGENTA, POSTAC2_1);
 uart_tx_vt100_yx_col_string_PROG(y+1, x+6, 0, POSTAC2_2);
 uart_tx_vt100_yx_col_string_PROG(y+2, x+5, 0, POSTAC2_3);
 uart_tx_vt100_yx_col_string_PROG(y+3, x+4, 0, POSTAC2_4);
 uart_tx_vt100_yx_col_string_PROG(y+4, x+3, 0, POSTAC2_5);
 uart_tx_vt100_yx_col_string_PROG(y+5, x+3, 0, POSTAC2_6);
 uart_tx_vt100_yx_col_string_PROG(y+6, x+2, 0, POSTAC2_7);
 uart_tx_vt100_yx_col_string_PROG(y+7, x, 0, POSTAC2_8);
 uart_tx_vt100_yx_col_string_PROG(y+8, x, 0, POSTAC2_9);
 uart_tx_vt100_yx_col_string_PROG(y+9, x+1, 0, POSTAC2_10);
 uart_tx_vt100_yx_col_string_PROG(y+10, x+2, 0, POSTAC2_11);
 uart_tx_vt100_yx_col_string_PROG(y+11, x+2, 0, POSTAC2_12);
 uart_tx_vt100_yx_col_string_PROG(y+12, x+4, 0, POSTAC2_13);
 uart_tx_vt100_yx_col_string_PROG(y+13, x+4, 0, POSTAC2_14);
 uart_tx_vt100_yx_col_string_PROG(y+14, x+6, 0, POSTAC2_15);
 uart_tx_vt100_yx_col_string_PROG(y+15, x+7, 0, POSTAC2_16);
 uart_tx_vt100_yx_col_string_PROG(y+16, x+7, 0, POSTAC2_17);
 uart_tx_vt100_yx_col_string_PROG(y+17, x+8, 0, POSTAC2_18);
 uart_tx_vt100_yx_col_string_PROG(y+18, x+13, 0, POSTAC2_19);
}
//funkcja rysująca postać 3
void rysuj_postac3(uint8_t y, uint8_t x){
 uart_tx_vt100_yx_col_string_PROG(y, x+17, BLUE, POSTAC3_1);
 uart_tx_vt100_yx_col_string_PROG(y+1, x+13, 0, POSTAC3_2);
 uart_tx_vt100_yx_col_string_PROG(y+2, x+10, 0, POSTAC3_3);
 uart_tx_vt100_yx_col_string_PROG(y+3, x+9, 0, POSTAC3_4);
 uart_tx_vt100_yx_col_string_PROG(y+4, x+7, 0, POSTAC3_5);
 uart_tx_vt100_yx_col_string_PROG(y+5, x+6, 0, POSTAC3_6);
 uart_tx_vt100_yx_col_string_PROG(y+6, x+5, 0, POSTAC3_7);
 uart_tx_vt100_yx_col_string_PROG(y+7, x+4, 0, POSTAC3_8);
 uart_tx_vt100_yx_col_string_PROG(y+8, x+3, 0, POSTAC3_9);
 uart_tx_vt100_yx_col_string_PROG(y+9, x+3, 0, POSTAC3_10);
 uart_tx_vt100_yx_col_string_PROG(y+10, x+2, 0, POSTAC3_11);
 uart_tx_vt100_yx_col_string_PROG(y+11, x+2, 0, POSTAC3_12);
 uart_tx_vt100_yx_col_string_PROG(y+12, x+1, 0, POSTAC3_13);
 uart_tx_vt100_yx_col_string_PROG(y+13, x+1, 0, POSTAC3_14);
 uart_tx_vt100_yx_col_string_PROG(y+14, x+1, 0, POSTAC3_15);
 uart_tx_vt100_yx_col_string_PROG(y+15, x, 0, POSTAC3_16);
 uart_tx_vt100_yx_col_string_PROG(y+16, x, 0, POSTAC3_17);
 uart_tx_vt100_yx_col_string_PROG(y+17, x, 0, POSTAC3_18);
 uart_tx_vt100_yx_col_string_PROG(y+18, x, 0, POSTAC3_19);
}
//funkcja rysująca postać 4
void rysuj_postac4(uint8_t y, uint8_t x){
 uart_tx_vt100_yx_col_string_PROG(y, x+18, GREEN, POSTAC4_1);
 uart_tx_vt100_yx_col_string_PROG(y+1, x+15, 0, POSTAC4_2);
 uart_tx_vt100_yx_col_string_PROG(y+2, x+11, 0, POSTAC4_3);
 uart_tx_vt100_yx_col_string_PROG(y+3, x+2, 0, POSTAC4_4);
 uart_tx_vt100_yx_col_string_PROG(y+4, x, 0, POSTAC4_5);
 uart_tx_vt100_yx_col_string_PROG(y+5, x, 0, POSTAC4_6);
 uart_tx_vt100_yx_col_string_PROG(y+6, x+5, 0, POSTAC4_7);
 uart_tx_vt100_yx_col_string_PROG(y+7, x+7, 0, POSTAC4_8);
 uart_tx_vt100_yx_col_string_PROG(y+8, x+11, 0, POSTAC4_9);
 uart_tx_vt100_yx_col_string_PROG(y+9, x+12, 0, POSTAC4_10);
 uart_tx_vt100_yx_col_string_PROG(y+10, x+11, YELLOW, POSTAC4_11);
 uart_tx_vt100_yx_col_string_PROG(y+11, x+8, 0, POSTAC4_12);
 uart_tx_vt100_yx_col_string_PROG(y+12, x+6, 0, POSTAC4_13);
 uart_tx_vt100_yx_col_string_PROG(y+13, x+3, 0, POSTAC4_14);
 uart_tx_vt100_yx_col_string_PROG(y+14, x, 0, POSTAC4_15);
 uart_tx_vt100_yx_col_string_PROG(y+15, x, 0, POSTAC4_16);
 uart_tx_vt100_yx_col_string_PROG(y+16, x, 0, POSTAC4_17);
 uart_tx_vt100_yx_col_string_PROG(y+17, x, 0, POSTAC4_18);
 uart_tx_vt100_yx_col_string_PROG(y+18, x+7, 0, POSTAC4_19);
}
//funkcja rysująca dużą liczbę 0
void rysuj_liczba0(uint8_t y, uint8_t x){
 uart_tx_vt100_yx_col_string_PROG(y, x, 0, LICZBA0_1);
 uart_tx_vt100_yx_col_string_PROG(y+1, x, 0, LICZBA0_2);
 uart_tx_vt100_yx_col_string_PROG(y+2, x, 0, LICZBA0_3);
 uart_tx_vt100_yx_col_string_PROG(y+3, x, 0, LICZBA0_4);
 uart_tx_vt100_yx_col_string_PROG(y+4, x, 0, LICZBA0_5);
 uart_tx_vt100_yx_col_string_PROG(y+5, x, 0, LICZBA0_6);
 uart_tx_vt100_yx_col_string_PROG(y+6, x, 0, LICZBA0_7);
}
//funkcja rysująca dużą liczbę 1
void rysuj_liczba1(uint8_t y, uint8_t x){
 uart_tx_vt100_yx_col_string_PROG(y, x, 0, LICZBA1_1);
 uart_tx_vt100_yx_col_string_PROG(y+1, x, 0, LICZBA1_2);
 uart_tx_vt100_yx_col_string_PROG(y+2, x, 0, LICZBA1_3);
 uart_tx_vt100_yx_col_string_PROG(y+3, x, 0, LICZBA1_4);
 uart_tx_vt100_yx_col_string_PROG(y+4, x, 0, LICZBA1_5);
 uart_tx_vt100_yx_col_string_PROG(y+5, x, 0, LICZBA1_6);
 uart_tx_vt100_yx_col_string_PROG(y+6, x, 0, LICZBA1_7);
}
//funkcja rysująca dużą liczbę 2
void rysuj_liczba2(uint8_t y, uint8_t x){
 uart_tx_vt100_yx_col_string_PROG(y, x, 0, LICZBA2_1);
 uart_tx_vt100_yx_col_string_PROG(y+1, x, 0, LICZBA2_2);
 uart_tx_vt100_yx_col_string_PROG(y+2, x, 0, LICZBA2_3);
 uart_tx_vt100_yx_col_string_PROG(y+3, x, 0, LICZBA2_4);
 uart_tx_vt100_yx_col_string_PROG(y+4, x, 0, LICZBA2_5);
 uart_tx_vt100_yx_col_string_PROG(y+5, x, 0, LICZBA2_6);
 uart_tx_vt100_yx_col_string_PROG(y+6, x, 0, LICZBA2_7);
}
//funkcja rysująca dużą liczbę 3
void rysuj_liczba3(uint8_t y, uint8_t x){
 uart_tx_vt100_yx_col_string_PROG(y, x, 0, LICZBA3_1);
 uart_tx_vt100_yx_col_string_PROG(y+1, x, 0, LICZBA3_2);
 uart_tx_vt100_yx_col_string_PROG(y+2, x, 0, LICZBA3_3);
 uart_tx_vt100_yx_col_string_PROG(y+3, x, 0, LICZBA3_4);
 uart_tx_vt100_yx_col_string_PROG(y+4, x, 0, LICZBA3_5);
 uart_tx_vt100_yx_col_string_PROG(y+5, x, 0, LICZBA3_6);
 uart_tx_vt100_yx_col_string_PROG(y+6, x, 0, LICZBA3_7);
}
//funkcja rysująca tabelkę 1
void rysuj_okno(uint8_t y, uint8_t x){
 uart_tx_vt100_yx_col_string_PROG(y, x, 0, OKNO_1);
 uart_tx_vt100_yx_col_string_PROG(y+1, x, 0, OKNO_2);
 uart_tx_vt100_yx_col_string_PROG(y+2, x, 0, OKNO_3);
 uart_tx_vt100_yx_col_string_PROG(y+3, x, 0, OKNO_4);
 uart_tx_vt100_yx_col_string_PROG(y+4, x, 0, OKNO_5);
 uart_tx_vt100_yx_col_string_PROG(y+5, x, 0, OKNO_6);
 uart_tx_vt100_yx_col_string_PROG(y+6, x, 0, OKNO_7);
}
//funkcja rysująca tabelkę wyników
void rysuj_tab_wyn(uint8_t y, uint8_t x){
 uart_tx_vt100_yx_col_string_PROG(y, x, 0, TAB_WYN_1);
 uart_tx_vt100_yx_col_string_PROG(y+1, x, 0, TAB_WYN_2);
 uart_tx_vt100_yx_col_string_PROG(y+2, x, 0, TAB_WYN_3);
 uart_tx_vt100_yx_col_string_PROG(y+3, x, 0, TAB_WYN_4);
 uart_tx_vt100_yx_col_string_PROG(y+4, x, 0, TAB_WYN_5);
 uart_tx_vt100_yx_col_string_PROG(y+5, x, 0, TAB_WYN_6);
 uart_tx_vt100_yx_col_string_PROG(y+6, x, 0, TAB_WYN_7);
 uart_tx_vt100_yx_col_string_PROG(y+7, x, 0, TAB_WYN_8);
 uart_tx_vt100_yx_col_string_PROG(y+8, x, 0, TAB_WYN_9);
 uart_tx_vt100_yx_col_string_PROG(y+9, x, 0, TAB_WYN_10);
 uart_tx_vt100_yx_col_string_PROG(y+10, x, 0, TAB_WYN_11);
 uart_tx_vt100_yx_col_string_PROG(y+11, x, 0, TAB_WYN_12);
}
//funkcja rysująca logo
void rysuj_logo(uint8_t y, uint8_t x){
 uart_tx_vt100_yx_col_string_PROG(y, x, 0, REFLEX_1);
 uart_tx_vt100_yx_col_string_PROG(y+1, x, 0, REFLEX_2);
 uart_tx_vt100_yx_col_string_PROG(y+2, x, 0, REFLEX_3);
 uart_tx_vt100_yx_col_string_PROG(y+3, x, 0, REFLEX_4);
 uart_tx_vt100_yx_col_string_PROG(y+4, x, 0, REFLEX_5);
}
//funkcja rysująca pionowy napis hiscore
void rysuj_hiscore(uint8_t y, uint8_t x){
 uart_tx_vt100_yx_col_string_PROG(y, x, 0, HI_SCORE_1);
 uart_tx_vt100_yx_col_string_PROG(y+1, x, 0, HI_SCORE_2);
 uart_tx_vt100_yx_col_string_PROG(y+3, x, 0, HI_SCORE_3);
 uart_tx_vt100_yx_col_string_PROG(y+4, x, 0, HI_SCORE_4);
 uart_tx_vt100_yx_col_string_PROG(y+5, x, 0, HI_SCORE_5);
 uart_tx_vt100_yx_col_string_PROG(y+6, x, 0, HI_SCORE_6);
 uart_tx_vt100_yx_col_string_PROG(y+7, x, 0, HI_SCORE_7);
}



ascii.h

tuuu

/*
 * ascii.h
 *
 *  Created on: 21-02-2014
 *      Author: MODSezam
 */

#ifndef ASCII_H_
#define ASCII_H_


//deklaracje funkcji
void rysuj_loading (uint8_t x, uint8_t y);
void erase_load (uint8_t x, uint8_t y);
void rysuj_postac1 (uint8_t x, uint8_t y);
void rysuj_postac2 (uint8_t x, uint8_t y);
void rysuj_postac3 (uint8_t x, uint8_t y);
void rysuj_postac4 (uint8_t x, uint8_t y);
void rysuj_liczba0(uint8_t x, uint8_t y);
void rysuj_liczba1(uint8_t x, uint8_t y);
void rysuj_liczba2(uint8_t x, uint8_t y);
void rysuj_liczba3(uint8_t x, uint8_t y);
void rysuj_okno(uint8_t x, uint8_t y);
void rysuj_tab_wyn(uint8_t x, uint8_t y);
void rysuj_logo(uint8_t x, uint8_t y);
void rysuj_hiscore(uint8_t x, uint8_t y);

#endif /* ASCII_H_ */



uart_vt100.c

/*
 * uart.c
 *
 *  Created on: 11-02-2014
 *      Author: MODSezam
 */

#include<avr/io.h>
#include<avr/interrupt.h>
#include<avr/pgmspace.h>
#include<stdlib.h>

#include"uart_vt100.h"

volatile uint8_t interrupt_flag = 0; //flaga uart
volatile uint8_t uart_tx_first_byte, uart_tx_last_byte;

//bufor uart
char uart_tx_buf[UART_TX_BUF_SIZE];

//uart inicjalizacja
void uart_tx_initialize(uint16_t baud_rate){
 UBRRL = (uint8_t) baud_rate;
 UBRRH = (baud_rate>>8);
 UCSRB = (1<<TXCIE)|(1<<TXEN);
}

//wysyłanie znaku
void uart_tx_char(char data){
 uart_tx_buf[uart_tx_last_byte] = data;
 uart_tx_last_byte = (uart_tx_last_byte + 1) & UART_TX_BUF_MASK;
 while(uart_tx_first_byte == uart_tx_last_byte);
 if(interrupt_flag == 0){
   interrupt_flag = 1;
   UDR = uart_tx_buf[uart_tx_first_byte];
 }
}

//wysyłanie liczb całkowitych
void uart_tx_int(uint16_t data){
 char temp_buffer[8];
 itoa(data, temp_buffer, 10);
 uart_tx_string(temp_buffer);
}

//wysyłnie ciągu znaków
void uart_tx_string(char *string){
 while(*string) uart_tx_char(*string++);
}

//wysyłanie ciągu naków z pamięci flash
void uart_tx_string_PROG(const char *string){
 while(pgm_read_byte(string)) uart_tx_char(pgm_read_byte(string++));
}

//czyszczenie ekranu terinala
void vt100_cls(void){
 uart_tx_string ("\x1b[2J"); //<ESC>[2J
}

//ukrycie kursora - cur_off = 1, włączenie czur_off = 0
void vt100_cur_off (uint8_t cur_off){
 if (cur_off == 1) uart_tx_string ("\x1b[?25l"); //<ESC>[?25l
 else uart_tx_string ("\x1b[?25h"); //<ESC>[?25h
}

//ustawienie koloru czcionki
void vt100_col (uint8_t color){
 uart_tx_char(0x1b );
 uart_tx_char('[' );
 uart_tx_int(color);
 uart_tx_char('m' );
}

//ustawienie współrzędnych kursora
void vt100_yx_col( uint8_t y, uint8_t x, uint8_t color) {
 uart_tx_char(0x1b ); //<ESC>[<y>;<x>H
 uart_tx_char('[' );
 uart_tx_int( y );
 uart_tx_char(';' );
 uart_tx_int( x );
 uart_tx_char('H' );
 if (color != 0){
  uart_tx_char(0x1b );  //<ESC>[<color>m
  uart_tx_char('[' );
  uart_tx_int(color);
  uart_tx_char('m' );
 }
}

//wysłnie komendy BELL - dzwonek
void vt100_bell (void) {
 uart_tx_string("\x1b\x07"); //<ESC><BELL>
}

//wysłenie ciągu znaków przez uart
//ustawiając współrzędne kursora i kolor czcionki
void uart_tx_vt100_yx_col_string ( uint8_t y, uint8_t x, uint8_t color, char *string){
 vt100_yx_col( y, x, color);
 while(*string) uart_tx_char(*string++);
}

//wysłenie ciągu znaków z pamięci flash przez uart
//ustawiając współrzędne kursora i kolor czcionki
void uart_tx_vt100_yx_col_string_PROG ( uint8_t y, uint8_t x, uint8_t color,const char *string){
 vt100_yx_col( y, x, color);
 while(pgm_read_byte(string)) uart_tx_char(pgm_read_byte(string++));
}

//przerwanie
ISR(USART_TXC_vect)
{
 uart_tx_first_byte = (uart_tx_first_byte + 1) & UART_TX_BUF_MASK;
 if(uart_tx_first_byte != uart_tx_last_byte){
  UDR = uart_tx_buf[uart_tx_first_byte];
 }
 else{
  interrupt_flag = 0;
 }
}




uart_vt100.h

/*
 * uart.h
 *
 *  Created on: 11-02-2014
 *      Author: MODSezam
 */

#ifndef UART_H_
#define UART_H_

#define BLACK 30
#define RED 31
#define GREEN 32
#define YELLOW 33
#define BLUE 34
#define MAGENTA 35
#define CYAN 36
#define WHITE 37


//zmienne
#define UART_TX_BUF_SIZE 16
#define UART_TX_BUF_MASK (UART_TX_BUF_SIZE-1)

#define BAUD_RATE 230400
#define __UBRR ((F_CPU+BAUD_RATE*8UL) / (16UL*BAUD_RATE)-1)

//deklaracje funkcji
void uart_tx_initialize(uint16_t baud_rate);
void uart_tx_char(char data);
void uart_tx_string(char * string);
void uart_tx_string_PROG(const char *string);
void uart_tx_int(uint16_t data);

void vt100_col (uint8_t color);
void vt100_cls(void);
void vt100_cur_off (uint8_t cur_off);
void vt100_yx_col( uint8_t y, uint8_t x, uint8_t color);
void vt100_bell (void);
void uart_tx_vt100_yx_col_string ( uint8_t y, uint8_t x, uint8_t color, char *string);
void uart_tx_vt100_yx_col_string_PROG ( uint8_t y, uint8_t x, uint8_t color,const char *string);


#endif /* UART_H_ */


Oceń artykuł.
Wasze opinie są dla nas ważne, gdyż pozwalają dopracować poszczególne artykuły.
Pozdrawiamy, Autorzy
Ten artykuł oceniam na:

Brak komentarzy:

Prześlij komentarz

Działy
Działy dodatkowe
Inne
O blogu




Dzisiaj
--> za darmo!!! <--
1. USBasp
2. microBOARD M8


Napisz artykuł
--> i wygraj nagrodę. <--


Co nowego na blogu?
Śledź naszego Facebook-a



Co nowego na blogu?
Śledź nas na Google+

/* 20140911 Wyłączona prawa kolumna */
  • 00

    dni

  • 00

    godzin

  • :
  • 00

    minut

  • :
  • 00

    sekund

Nie czekaj do ostatniego dnia!
Jakość opisu projektu także jest istotna (pkt 9.2 regulaminu).

Sponsorzy:

Zapamiętaj ten artykuł w moim prywatnym spisie treści.