Przystąpiłem do lekcji 10. Zrobiłem analogiczne poprawki, jak w lekcji 9, ale niestety również nie mogę skompilować kodu. Poświęciłem praktycznie cały dzień na szukaniu przyczyny.
Pojawiają się takie błędy przy kompilacji:
Tutaj zamieszczam kod programu po moich poprawkach:
Tutaj kod orginalny:
http://www.sendspace.com/file/slcc8q
Co należy jeszcze poprawić, aby była możliwość kompilacji??
Pojawiają się takie błędy przy kompilacji:
![[ATmega32][C] Kurs progamowania w C z EdW Lekcja 10 [ATmega32][C] Kurs progamowania w C z EdW Lekcja 10](https://obrazki.elektroda.pl/4932303600_1293947517_thumb.jpg)
Tutaj zamieszczam kod programu po moich poprawkach:
/////////////////////////////////////////////////////////////////////////////////////////////
// main.c - testowanie możliwości zmiany języka
//
// Autor: Radosław Koppel Kompilator: WinAVR 20060125
/////////////////////////////////////////////////////////////////////////////////////////////
#include <avr/io.h>
#include <stdio.h>
#include <util/delay.h>
#include "makra.h"
#include "harddef.h"
//#include "makra.h"
#include "lcd.h"
#include "langsys.h"
void uint8_t sw_wait(void)
{
for(;;)
{
// Oczekiwanie na naciśnięcie przycisku
if(!(PIN(SW_PORT) & 1<<SW1))
{
_delay_ms(30);
if(!(PIN(SW_PORT) & 1<<SW1))
return 1;
}
if(!(PIN(SW_PORT) & 1<<SW2))
{
_delay_ms(30);
if(!(PIN(SW_PORT) & 1<<SW2))
return 2;
}
}
}
int main(void)
{
// Inicjacja wyprowadzeń
DDR(LCD_CTRLPORT) = (1<<LCD_E | 1<<LCD_RW | 1<<LCD_RS | 1<<LCD_LED);
PORT(LCD_CTRLPORT) = ~(1<<LCD_E | 1<<LCD_LED);
PORT(SW_PORT) = 1<<SW1 | 1<<SW2;
// Inicjacja wyświetlacza
lcd_Init();
lcd_SetStatus(LCD_STATUS_DISP);
// Wyświetlenie zapytania o język
fputs_P(PSTR("S1 - "), lcd_GetFile());
fputs_P(langsys_GetLangName(0), lcd_GetFile());
lcd_GoTo(0, 1);
fputs_P(PSTR("S2 - "), lcd_GetFile());
fputs_P(langsys_GetLangName(1), lcd_GetFile());
lcd_Update();
// Oczekiwanie na przycisk i wybranie odpowiedniego języka
langsys_Select(sw_wait()-1);
// Wyświetlenie przywitania w wybranym języku
lcd_Cls();
fputs_P(langsys_GetText(IDS_Start), lcd_GetFile());
lcd_Update();
return 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////
// lcd.c - plik źródłowy do obsługi alfanumerycznego wyświetlacza LCD.
// ! Dynamiczne przydzielanie znaków specjalnych !
//
// Autor: Radosław Koppel Kompilator: WinAVR 20060125
/////////////////////////////////////////////////////////////////////////////////////////////
#include <avr/io.h>
#include <inttypes.h>
#include <util/delay.h>
#include <string.h>
#include <avr/pgmspace.h>
#include "makra.h"
#include "harddef.h"
#include "lcd.h"
#include "langsys.h"
//__________________________________________________________________________________________
// Definicje stałych
// Komendy sterujące wyświetlaczem
#define LCDC_CLS 0x01
#define LCDC_HOME 0x02
#define LCDC_MODE 0x04
#define LCDC_MODER 0x02
#define LCDC_MODEL 0
#define LCDC_MODEMOVE 0x01
#define LCDC_ON 0x08
#define LCDC_ONDISPLAY 0x04
#define LCDC_ONCURSOR 0x02
#define LCDC_ONBLINK 0x01
#define LCDC_SHIFT 0x10
#define LCDC_SHIFTDISP 0x08
#define LCDC_SHIFTR 0x04
#define LCDC_SHIFTL 0
#define LCDC_FUNC 0x20
#define LCDC_FUNC8b 0x10
#define LCDC_FUNC4b 0
#define LCDC_FUNC2L 0x08
#define LCDC_FUNC1L 0
#define LCDC_FUNC5x10 0x4
#define LCDC_FUNC5x7 0
#define LCDC_CGA 0x40
#define LCDC_DDA 0x80
//__________________________________________________________________________________________
// Deklaracje funkcji które muszą być tutaj zdeklarowane
static int lcd_put(char c, FILE* f);
//__________________________________________________________________________________________
// Zmienne
// Korzystamy z nowej możliwości avrlibc 1.4
static FILE lcd_fLCD_temp = FDEV_SETUP_STREAM(lcd_put, NULL, _FDEV_SETUP_WRITE);
#define lcd_fLCD (&lcd_fLCD_temp)
// Uwaga - wyświetlacz niewykorzystuje kodów 0x80-0x9f. To 32 kody które zostaną wykorzystane dla znaków specjalnych
static char lcd_buffer[LCD_SX*LCD_SY];
// Aktualne pozycja kursora (dotyczy bufora i jest aktualizwana przy odświerzaniu napisu)
static uint8_t lcd_curpos;
// Informacja o tym jakie znaki specjalne zostały zapisane do wyświetlacza
static uint8_t lcd_spec[8];
// Zmienna przechowująca flagi na temat włączenia wyświetlacza (wyświetlacz, kursor, migający kursor)
static uint8_t lcd_status;
//__________________________________________________________________________________________
// Obsługa LCD - funkcje niskiego poziomu
// Impuls ENABLE - przede wszystkim dla zapisu
// Odczyt wymaga trochę bardziej skomplikowanej sekwencji
#define lcd_epulse() \
{PORT(LCD_CTRLPORT) |= 1<<LCD_E; \
_delay_us(0.25); \
PORT(LCD_CTRLPORT) &= ~(1<<LCD_E);}
// Odbiór danej - funkcja wewnętrzna
static inline uint8_t lcd_Get(void)
{
uint8_t dana;
// Ustawienie portu lcd jako wejścia
DDR(LCD_DATAPORT) = 0x00;
// Aktywacja odczytu
PORT(LCD_CTRLPORT) |= 1<<LCD_E;
// \/ Uwaga - sprawdziłem eksperymentalnie,
// \/ że 0.5us to czasami za mało
// \/ przy podłączonym programatorze wyświetlacz
// \/ wciąż gubił dane
_delay_us(1);
// Skopiowanie danych z wyjścia modułu
dana = PIN(LCD_DATAPORT);
// Deaktywacja wyjścia ENABLE
PORT(LCD_CTRLPORT) &= ~(1<<LCD_E);
return dana;
}
uint8_t lcd_GetBF(void)
{
// Wysterowanie wyprowadzeń do odczytu statusu
PORT(LCD_CTRLPORT) |= 1<<LCD_RW;
PORT(LCD_CTRLPORT) &= ~(1<<LCD_RS);
// Odczekanie wymaganego przez sterownik czasu
_delay_us(0.25);
// Odczyt danej
return lcd_Get();
}
// Sprawdza flagę zajętości i czeka na jej wyzerowanie
void lcd_WaitBF(void)
{
// Bit zajętości to bit najstarszy
while(0 != (0x80 & lcd_GetBF())) {};
}
// Wysłanie danej - funkcja wewnętrzna
static void lcd_Send(uint8_t dana)
{
// Ustawienie portu lcd jako wyjścia
DDR(LCD_DATAPORT) = 0xFF;
// Presłanie na port danej
PORT(LCD_DATAPORT) = dana;
// Przesłanie do lcd
lcd_epulse();
}
// Wysłanie danej do pamięci DDRAM lub CGRAM
// Zależnie od ustawionego adresu
void lcd_SendData(uint8_t dana)
{
lcd_WaitBF();
// Wysterowanie wyprowadzeń dla zapisu danej
PORT(LCD_CTRLPORT) &= ~(1<<LCD_RW);
PORT(LCD_CTRLPORT) |= 1<<LCD_RS;
// Odczekanie oraz wysłanie
_delay_us(0.25);
lcd_Send(dana);
}
// Wysłanie instrukcji sterującej
void lcd_SendInstr(uint8_t dana)
{
lcd_WaitBF();
// Wysterowanie wyprowadzeń dla zapisu instrukcji
PORT(LCD_CTRLPORT) &= ~(1<<LCD_RW | 1<<LCD_RS);
// Odczekanie oraz wysłanie
_delay_us(0.25);
lcd_Send(dana);
}
//__________________________________________________________________________________________
// Funkcje obsługujące wejście wyjście strumienia
static int lcd_put(char c, FILE* f)
{
// Zabezpieczenie przed przepełnieniem
if(lcd_curpos >= ELEMS(lcd_buffer))
lcd_curpos = 0;
// Zapis do bufora
lcd_buffer[lcd_curpos++] = c;
return 0;
}
//__________________________________________________________________________________________
// Funkcje interfejsu
// inicjacja LCD (uwaga - nie włączam wyświetlacza ani kursora)
void lcd_Init(void)
{
lcd_Cls();
PORT(LCD_CTRLPORT) &= ~(1<<LCD_RW | 1<<LCD_RS);
_delay_us(0.25);
lcd_Send(LCDC_FUNC | LCDC_FUNC8b);
_delay_ms(4.3);
lcd_Send(LCDC_FUNC | LCDC_FUNC8b);
_delay_us(200);
lcd_Send(LCDC_FUNC | LCDC_FUNC8b);
// Już można sprawdzać BF
#if LCD_SY == 1
lcd_SendInstr(LCDC_FUNC | LCDC_FUNC8b | LCDC_FUNC1L);
#else
lcd_SendInstr(LCDC_FUNC | LCDC_FUNC8b | LCDC_FUNC2L);
#endif
lcd_SendInstr(LCDC_ON);
lcd_SendInstr(LCDC_CLS);
lcd_SendInstr(LCDC_MODE | LCDC_MODER);
lcd_WaitBF();
// Koniec inicjacji. Wyjątkowo czekam na zakończenie. Normalnie BF jest sprawdzana przed wykonaniem indtrukcji
// - daje to większą oszczędność czasu. Podczas inicjacji nie ma to wielkiego znaczenia.
}
// Zerowanie bufora wyświetlacza
void lcd_Cls(void)
{
lcd_curpos = 0;
memset(lcd_buffer, ' ', sizeof(lcd_buffer));
}
// kontrola włączenia wyświetlacza, kursora, migającego kursora
void lcd_SetStatus(uint8_t status)
{
lcd_status = status;
}
// Odswierzenie statusu
inline void lcd_UpdateStatus(void)
{
lcd_SendInstr(LCDC_ON | lcd_status);
}
// Funkcja wewnętrzna podająca początek danej linii
static uint8_t lcd_LineStart(uint8_t line)
{
#if LCD_SY == 1
return LCD_LINE1;
#elif LCD_SY == 2
if(line == 0)
return LCD_LINE1;
else
return LCD_LINE2;
#elif LCD_SY == 4
if(line == 0)
return LCD_LINE1;
else if(linenum == 1)
return LCD_LINE2;
else if(linenum == 2)
return LCD_LINE3;
else
return LCD_LINE4;
#else
#error Unknown display type!
#endif
}
// Ustawienie kursora
inline void lcd_GoToAdr(uint8_t adr)
{
lcd_curpos = adr;
}
// Odswierzenie pozycji kursora
void lcd_UpdateCurPos(void)
{
// Obliczenie adresu w wyświetlaczu
uint8_t adres =
lcd_LineStart(lcd_curpos / LCD_SX) + (lcd_curpos % LCD_SX);
// Wysłanie instrkucji ustawiającej kursor
lcd_SendInstr(LCDC_DDA | adres);
}
// Wewnętrzna pomocnicza funkcja sprawdzająca czy dany znak jest znakiem specjalnym
static uint8_t lcd_IsSpec(char c)
{
// Przydział znaków specjalnych na obszar którego LCD nie wykorzystuje
return (c >= 0x80) && (c <= 0x9f);
}
// Zamiana znaku specjalnego na odpowiedni numer w tablicy symboli
static inline uint8_t lcd_Spec2Index(char c)
{
return c-0x80;
}
// Funkcja sprawdzajaca czy w tablicy jest podany znak
// Zwraca: indeks w tablicy gdzie znajduje sie dany znak
// lub kod znaku alternatywnego (zawsze >= 0x20)
static uint8_t lcd_GetSpec(uint8_t s_index)
{
// Zabezpieczenie
if(langsys_GetSpec() == NULL)
return 0x20;
uint8_t a;
for(a=0; a<ELEMS(lcd_spec); a++)
{
// 0xff oznacza, że nie ma już dalej wpisów
if(lcd_spec[a] == 0xff)
break;
// Jeśli znaleziono...
else if(lcd_spec[a] == s_index)
return a;
}
// Nic nie znaleziono
return pgm_read_byte(&(langsys_GetSpec()[s_index].cAlt));
}
// Makro pomocnicze
#define LCD_SPECNF(spec) (spec > 7)
// Funkcja przydzielająca znaki specjalne
// Zwraca ilość różnych znaków jaką znaleziono. Jeśli > 8 części znaków nie udało się przydzielić
uint8_t lcd_PrepareSpec(void)
{
// Analizuję cały łańcuch danych i zapisuję kolejno znalezione znaki
char* pbuffer = lcd_buffer;
uint8_t n;
uint8_t cnt=0;
char znak;
// Na początku "zerowanie" tablicy znaków specjalnych
memset(lcd_spec, 0xff, sizeof(lcd_spec));
// dodawanie wpisów
for(n=0; n<ELEMS(lcd_buffer); n++)
{
znak = *pbuffer++;
// Jeśli znaleziony znak jest specjalny
if(lcd_IsSpec(znak))
{
// Przeszukanie tablicy
znak = lcd_Spec2Index(znak);
// Jeśli nie znaleziono - dodawanie
if(LCD_SPECNF(lcd_GetSpec(znak)))
{
// dodaj do tablicy tylko jeśli
// nie wystąpiło przepełnienie
if(cnt < ELEMS(lcd_spec))
lcd_spec[cnt] = znak;
// Licznik zwiększany zawsze
// dla statystyki
++cnt;
}
}
}
return cnt;
}
// Funkcja zapisująca definicje znaków do pamięci CGRAM wyświetlacza
void lcd_UpdateCGRAM(void)
{
// Zabezpieczenie
if(langsys_GetSpec() == NULL)
return;
// Ustawiam adres w module na początek definicji znaków:
lcd_SendInstr(LCDC_CGA);
// Przesyłanie bloków - tylko do czasu aż mam 0xff w tablicy - koniec danych
uint8_t a;
for(a=0; a<ELEMS(lcd_spec); a++)
{
// 0xff oznacza koniec danych
if(lcd_spec[a] == 0xff) break;
// Wskaźnik na początek danych wyglądu znaku
uint8_t* pdata = langsys_GetSpec()[lcd_spec[a]].matrix;
// Wysyłam kolejny indeks
uint8_t bait;
for(bait=0; bait<8; bait++)
{
lcd_SendData(pgm_read_byte(pdata++));
}
}
}
// Funckcja odświerzająca dane w pamięci DDRAM wyświetlacza
// Aby wyświetlanie przebiegło prawidłowo pamięć CGRAM musi być już ustawiona
void lcd_UpdateText(void)
{
uint8_t x, y;
char *pbuffer = lcd_buffer;
// Przetwarzanie każdej linii oddzielnie
for(y=0; y<LCD_SY; y++)
{
lcd_SendInstr(LCDC_DDA | lcd_LineStart(y));
// Wysłanie wszystkich znaków z danej linii
for(x=0; x<LCD_SX; x++)
{
uint8_t znak = *pbuffer++;
if(lcd_IsSpec(znak))
znak = lcd_GetSpec(lcd_Spec2Index(znak));
// Znak gotowy do wysłania
lcd_SendData(znak);
}
}
}
// Odświerzenie wszystkich danych wyświetlacza
void lcd_Update(void)
{
lcd_PrepareSpec();
lcd_UpdateCGRAM();
// Wyłączenie kursora na czas odświerzania
lcd_SendInstr(LCDC_ON | (lcd_status & LCD_STATUS_DISP));
lcd_UpdateText();
lcd_UpdateCurPos();
// Ponowne włączenie kursora (jeśli był włączony)
lcd_UpdateStatus();
}
//__________________________________________________________________________________________
// Funkcja podająca uchwyt do strumienia
inline FILE* lcd_GetFile(void)
{
return lcd_fLCD;
}
/////////////////////////////////////////////////////////////////////////////////////////////
// langsys.c - moduł zarządzający językiem interfejsu
//
// Autor: Radosław Koppel Kompilator: WinAVR 20060125
/////////////////////////////////////////////////////////////////////////////////////////////
#include <inttypes.h>
#include <avr/pgmspace.h>
#include "makra.h"
#include "lcd.h" // Potrzebujemy stąd zmiennej opisującej wygląd znaku specjalnego
#include "langsys.h"
// Tutaj dodać wszystkie nagłówki języków
#include "english.h"
#include "polski.h"
//______________________________________________________________________________________________
// Zmienne
static uint8_t langsys_sel = 0; // wybrany język
// Definicja informacji o znakach specjalnych
const LCD_LOCAL_PGM* langsys_lcdspec[] PROGMEM /*w EdW brak PROGMEM - to błąd!*/=
{
NULL,
PL_lcdspec
};
// Tablica wszystkich posiadanych napisów
// [język][tekst] - na odwrót nie trzebaby pilnować rozmiaru
// (pierwszy wymiar może być obliczany przez kompilator), jednka inicjacja była by mniej wygodna
// +---tablica wskaźników na tablice w pamięci programu
// | +--umieść tą tablicę w pamięci programu
const prog_char* langsys_strTable[2][IDS_END] PROGMEM =
{
{
EN_strDisplay,
EN_strStart
},
{
PL_strDisplay,
PL_strStart
}
};
//______________________________________________________________________________________________
// Funkcje dostępu
// Ilość "zainstalowanych" języków
uint8_t langsys_GetNumOfLangs(void)
{
return ELEMS(langsys_strTable);
}
// Wybór języka
void langsys_Select(uint8_t index)
{
langsys_sel = index;
}
// Pobranie informacji o wybranym języku
uint8_t langsys_GetSelected(void)
{
return langsys_sel;
}
// Pobranie nazwy języka o podanym indeksie
prog_char* langsys_GetLangName(uint8_t index)
{
if(index > ELEMS(langsys_strTable))
return NULL;
return (prog_char*)pgm_read_word_near(&langsys_strTable[index][IDS_LANGNAME]);
}
// Pobieranie wskaźnika na informację o znakach specjalnych
LCD_LOCAL_PGM* langsys_GetSpec(void)
{
return (LCD_LOCAL_PGM*)pgm_read_word_near(&langsys_lcdspec[langsys_sel]);
}
// Pobieranie wybranego napisu
prog_char* langsys_GetText(uint8_t index)
{
return (prog_char*)pgm_read_word_near(&langsys_strTable[langsys_sel][index]);
}
/////////////////////////////////////////////////////////////////////////////////////////////
// langsys.h - plik nagłówkowy modułu zarządzającego danymi języka
// Tutaj znajdują się oznaczenia syboliczne wszystkich łańcuchów
//
// Autor: Radosław Koppel Kompilator: WinAVR 20060125
/////////////////////////////////////////////////////////////////////////////////////////////
#ifndef LANGSYS_H_INCLUDED
#define LANGSYS_H_INCLUDED
//__________________________________________________________________________________________
// Funkcje interfejsu
uint8_t langsys_GetNumOfLangs(void);
void langsys_Select(uint8_t index);
uint8_t langsys_GetSelected(void);
prog_char* langsys_GetLangName(uint8_t index);
LCD_LOCAL_PGM* langsys_GetSpec(void);
prog_char* langsys_GetText(uint8_t index);
//__________________________________________________________________________________________
// Indeksy dla poszczególnych napisów
// Dużymi literami specjalne, reszta tak jak odpowiednie zmienne
enum
{
IDS_LANGNAME,
IDS_Start,
// Nie umieszczać żadnych identyfikatorów za poniższym!
IDS_END
};
#endif //LANGSYS_H_INCLUDED
/////////////////////////////////////////////////////////////////////////////////////////////
// lcd.h - plik nagłówkowy do obsługi alfanumerycznego wyświetlacza LCD.
// ! Dynamiczne przydzielanie znaków specjalnych !
//
// Autor: Radosław Koppel Kompilator: WinAVR 20060125
/////////////////////////////////////////////////////////////////////////////////////////////
#ifndef LCD_H_INCLUDED
#define LCD_H_INCLUDED
#include <avr/pgmspace.h>
#include <stdio.h>
// Struktura definiująca wygląd znaku specjalnego
typedef struct
{
uint8_t matrix[8]; // Matryca znaku
char cAlt; // Znak alternatywny
}LCD_LOCAL_PGM;
// Definicje funkcji interfejsu
void lcd_Init(void);
void lcd_Cls(void);
void lcd_SetStatus(uint8_t status);
#define LCD_STATUS_BLINK 0x01
#define LCD_STATUS_CURSOR 0x02
#define LCD_STATUS_DISP 0x04
void lcd_UpdateStatus(void);
void lcd_GoToAdr(uint8_t adr);
#define lcd_GoTo(x, y) lcd_GoToAdr(y*LCD_SX+x);
void lcd_UpdateCurPos(void);
uint8_t lcd_PrepareSpec(void);
void lcd_UpdateCGRAM(void);
void lcd_UpdateText(void);
void lcd_Update(void);
FILE* lcd_GetFile(void);
#endif // LCD_H_INCLUDED
/////////////////////////////////////////////////////////////////////////////////////////////
// harddef.h - definicja sprzętu dla programu zaawansowanej obsługi alfanumerycznego wyśw. LCD
//
// Autor: Radosław Koppel Kompilator: WinAVR 20060125
/////////////////////////////////////////////////////////////////////////////////////////////
#ifndef HARDDEF_H_INCLUDED
#define HARDDEF_H_INCLUDED
//__________________________________________________
// Definicje wyświetlacza LCD
// Informacje o typie wyświetlacza
#define LCD_SX 16
#define LCD_SY 2
#define LCD_LINE1 0
#define LCD_LINE2 64
// Podłączenie
#define LCD_DATAPORT B
#define LCD_CTRLPORT D
#define LCD_E 4
#define LCD_RW 3
#define LCD_RS 2
#define LCD_LEDPORT D
#define LCD_LED 5
//___________________________________________________
// Definicja przycisków
#define SW_PORT E
#define SW1 0
#define SW2 2
#endif // HARDDEF_H_INCLUDED
//////////////////////////////////////////////////////////////////////////////////////////////////
// makra.h - makra pomocnicze
//
// Autor: Radosław Koppel Kompilator: WinAVR 20050214
//////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef MAKRA_H_INCLUDED
#define MAKRA_H_INCLUDED
// Makra upraszczające dostęp do portów
// *** Port
#define PORT(x) XPORT(x)
#define XPORT(x) (PORT##x)
// *** Pin
#define PIN(x) XPIN(x)
#define XPIN(x) (PIN##x)
// *** DDR
#define DDR(x) XDDR(x)
#define XDDR(x) (DDR##x)
// NOPek
#define NOP() {asm volatile("nop"::);}
// Ilość elementów tablicy
#define ELEMS(p) (sizeof(p)/sizeof(p[0]))
#endif //MAKRA_H_INCLUDED
/////////////////////////////////////////////////////////////////////////////////////////////
// english.h - dane dla języka angielskiego.
//
// Uwaga: Ten plik definiuje zmienne. Wolno go dołączyć tylko raz i robimy do w langsys.c
//
// Autor: Radosław Koppel Kompilator: WinAVR 20060125
/////////////////////////////////////////////////////////////////////////////////////////////
// Język angielski nie potrzebuje definicji znaków specjalnych
// Teksty
prog_char EN_strDisplay[] = "English";
prog_char EN_strStart[] = " Welcome in English Version";
/////////////////////////////////////////////////////////////////////////////////////////////
// polski.h - dane dla języka polskiego.
//
// Uwaga: Ten plik definiuje zmienne. Wolno go dołączyć tylko raz i robimy do w langsys.c
//
// Autor: Radosław Koppel Kompilator: WinAVR 20060125
/////////////////////////////////////////////////////////////////////////////////////////////
// Definicja znaków narodowych
// (Polski ma ich 18)
LCD_LOCAL_PGM PL_lcdspec[18] PROGMEM =
{
// Znaczki - poprawiłem pod względem wyglądu znaczki z EdW 1/98, dodałem brakujące
{{0, 0, 14, 1, 15, 17, 15, 2}, 'a'}, //ą - kod 0x80
{{2, 4, 14, 16, 16, 17, 14, 0}, 'c'}, //ć - kod 0x81
{{0, 0, 14, 17, 31, 16, 14, 2}, 'e'}, //ę - kod 0x82
{{12, 4, 6, 4, 12, 4, 14, 0}, 'l'}, //ł - kod 0x83
{{2, 4, 22, 25, 17, 17, 17, 0}, 'n'}, //ń - kod 0x84
{{2, 4, 14, 17, 17, 17, 14, 0}, 'o'}, //ó - kod 0x85
{{2, 4, 14, 16, 14, 1, 30, 0}, 's'}, //ś - kod 0x86
{{2, 4, 31, 2, 4, 8, 31, 0}, 'z'}, //ź - kod 0x87
{{4, 0, 31, 2, 4, 8, 31, 0}, 'z'}, //ż - kod 0x88
{{14, 17, 17, 31, 17, 17, 17, 2}, 'A'}, //Ą - kod 0x89
{{2, 14, 21, 16, 16, 16, 17, 14}, 'C'}, //Ć - kod 0x8a
{{31, 16, 16, 30, 16, 16, 31, 2}, 'E'}, //Ę - kod 0x8b
{{16, 16, 20, 24, 16, 16, 31, 0}, 'L'}, //Ł - kod 0x8c
{{2, 21, 17, 25, 21, 19, 17, 17}, 'N'}, //Ń - kod 0x8d
{{2, 14, 21, 17, 17, 17, 17, 14}, 'O'}, //Ó - kod 0x8e
{{2, 15, 20, 16, 14, 1, 1, 30}, 'S'}, //Ś - kod 0x8f
{{2, 31, 5, 2, 4, 8, 16, 31}, 'Z'}, //Ź - kod 0x90
{{4, 31, 1, 2, 4, 8, 16, 31}, 'Z'}, //Ż - kod 0x91
};
// Teksty
prog_char PL_strDisplay[] = "Polski";
prog_char PL_strStart[] = " Witaj w wersji Polskiej\x80";
Tutaj kod orginalny:
http://www.sendspace.com/file/slcc8q
Co należy jeszcze poprawić, aby była możliwość kompilacji??