logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Atmega128 jako emulator klawiatury PS/2 – jak wysyłać sygnały klawiszy do PC?

webserver 28 Lis 2006 14:52 8192 36
Najlepsze odpowiedzi LABEL_AI_GENERATED

Jak Atmega128 ma emulować klawiaturę PS/2 i wysyłać do PC wciśnięcia oraz puszczenia klawiszy?

Najprościej trzeba zaimplementować protokół PS/2 i wysyłać do komputera scankody klawiatury, a nie „symulować” samymi poziomami na pinach. Ramka transmisji PS/2 ma bit startu, 8 bitów danych LSB first, bit parzystości i bit stopu; dla przykładu wciśnięcie klawisza A to kod `1C`, a puszczenie to `F0` potem `1C` [#3346480] Linie CLK i DATA powinny być z podciąganiem, a urządzenie musi nadążać za timingiem rzędu ok. 20–30 kHz; w przykładzie użyto opóźnień `Waitus 20` i podłączenia do PD.0/PD.1 [#3346480] Trzeba też obsłużyć komunikację zwrotną od PC, bo komputer może wysyłać np. `0xEE` (echo) i `0xFE` (RESEND), a brak odpowiedzi albo błędna transmisja powoduje piszczenie i błędy [#3350127][#3349870] Jeśli chcesz współdzielić magistralę z prawdziwą klawiaturą, użyj wyjść typu open-collector/tranzystorów i licz się z możliwymi kolizjami, gdy oba urządzenia nadają jednocześnie [#3362644]
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA
  • #1 3272230
    webserver
    Poziom 12  
    Posty: 90
    Ocena: 1
    Witam chce zapiac procka Atmega128 zeby wysylal do kompa polecenia takie same jak by zostal nacisniety przycisk na klawiaturce jak to zrobic >?
  • REKLAMA
  • #2 3281636
    kuba2102
    Poziom 20  
    Posty: 524
    Pomógł: 10
    a tak konkretniej o co chodzi...?? Za duzo tu nie napisales... Kto kolwiek to czytal pewnie teraz glowkuje o co Ci chodzi... Napisz bardziej wyczerpujaca odpowiedz, tak bedzie lepiej, pozdrawiam...

    webserver napisał:
    Witam chce zapiac procka


    co to znaczy zapiac procka??
  • #3 3281650
    Elektrooonik
    Poziom 29  
    Posty: 1212
    Pomógł: 127
    Ocena: 83
    w ksiazce 'Mikrokontrolery AVR ATmega w Praktyce' z BTC jest rozdział poświęcony interfejsowi PS2 i rozwiązania programowe w asemblerze na AVR

    Dodano po 2 [minuty]:

    moze sie przydac http://radzio.dxp.pl/pckeyboard poczytaj w internecie o scankodach i sprobuj wygenerowac je za pomocą mikrokontrolera

    Pzdr
    Paweł
  • #4 3282667
    thug
    Poziom 12  
    Posty: 58
    Ocena: 2
    na pewno przyda Ci sie opis transmisji danych wysylanych z klawiatury

    tutaj masz swietny opis co prawda odwrotnego projektu ;D nie mniej jednak mysle ze bez problemow bedziesz mogl zaadaptowac to do swojego projektu

    http://www.easy-soft.pl/zasoby/kbd8051.pdf

    PS. Nota bene swietna stronka bardzo polecam :D

    EDIT:

    nie zauwazylem linka powyzej :) ale uwazam jednak ze na easy-soft jest lepszy opis - alternatywny :D
  • REKLAMA
  • #5 3283782
    darrrrek
    Poziom 22  
    Posty: 733
    Pomógł: 4
    Ocena: 98
    napsialem przed chwilka program ktory emuluje klawiature jak chcesz to daj znac

    Dodano po 11 [minuty]:

    Clk Alias P2.1
    Dat Alias P2.2
    
    
    Dim I As Byte , Wartosc As Byte , Parz As Byte , Parzystosc As Bit
    
    
    Do
    Wait 1                                                        ' co sekunde wysyla litere "k"
    
    Wartosc = &H42
    Call Wyslij
    Waitms 100
    Wartosc = &HF0
    Call Wyslij
    Wartosc = &H42
    Call Wyslij
    Loop
    
    
    Sub Czekaj
    Parz = 0
    $asm
    MOV R7,#20  'czekaj 40 us
    Et1:
    DJNZ R7,ET1
    $end Asm
    End Sub
    
    Sub Wyslij
    
    For I = 0 To 7
     If Wartosc.i = 1 Then
      Incr Parz
     End If
    Next I
    Parz = Parz Mod 2
    If Parz = 0 Then
     Parzystosc = 1
    Else
     Parzystosc = 0
    End If
    
    Dat = 0
    Call Czekaj
    Clk = 0
    Call Czekaj
    
    For I = 0 To 7
     Clk = 1
     Dat = Wartosc.i
     Call Czekaj
     Clk = 0
     Call Czekaj
    Next I
    
     Clk = 1
     Dat = Parzystosc
     Call Czekaj
     Clk = 0
     Call Czekaj
    
     Clk = 1
     Dat = 1
     Call Czekaj
     Clk = 0
     Call Czekaj
    
     Clk = 1
     Dat = 0
     Waitms 1
     Dat = 1
    End Sub
  • #6 3295494
    Adam_dz
    Poziom 12  
    Posty: 61
    Pomógł: 3
    Ocena: 3
    moge spytać jak dziala ta wstawka assemblerowa?
    chcialem ten kawaleczek programu jakos wykorzystać w ATMega8 ale bascom mi błąd wywala w
    MOV R7,#20 'czekaj 40 us
    i
    DJNZ R7,ET1

    odpowiednio:
    .DEF not found [#20 [adddr]]
    i
    Unknown ASM mnemonic [DJNZ R7,ET1]

    czegos nie zadeklarowalem jeszcze? Da sie to ominąć jakos?
  • #7 3295582
    Elektrooonik
    Poziom 29  
    Posty: 1212
    Pomógł: 127
    Ocena: 83
    bo ten kod asemblerowy jest do '51 a nie do AVR ;) nie ma szans działać w ATMega8, a tak w ogóle jaki to ma związek z tym tematem ? ;)
  • #8 3295701
    Adam_dz
    Poziom 12  
    Posty: 61
    Pomógł: 3
    Ocena: 3
    związek ma spory bo autor tematu chcial zaprogramowac ATMege.. ja zamiast pisać nowy temat i wklejać kod kolegi Darka wolalem zapytać o szczegoly. Jestes w stanie cos podpowiedziec jak zrobic to w Atmedze?
  • #9 3306977
    webserver
    Poziom 12  
    Posty: 90
    Ocena: 1
    Witam kolegow
    dzieki serdecznie za napisanie programiku ale zeczywscie ja potrzebuje na AVR jesli byl bys laskawy objasnic ten kawalek kodu z asemblera lub poprawic go na taki co bedzie dzialal z Avr
  • #10 3307380
    darrrrek
    Poziom 22  
    Posty: 733
    Pomógł: 4
    Ocena: 98
    to jest chyba najprostrzy kod opuzniajacy 40us w asemblerze, zerknij do helpa bascoma i zobacz jakie sa dostepne rozkazy asemblera, trzeba wziasc pod uwage ile cykli maszynowych zabiera kazdy z rozkazow. Teraz jestem w pracy i nie bardzo moge sprawdzic.
  • #11 3311890
    Adam_dz
    Poziom 12  
    Posty: 61
    Pomógł: 3
    Ocena: 3
    W Bascomie AVR jest gotowa instrukcja waitus

    kombinowalem z roznymi dlugosciami czasów ale dalem sobie na razie spokoj.. piszczy mi glosniczek systemowy, jak by sie bufor klawiatury przepelniał czy cos..? nie wiem juz sam...
  • #12 3340753
    MODI
    Poziom 17  
    Posty: 262
    Pomógł: 21
    Ocena: 16
    Cytat:
    kombinowalem z roznymi dlugosciami czasów ale dalem sobie na razie spokoj.. piszczy mi glosniczek systemowy, jak by sie bufor klawiatury przepelniał czy cos..? nie wiem juz sam...


    kombinowałem ostatnio z klawiaturkami. Piszczy dlatego że komputer podczas uruchamiania wysyła komendę echo do klawiatury(EE to chyba było) jeśli klawiatura nie odsyła to jest błąd klawiatury. Jeśli połączysz klawiature normalną a potem po uruchomieniu zmienisz na emulowanąto może wystąpić przepełnienie takie samo jak przy naciśnięciu 4(zależy od klawiatury) klawiszów. Bo:
    -klawiatura oznajmia komputerowi że klawisz został wciśnięty oraz:
    -klawiatura oznajmia komputerowi że klawisz został zwolniony.
    Jeśli tego niezrobi to efekt jest taki jak mówiłem.(ale to jest zaimplementowane w programie)

    P.S. klawiatura nieobsługuje caps locków i num locków a diody są zapalane przez komputer.

    http://www.computer-engineering.org/ps2protocol/

    to było bardzo pomocne.
    Mam gdzieś program w C do emulacji i czytania klawiatury ale ma kilka błędów. Jak znajde czas to postaram się nad nim popracować.
  • #13 3345198
    Adam_dz
    Poziom 12  
    Posty: 61
    Pomógł: 3
    Ocena: 3
    Z tego co sie zorientowalem to wysyła sie: F0, kod klawisza, F0, co ciekawe zaczyna piszczeć po podlaczeniu uC zamiast klawiatury gdy komputer pracuje normlanie.. ale kilka razy zdarzylo sie ze po wypięciu uC z portu w edytorze tekstu wyskoczyło kilka literek (w momencie wypinania z gniazda PS2).. wiec blisko ale jeszcze cos mi kuleje.. jak znajdziesz gdzies jakikolwiek kawałeczek programu (cokolwiek byle nie ASM :) ) ktory poprawnie wysle chociaż jeden kod klawisza to daj znać. Reszte juz potem mozna sobie rozbudować, chodzi przecież tylko o ten najważniejszy fragment wysłania pojedynczego znaku.

    Pozdrawiam,
    Adam.
  • REKLAMA
  • #14 3346480
    Konto nie istnieje
    Konto nie istnieje  
  • #15 3346971
    Adam_dz
    Poziom 12  
    Posty: 61
    Pomógł: 3
    Ocena: 3
    czemu bascom AVR czepia sie tej częsci kodu:

    
    Wyslij($H1C) 
    Wait 3                ' "przytrzymajmy" go 3 sekundy, niech się zrobi trochę 
                              'znaków w np. Notatniku 
    Wyslij($HF0) 
    Wyslij($H1C)
    


    niby "unknows statement" przy kazdym wyslij....

    a zadeklarowana jest..
    acha, kiedy uzywamy $ a kiedy & przy szesnastkowch wartosciach?

    /edit:
    zmienilem deklaracje funkcji na podprogram (sub) i ustawiam zmienną bajt przed wywołaniem podprogramu. Działa jak na razie wiec serdeczne dzieki.. nie zadziałało na początku ale dolutowałem rezystory podciągające i chodzi..
    Tak więc dziękuje serdecznie :) jak by komus sie chciało zerknąć czemu błędy wywala na wywołaniach funkci było by miło.

    Pozdrawiam,
    Adam.
  • #16 3348333
    tomasz_wilko
    Poziom 14  
    Posty: 144
    Pomógł: 14
    Ocena: 4
    Bardzo dobrze i zrozumiale opisane to jest w książce Mikrokontorolery dla początkujących - P.Góreckiego,
    moze tam znajdziesz cos dla siebie,
    pozd.
  • #17 3348807
    Konto nie istnieje
    Konto nie istnieje  
  • #18 3349551
    MODI
    Poziom 17  
    Posty: 262
    Pomógł: 21
    Ocena: 16
    mała sugestia
    żeby poprawnie używać funkcji wait i waitus trzeba poprawnie zdefiniować częstotliwość pracy procesora. $crystal o ile dobrze pamiętam

    tu jest dokładniejsza specyfikacja:
    http://www.networktechinc.com/ps2-prots.html
  • REKLAMA
  • #19 3349659
    Adam_dz
    Poziom 12  
    Posty: 61
    Pomógł: 3
    Ocena: 3
    poprzerabialem poprzedni kod Rocket_93 i działa w ten sposób ze komputer rozpoznaje co do niego wysyłam ale przy okazji piszczy :) .. zaraz sprawdze ostatnią wersje kodu.
  • #20 3349870
    Konto nie istnieje
    Konto nie istnieje  
  • #21 3349959
    Adam_dz
    Poziom 12  
    Posty: 61
    Pomógł: 3
    Ocena: 3
    testowalem z 1 i 4 Mhz, zadeklarowane na początku.. ciekawostka: gdy wysle pojedynczy kod znaku np 1C bez F0,1C zaraz po nim, to nie piszczy, ale gdy chce wyslać wiecej i odczekam nawet jakies 450ms po wyslaniu jednego z nich to roznie bywa, dla jednego kodu znaku zapiszczy, dla innego nie (np
    
    Call Wyslij(&H3a)
    Waitms 450
    Call Wyslij(&H23)
    Waitms 450
    Call Wyslij(&H1c)
    Waitms 450
    

    zapiszczy tylko przy ostatnim..
    zostaje mi tylko zabawa z odczytaniem co komuter mi chce wyslać gdy ja rozpoczne wysylanie..
    dzieki za podpowiedzi i kod programu
    pozdrawiam
    adam.
  • #22 3350042
    Konto nie istnieje
    Konto nie istnieje  
  • #23 3350091
    Adam_dz
    Poziom 12  
    Posty: 61
    Pomógł: 3
    Ocena: 3
    dobra dobra :) ja tez zaczynam ale mi to bardziej topornie idzie..
    zastanawia mnie tylko to, ze przecież tylko wysyłamy a nie chcemy nic odbierać.. a komputer nie przyjmuje mi kodu f0 i kolejnego kodu znaku, zebym potem mogl od razu wyslać kolejną trójkę kodów. Odbiera tylko pierwszy.. gdy odczekam dostatecznie dlugo to chyba sam sobie "dopowie" ten kod puszczenia klawisza i tyle..

    jesli nie sprawi to problemu pogadaj z tym gościem od klawiatury do laptopa.
    jak cos ciekawego znajdziesz to na priv tez podaj, ja bede zaglądał tez do tego wątka..

    /edit:
    jesli jednak jest tak jak mowisz, ze komputer po otrzymaniu pierwszego kodu chce cos jeszcze dopowiedziec to moza by bylo (po wykryciu takiej zachcianki systemu) zasymulować sygnał zegara zeby myslał ze go ktos slucha i potem dalej wysyłać swoje (mam na mysli kod puszczenia klawisza i powtórnie kod znaku)..
  • #24 3350127
    Konto nie istnieje
    Konto nie istnieje  
  • #25 3350218
    Adam_dz
    Poziom 12  
    Posty: 61
    Pomógł: 3
    Ocena: 3
    odezwe sie niedlugo na gadu i opowiem dokładnie co mi dolega..
  • #26 3353697
    MODI
    Poziom 17  
    Posty: 262
    Pomógł: 21
    Ocena: 16
    nie wydaje mi sie żeby po każym wysłaniu znaku komputer wsyłał coś. Wiem że przy uruchamianiu wysyła echo i kiedy jest błąd w transmisji(może tak być gry odd bit sie niezgadza) może tam niema być tego "not". Niejestem pewny do końca bo nie analizowałem kodu.
  • #27 3355943
    MODI
    Poziom 17  
    Posty: 262
    Pomógł: 21
    Ocena: 16
    poprawiłem swój stary kod:




    
    //Piny do pc
    	//Data
    
    	#define KBD_DATA_PORT	 PORTC //pull
    	#define KBD_DATA_P	 	 5	   //pull
    	#define KBD_inDATA_PIN	 PIND
    	#define KBD_inDATA_P	 1
    	//Clk
    	#define KBD_CLK_PORT 	 PORTC //pull
    	#define KBD_CLK_P		 4   //pull
    	#define KBD_inCLK_PORT 	 PIND 
    	#define KBD_inCLK_P		 3
    //pull to pin podłączony do tranzystora ściągającego do 0
    //podobnie jak tu 
    //http://www.computer-engineering.org/ps2protocol/ps2.JPG
    
    SIGNAL (SIG_OVERFLOW0)
    {
    if(wait)
    wait--;
    
    }
    
    
    
    void sendpc(char sbp){
    	
    	while(!((KBD_inCLK_PORT>>KBD_inCLK_P)&1)){//czeka na clk 1
    	recpc();							//odbior
    	}
    	if(!((KBD_inDATA_PIN>>KBD_inDATA_P)&1))//sprawdza czy transmisja
    	recpc();
    	
    	KBD_DATA_PORT&=~(1<<KBD_DATA_P);  	//data 0
    	TCNT0=128;
    	wait=1;
    	while(wait){						//czeka 5-25us, sprawdza czy transmisja
    	if(!((KBD_inCLK_PORT>>KBD_inCLK_P)&1))
    	recpc();							//odbior
    	}
    	/////////////////////////////////////////////////
    	KBD_CLK_PORT&=~(1<<KBD_CLK_P);		//ckl 0
    	wait=2;
    	TCNT0=128;
    	while(wait);						//czeka 30-50us
    	KBD_CLK_PORT|=(1<<KBD_CLK_P);		//clk 1
    	odd=1;
    	for(i=0;i<8;i++){						//przesył \/ \/ \/
    		wait=1;
    		TCNT0=140;
    		while(wait);						//czeka +-20us
    		KBD_DATA_PORT=(KBD_DATA_PORT&(~(1<<KBD_DATA_P)))|(((sbp>>i)&1)<<KBD_DATA_P);
    											//ustawia data i-ty bit LSBF
    		wait=1;
    		TCNT0=140;
    		while(wait){						//czeka +-20us, sprawdza czy transmisja
    		if(!((KBD_inCLK_PORT>>KBD_inCLK_P)&1))
    		recpc();							//odbior
    		}
    		KBD_CLK_PORT&=~(1<<KBD_CLK_P);		//ckl 0
    		wait=2;
    		TCNT0=128;
    		while(wait);						//czeka 30-50us
    		odd^=(sbp>>i)&1;					//suma kontrolna
    		KBD_CLK_PORT|=(1<<KBD_CLK_P);		//clk 1				
    	}										//koniec /\ /\ /\
    	
    	wait=1;
    	TCNT0=140;
    	while(wait);							//czeka +-20us
    	KBD_DATA_PORT=(KBD_DATA_PORT&(~(1<<5)))|((odd&1)<<5);
    											//bit parzystości
    	wait=1;
    	TCNT0=140;
    	while(wait){							//czeka +-20us, sprawdza czy transmisja
    	if(!((KBD_inCLK_PORT>>KBD_inCLK_P)&1))
    	recpc();								//odbior
    	}
    	
    	
    	KBD_CLK_PORT&=~(1<<KBD_CLK_P);			//clk 0	
    	wait=2;
    	TCNT0=128;
    	while(wait);							//czeka 30-50us
    	KBD_CLK_PORT|=(1<<KBD_CLK_P);			//clk 1
    	wait=1;
    	TCNT0=140;
    	while(wait);							//czeka +-20us
    	KBD_DATA_PORT|=(1<<KBD_DATA_PORT);		//data 1
    	wait=1;
    	TCNT0=140;
    	while(wait){							//czeka +-20us, sprawdza czy transmisja
    	if(!((KBD_inCLK_PORT>>KBD_inCLK_P)&1))
    	recpc();								//odbior
    	}
    	KBD_CLK_PORT&=~(1<<KBD_CLK_P);			//clk 0	
    	wait=3;
    	TCNT0=0;
    	while(wait);							//czeka 100us
    	PORTC|=(1<<4);
    	KBD_CLK_PORT|=(1<<KBD_CLK_P);			//clk 1
    	while(wait){							//czeka +-20us, sprawdza czy transmisja
    	if(!((KBD_inCLK_PORT>>KBD_inCLK_P)&1))
    	recpc();								//odbior
    	}
    }
    
    
    
    
    
    
    int main(void)
    {
    DDRA=255;
    DDRB=255;
    DDRC=255;
    //PORTD=PIND=255;//////////////
    PORTC|=(1<<6);
    PORTC|=(1<<7);
    PORTC|=(1<<5);
    PORTC|=(1<<4);
    DDRD|=~(1<<2|1<<4|1<<3|1<<1);
    //PORTB=0;
    MCUCR=2;
    //PORTB=255;
    TCCR0=1;
    TCCR1A=0;
    TCCR1B=0;
    TIFR=0;
    TIMSK=1<<TOIE0;
    sei();
    TCNT0=0;
    
    
    
    wait=1;
    TCNT0=80;
    while(wait);
    GICR|=1<<INT0;
    //GICR|=1<<INT1;
    //init();
    
    
    while(1){
    sendpc(0x42);  //wysyła "k"
    sendpc(0xF0);  
    sendpc(0x42);  
    }
    
    
    
    }
    
    


    kwarc jest 11,0592
    trzeba jeszcze zadeklarować wait
    procesor atmega8515L(overclocked)

    aha funkcja recpc() jest pusta
    musze dopisać obsługe odbioru
  • #28 3362552
    Adam_dz
    Poziom 12  
    Posty: 61
    Pomógł: 3
    Ocena: 3
    Widze ze wreszcie zmusze sie do programowania w C :)
    Pojdzie ten kod na ATmega8 na 8 MHz?
    Jesli nie to co by wypadało zmienic?

    A poza tym dziękuje za zainteresowanie :)
    I jeszcze jedno pytanie: jak połączyć uC by działał rownolegle do klawiatury?
    Keyb ==== PC
    ||
    uC

    klawiatura robi swoje, uC od czasu do czasu tez cos wsyła.. ten tranzystor pomoze? Bo jak połącze bezpośrednio piny uC do linni Clock i Data to juz PC nie odbiera nic z klawiarury.
  • #29 3362644
    MODI
    Poziom 17  
    Posty: 262
    Pomógł: 21
    Ocena: 16
    Adam_dz napisał:

    Pojdzie ten kod na ATmega8 na 8 MHz?
    Jesli nie to co by wypadało zmienic?


    program działa na 8Mhz na moim sprzęcie(sprawdzone) tylko niewiem czy tak samo będzie na innych.
    przez święta spróbuje przepisać kod aby działał tak samo niezależnie od kwarcu.

    w twoim przypadku wystarczy podłączyć te tranzystory pod klawiatórke równolegle i liczyć że oba urządzenia w tym samym czasie niebędą nadawać.
    a jeśli będą to będą błędy w transmisji.
    Pozdrowienia
    Wesołych Świąt
  • #30 3363116
    Adam_dz
    Poziom 12  
    Posty: 61
    Pomógł: 3
    Ocena: 3
    dziękuje,
    rownież życzę spokojnych radosnych i wesołych Świąt Bożego Narodzenia.
    Pozdrawiam.
    Adam

    //EDIT:
    Tam sie tylko zapytam..
    jakim cudem pętla nieskonczona generuje zwłokę?
    bo na pewno kilka ms (us) nie trwa takie cos:
    
     wait=3; 
    TCNT0=0;
     while(wait);
    

    chyba ze nie wiem jak działa while, to mnie douczcie (jesli mozna)..

Podsumowanie tematu

LABEL_AI_GENERATED
Dyskusja dotyczy wykorzystania mikrokontrolera Atmega128 (oraz innych AVR, np. Atmega8) jako emulatora klawiatury PS/2, który wysyła do komputera sygnały odpowiadające naciśnięciom klawiszy. Poruszono kwestie implementacji protokołu PS/2, w tym generowania sygnałów zegara i danych, obsługi kodów skanowania (scan codes) oraz bitów parzystości. Użytkownicy dzielili się przykładami kodów w BASCOMie i C, omawiając problemy z kompatybilnością asemblera 8051 z AVR, konieczność stosowania rezystorów podciągających, oraz znaczenie prawidłowego taktowania (częstotliwości kwarcu) dla poprawnej transmisji. Wskazano, że komputer podczas uruchamiania wysyła komendę echo (0xEE) do klawiatury, a brak odpowiedzi powoduje sygnał błędu (piszczenie). Omówiono także problem symultanicznego podłączenia standardowej klawiatury i mikrokontrolera do linii PS/2, sugerując stosowanie tranzystorów do separacji sygnałów i unikanie kolizji transmisji. Wskazano na potrzebę implementacji odbioru danych z komputera (np. komendy RESEND 0xFE) dla pełnej emulacji. Podano linki do dokumentacji protokołu PS/2 oraz przykładowych implementacji. Dyskusja zawierała także pytania o wysyłanie kombinacji klawiszy (np. CTRL-ALT-DEL) oraz prośby o działające przykłady programów w BASCOMie.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA