Aktyw Forum
Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.
Sprawdź punkty Zarejestruj sięmyszka
Moderatorzy:Jacek Bogusz, Moderatorzy
-
- -
- Posty:8
- Rejestracja:16 lis 2003, o 08:49
- Lokalizacja:Zgierz
- Kontaktowanie:
Zrobiłem ekran diodowy 10x10 diód (nie są połączone ze sobą). Jak zrobić coś takiego, że za pomocą myszki diody będą imitowały kursor myszki, czyli tam gdzie ruszy się myszka to będzie świecić się dioda a po naciśnięciu myszki dioda świeci cały czas. Czy to jest możliwe do wykonania i ile trzeba by było w to włożyć kasy? Za wszystkie odpowiedzi z góry dziękuję.
Wydaje mi się że musiałbyś dzieląc matrycę diod na wiersze i kolumny wysyłać "adres" poszczególnej diody. Ale to byłoby tylko po naciśnięciu klawisza myszy. Musiałbyś na ekranie określiż też taką samą matrycę jak tą z diod z np kratkami do zaznaczania która dioda ma się świecić.
Osobiście robiłbym na '51 (bo tylko tego procka znam )
PC wysyłałby wtedy najpierw adres kolumny potem wiersza (albo odwrotnie) a uP dekodowałby go i zapalał odpowiednią diodę.
Osobiście robiłbym na '51 (bo tylko tego procka znam )
PC wysyłałby wtedy najpierw adres kolumny potem wiersza (albo odwrotnie) a uP dekodowałby go i zapalał odpowiednią diodę.
-
- -
- Posty:8
- Rejestracja:16 lis 2003, o 08:49
- Lokalizacja:Zgierz
- Kontaktowanie:
mayszka
Jak to zrobić nie podłanczając tego do kompa? Napisz mi coś więcej na ten temat.
Transmisja szeregowa, jaka jest używana przez myszki nie jest skomplikowana. Myszka pracuje z prędkościa 1200 bps i transmisją 7-bitową.
Każde przesunięcie myszki powoduje transmisję 3 bajtów. Dwa bajty mówią o względnym przesunięciu myszki (jeden w kierunku X i drugi w kierunku Y) oraz bajt określający stany przycisków.
Każde przesunięcie myszki powoduje transmisję 3 bajtów. Dwa bajty mówią o względnym przesunięciu myszki (jeden w kierunku X i drugi w kierunku Y) oraz bajt określający stany przycisków.
re:myszka
A czy w myszce z PS-2 jest tak samo. A niemoglbys podac na forum przyklad prostego programu (dla RS i PS-2). to jest to bardzo interesujace, z przyznam, ze kiedys chcislem oprogramowac myszke tylko niewiedzialem jak to zrobic. Osobiscie bylbym wdzieczny za takie listingi.
Dzieki,
Sławek
Dzieki,
Sławek
W sumie moja odpowiedź jest troszkę obszerna. Ponieważ nie wiem jak
zrobić to inaczej, więc będzie w odcinkach. Jeżeli ktoś jest zainteresowany
postacią źródłową, niech pisze do mbie na adres an177@poczta.fm.
Na wstępie zmartwię być może niektórych, bo prezentacja dotyczy programu
na PC, ponieważ małe procki nie odbierają transmisji 7-bitowej. Można by
zrobić odbiornik programowy, ale w końcu chodzi o przedstawienie obsługi
myszy, a nie o walkę z odbieraniem nietypowego RS.
W przypadku myszki 2-klawiszowej.
Myszka pracuje w trybie 1200 N71 (prędkość transmisji 1200 bitów, bez parzystości, 7 bitów danych i 1 bit stopu). Przesyłane sa 3 bajty danych.
pierwszy określa stan klawiszy, drugi relatywne przesunięcie w osi X, trzeci relatywne przesunięcie w osi Y. Drugi i trzeci dajt (te od przesunięć) są zapisane w śmiesznym kodzie.
Jest to kod z uzupełnieniem do 2 (U2) ala tak jakby słowo było 6-bitowe.
Kod U2 pozwala na używanie liczb dodatnich i ujemnych (liczby ze znakiem). Jeżeli jest ustawiony najwyższy bit, to oznacza, że liczba jest
ujemna.
zrobić to inaczej, więc będzie w odcinkach. Jeżeli ktoś jest zainteresowany
postacią źródłową, niech pisze do mbie na adres an177@poczta.fm.
Na wstępie zmartwię być może niektórych, bo prezentacja dotyczy programu
na PC, ponieważ małe procki nie odbierają transmisji 7-bitowej. Można by
zrobić odbiornik programowy, ale w końcu chodzi o przedstawienie obsługi
myszy, a nie o walkę z odbieraniem nietypowego RS.
W przypadku myszki 2-klawiszowej.
Myszka pracuje w trybie 1200 N71 (prędkość transmisji 1200 bitów, bez parzystości, 7 bitów danych i 1 bit stopu). Przesyłane sa 3 bajty danych.
pierwszy określa stan klawiszy, drugi relatywne przesunięcie w osi X, trzeci relatywne przesunięcie w osi Y. Drugi i trzeci dajt (te od przesunięć) są zapisane w śmiesznym kodzie.
Jest to kod z uzupełnieniem do 2 (U2) ala tak jakby słowo było 6-bitowe.
Kod U2 pozwala na używanie liczb dodatnich i ujemnych (liczby ze znakiem). Jeżeli jest ustawiony najwyższy bit, to oznacza, że liczba jest
ujemna.
Treść programu:
/*
Zalozmy, ze mysz porusza sie po obszarze o wielkosci 1024 x 1024
punktow (np. pixeli ekranowych). Program wyswietla polozenie
wskazywane przez mysz i stan klawiszy (lewego i prawego).
Program wymaga podlaczenie myszy na port COM1.
Mysz transmituje dane przez kanal szeregowy, ktory nalezy
zaprogramowac nastepujaco:
- transmisja N71 (bez parzystosci, 7 bitow, 1 bit stopu)
- predkosc 1200 bps
Mysz transmituje swoje dane po 3 bajty.
pierwszy bajt okresla stan klawiszy
drugi bajt okresla wzgledne przesuniecie w osi X
trzeci bajt okresla wzgledne przesuniecie w osi Y
Wzgledne przesuniecie jest w kodzie U2 na 6 bitach, czyli
otrzymywane sa wyniki z zakresu -32..31.
Kod U2 (kod uzupelnien do 2) jest kodem pozwalajacym
uzywac liczby dodatnie i ujemne. Najwyzszy bit jest bitem
znaku liczby i jezeli jest ustawiony, to liczba jest ujemna,
jezeli nie jest ustawiony, to liczba jest dodatnia.
Dla liczba dodatnich jest zgodny z kodem naturalnym (tylko
liczby dodatnie). Dla liczb ujemnych jest 'tak troche odwrocony'.
W przypadku myszy (6 bitow U2) mamy:
111111 jest liczba -1
100000 jest liczba -32
000001 jest liczba 1
011111 jest liczba 31
Zamiana liczby dodatniej na ujemna polega na odwroceniu
kazdego bitu liczby na przeciwny i dodaniu do wyniku 1.
Przyklad:
liczba 14 to : 001110
liczba -14 to : 110001 (negacja 14)
+ 1
-------
110010
W przypadku myszy 3-klawiszowych obsluga jest inna
(po pierwsze transmitowane sa 4 bajty), wiec jezeli
jest podlaczona mysz 3-klawiszowa nie nalezy uzywac
srodkowego klawisza ani kolka ok scrollbara. Ten
program pokazuje obsluge myszy w maksymalnie
uproszczony sposob.
*/
/*
Zalozmy, ze mysz porusza sie po obszarze o wielkosci 1024 x 1024
punktow (np. pixeli ekranowych). Program wyswietla polozenie
wskazywane przez mysz i stan klawiszy (lewego i prawego).
Program wymaga podlaczenie myszy na port COM1.
Mysz transmituje dane przez kanal szeregowy, ktory nalezy
zaprogramowac nastepujaco:
- transmisja N71 (bez parzystosci, 7 bitow, 1 bit stopu)
- predkosc 1200 bps
Mysz transmituje swoje dane po 3 bajty.
pierwszy bajt okresla stan klawiszy
drugi bajt okresla wzgledne przesuniecie w osi X
trzeci bajt okresla wzgledne przesuniecie w osi Y
Wzgledne przesuniecie jest w kodzie U2 na 6 bitach, czyli
otrzymywane sa wyniki z zakresu -32..31.
Kod U2 (kod uzupelnien do 2) jest kodem pozwalajacym
uzywac liczby dodatnie i ujemne. Najwyzszy bit jest bitem
znaku liczby i jezeli jest ustawiony, to liczba jest ujemna,
jezeli nie jest ustawiony, to liczba jest dodatnia.
Dla liczba dodatnich jest zgodny z kodem naturalnym (tylko
liczby dodatnie). Dla liczb ujemnych jest 'tak troche odwrocony'.
W przypadku myszy (6 bitow U2) mamy:
111111 jest liczba -1
100000 jest liczba -32
000001 jest liczba 1
011111 jest liczba 31
Zamiana liczby dodatniej na ujemna polega na odwroceniu
kazdego bitu liczby na przeciwny i dodaniu do wyniku 1.
Przyklad:
liczba 14 to : 001110
liczba -14 to : 110001 (negacja 14)
+ 1
-------
110010
W przypadku myszy 3-klawiszowych obsluga jest inna
(po pierwsze transmitowane sa 4 bajty), wiec jezeli
jest podlaczona mysz 3-klawiszowa nie nalezy uzywac
srodkowego klawisza ani kolka ok scrollbara. Ten
program pokazuje obsluge myszy w maksymalnie
uproszczony sposob.
*/
#include <STDIO.H>
#include <CONIO.H>
#define TRUE 1
#define FALSE 0
#define MaxX 1024
#define MaxY 1024
#define IRSBuffSize 32
typedef struct {
unsigned short Start ;
unsigned short Stop ;
unsigned char RSBuffer [ IRSBuffSize ] ;
} IRSBufferRecT ;
/* struktura bufora cyklicznego na odbierane
z RS znaki */
typedef void ( __interrupt __far * IRQVectorProcT ) ( ) ;
typedef struct {
IRSBufferRecT InpBuffer ; /* bufor cykliczny odbiornika UART */
IRQVectorProcT OldIRQVector ; /* przechowanie istniejacego wektora przerwan UART */
unsigned short UARTAddress ; /* adres maszynowy UART (COM1 lub COM2) */
unsigned char OldIRQMask ; /* przechowanie istniejacej maski przerwan w
ukladzie 8259 - kontroler przerwan procesora */
unsigned char Valid ; /* flaga sygnalizujaca aktualizacje polozenia myszy
i jej klawiszy */
unsigned char Char1 ; /* pierwszy znak */
unsigned char Char2 ; /* drugi znak */
unsigned char Char3 ; /* trzeci znak */
unsigned char State ; /* stan automatu odbioru co 3 bajty
(okresla ile znakow juz odebrano) */
signed short XPosition ; /* aktualna pozycja X myszy */
signed short YPosition ; /* aktualna pozycja Y myszy */
unsigned short LeftButton ; /* stan lewego klawisza */
unsigned short RightButton ; /* stan prawego klawisza */
} SerialParamRecT ;
void Out ( unsigned short , unsigned char ) ;
#pragma aux Out=\
"OUT DX,AL"\
parm[DX][AL];
unsigned char In ( unsigned short ) ;
#pragma aux In=\
"IN AL,DX"\
parm[DX] value [AL];
void DisableInt ( ) ;
#pragma aux DisableInt=\
"CLI";
void EnableInt ( ) ;
#pragma aux EnableInt=\
"STI";
#define DataRegister 0
/* adresy wzgledne poszczegolnych rejestrow UART 16450 (16550)
patrz: dowolna dokumentacja od UART 16450,
np. uklad TL16C450 firmy texas instruments (www.ti.com) */
#define InterruptEnRegister 1
#define InterruptIdRegister 2
#define LineControlRegister 3
#define ModemControlRegister 4
#define LineStatusRegister 5
#define ModemStatusRegister 6
#define ScratchRegister 7
#define COM1IRQVector 12
/* numer wektora przerwan od COM1 w tablicy przerwan */
#define COM2IRQVector 11
/* numer wektora przerwan od COM2 w tablicy przerwan */
#define I8259 0x20
/* adres maszynowy kontrolera przerwan,
kontrolerem przerwan jest uklad INTEL 8259 (www.intel.com) */
#define COM1 0x3F8
/* adres maszynowy COM1 */
#define COM2 0x2F8
/* adres maszynowy COM2 */
SerialParamRecT SerialParamRec ;
/* zmienne programu */
#include <CONIO.H>
#define TRUE 1
#define FALSE 0
#define MaxX 1024
#define MaxY 1024
#define IRSBuffSize 32
typedef struct {
unsigned short Start ;
unsigned short Stop ;
unsigned char RSBuffer [ IRSBuffSize ] ;
} IRSBufferRecT ;
/* struktura bufora cyklicznego na odbierane
z RS znaki */
typedef void ( __interrupt __far * IRQVectorProcT ) ( ) ;
typedef struct {
IRSBufferRecT InpBuffer ; /* bufor cykliczny odbiornika UART */
IRQVectorProcT OldIRQVector ; /* przechowanie istniejacego wektora przerwan UART */
unsigned short UARTAddress ; /* adres maszynowy UART (COM1 lub COM2) */
unsigned char OldIRQMask ; /* przechowanie istniejacej maski przerwan w
ukladzie 8259 - kontroler przerwan procesora */
unsigned char Valid ; /* flaga sygnalizujaca aktualizacje polozenia myszy
i jej klawiszy */
unsigned char Char1 ; /* pierwszy znak */
unsigned char Char2 ; /* drugi znak */
unsigned char Char3 ; /* trzeci znak */
unsigned char State ; /* stan automatu odbioru co 3 bajty
(okresla ile znakow juz odebrano) */
signed short XPosition ; /* aktualna pozycja X myszy */
signed short YPosition ; /* aktualna pozycja Y myszy */
unsigned short LeftButton ; /* stan lewego klawisza */
unsigned short RightButton ; /* stan prawego klawisza */
} SerialParamRecT ;
void Out ( unsigned short , unsigned char ) ;
#pragma aux Out=\
"OUT DX,AL"\
parm[DX][AL];
unsigned char In ( unsigned short ) ;
#pragma aux In=\
"IN AL,DX"\
parm[DX] value [AL];
void DisableInt ( ) ;
#pragma aux DisableInt=\
"CLI";
void EnableInt ( ) ;
#pragma aux EnableInt=\
"STI";
#define DataRegister 0
/* adresy wzgledne poszczegolnych rejestrow UART 16450 (16550)
patrz: dowolna dokumentacja od UART 16450,
np. uklad TL16C450 firmy texas instruments (www.ti.com) */
#define InterruptEnRegister 1
#define InterruptIdRegister 2
#define LineControlRegister 3
#define ModemControlRegister 4
#define LineStatusRegister 5
#define ModemStatusRegister 6
#define ScratchRegister 7
#define COM1IRQVector 12
/* numer wektora przerwan od COM1 w tablicy przerwan */
#define COM2IRQVector 11
/* numer wektora przerwan od COM2 w tablicy przerwan */
#define I8259 0x20
/* adres maszynowy kontrolera przerwan,
kontrolerem przerwan jest uklad INTEL 8259 (www.intel.com) */
#define COM1 0x3F8
/* adres maszynowy COM1 */
#define COM2 0x2F8
/* adres maszynowy COM2 */
SerialParamRecT SerialParamRec ;
/* zmienne programu */
static void ProgramRSChannel ( )
/* procedura programowania UART do
pracy w trybie 1200 N71
patrz: dokumentacja UART 16450 */
{
unsigned char Data ;
unsigned char SpeedH ;
unsigned char SpeedL ;
unsigned char UARTMode ;
unsigned short Speed ;
/* ---------------------------------- */
UARTMode = 0x02 ; /* tryb pracy UART: tu konkretnie N71 */
Speed = 96 ; /* podzielnik czestotliwosci do uzyskania
predkosci 1200 */
SpeedH = ( unsigned char ) ( Speed / 256 ) ;
SpeedL = ( unsigned char ) ( Speed % 256 ) ;
/* tak na prawde potrzebny jest bajt starszy i mlodszy */
Out ( SerialParamRec . UARTAddress + LineControlRegister , ( unsigned char ) 0x080 ) ;
/* ustawienie w UART rozszerzenia adresowego
do zaprogramowania predkosci */
Out ( SerialParamRec . UARTAddress + DataRegister , SpeedL ) ;
/* mlodszy bajt podzielnika predkosci */
Out ( SerialParamRec . UARTAddress + InterruptEnRegister , SpeedH ) ;
/* starszy bajt podzielnika predkosci */
Out ( SerialParamRec . UARTAddress + LineControlRegister , UARTMode ) ;
/* zaprogramowania trybu transmisji (N71) */
Out ( SerialParamRec . UARTAddress + ModemControlRegister , ( unsigned char ) 0x00B ) ;
/* zaprogramowania stanu linii modemowych,
tu ustawienie wyjsciowych na taki stan
aby myszka miala z czego sie zasilic */
Data = In ( SerialParamRec . UARTAddress + LineStatusRegister ) ;
/* wygarniecie smieci z roznych rejestrow */
Data = In ( SerialParamRec . UARTAddress + ModemStatusRegister ) ;
/* wygarniecie smieci z roznych rejestrow */
Data = In ( SerialParamRec . UARTAddress + DataRegister ) ;
/* wygarniecie smieci z roznych rejestrow */
Data = In ( SerialParamRec . UARTAddress + DataRegister ) ;
/* wygarniecie smieci z roznych rejestrow */
Data = In ( SerialParamRec . UARTAddress + DataRegister ) ;
/* wygarniecie smieci z roznych rejestrow */
Data = In ( SerialParamRec . UARTAddress + DataRegister ) ;
/* wygarniecie smieci z roznych rejestrow */
Data = In ( SerialParamRec . UARTAddress + InterruptIdRegister ) ;
/* wygarniecie smieci z roznych rejestrow */
Out ( SerialParamRec . UARTAddress + InterruptEnRegister , ( unsigned char ) 0x003 ) ;
/* zezwolenie dla UART na przerwania od transmisji */
} /* ProgramRSChannel */
void _cdecl InitSerial ( )
{
/* zainicjowanie zmiennych programu */
/* ---------------------------------- */
SerialParamRec . InpBuffer . Start = 0 ;
SerialParamRec . InpBuffer . Stop = 0 ;
SerialParamRec . UARTAddress = 0 ;
SerialParamRec . State = 0 ;
SerialParamRec . XPosition = 0 ;
SerialParamRec . YPosition = 0 ;
} /* InitSerial */
static void __interrupt __far SerialService ( )
{
/* procedura obslugi przerwan od UART */
unsigned short SerialStatus ;
unsigned short IntIdentReg ;
unsigned char Data ;
/* ---------------------------------- */
for ( ; ; )
{
IntIdentReg = ( ( unsigned short ) In ( SerialParamRec . UARTAddress + InterruptIdRegister ) ) % 8 ;
/* wczytanie rejestru do identyfikacji przerwania
najmlodszy bit=0 oznacza, ze jest przerwanie
nastepne dwa okreslaja rodzaj przerwania */
switch ( IntIdentReg )
{
case 0 : /* 0 0 0 - Modem status */
SerialStatus = ( unsigned short ) In ( SerialParamRec . UARTAddress + ModemStatusRegister ) ;
/* przerwanie od modemu - odczytac rejestr i zignorowac */
break ;
case 1 : /* 0 0 1 - brak przerwania */
goto EndLoop ;
case 2 : /* 0 1 0 - transmitter */
/* przerwanie od nadajnika - zignorowac, do myszki nie transmitujemy */
break ;
case 3 : /* 0 1 1 - brak przerwania */
goto EndLoop ;
case 4 : /* 1 0 0 - reciever data */
/* przerwanie od odbiornika - obsluga */
Data = In ( SerialParamRec . UARTAddress + DataRegister ) ;
/* odczytac odebrany znak */
SerialParamRec . InpBuffer . RSBuffer [ SerialParamRec . InpBuffer . Stop ] = Data ;
/* umiescic go w buforze cyklicznym */
SerialParamRec . InpBuffer . Stop = ( SerialParamRec . InpBuffer . Stop + 1 ) % IRSBuffSize ;
/* zwiekszyc pozycje w buforze cyklicznym */
break ;
case 5 : /* 1 0 1 - brak przerwania */
goto EndLoop ;
case 6 : /* 1 1 0 - reciever status */
/* przerwanie od bledow transmisji - odczytac rejestr i zignorowac */
SerialStatus = ( unsigned short ) In ( SerialParamRec . UARTAddress + LineStatusRegister ) ;
break ;
case 7 : /* 1 1 1 - brak przerwania */
goto EndLoop ;
default :
goto EndLoop ;
} /* switch */ ;
} /* loop */ ;
EndLoop :
Out ( I8259 , ( unsigned char ) 0x20 ) ;
/* potwierdzenie dla kontrolera 8259 zakonczenia
obslugi przerwania */
} /* SerialService */
void _cdecl OpenCOM1 ( )
{
/* zainicjowanie myszki na COM1 */
IRQVectorProcT far * IRQArray ;
unsigned char NewMask ;
/* ---------------------------------- */
InitSerial ( ) ; /* inicjacja poczatkowa zmiennych */
SerialParamRec . UARTAddress = COM1 ;
/* okreslenie adresu dla UART */
DisableInt ( ) ; /* blokada przerwan : nie mozna programowac
UARTA i kontrolera przerwan przy zezwoleniu
na przerwania */
ProgramRSChannel ( ) ; /* zaprogramowanie UART na prace z myszka */
SerialParamRec . OldIRQMask = ( unsigned char ) In ( I8259 + 1 ) ;
/* przechowanie maski przerwan */
IRQArray = ( void far * ) 0L ;
SerialParamRec . OldIRQVector = * ( IRQArray + COM1IRQVector ) ;
/* przechowanie wskazania na dotychczasowa
obsluge przerwan od UART */
* ( IRQArray + COM1IRQVector ) = SerialService ;
/* wstawienie wlasnej procedury do obslugi przerwan */
NewMask = SerialParamRec . OldIRQMask & ( unsigned char ) 0xEF ;
Out ( I8259 + 1 , NewMask ) ;
/* ustawienie maski tak by moglo przerywac od COM1 */
EnableInt ( ) ; /* zezwolenia na przerwania */
} /* OpenCOM1 */
void _cdecl OpenCOM2 ( )
{
/* zainicjowanie myszki na COM2 - analogicznie jak w COM1 */
IRQVectorProcT far * IRQArray ;
unsigned char NewMask ;
/* ---------------------------------- */
InitSerial ( ) ;
SerialParamRec . UARTAddress = COM2 ;
DisableInt ( ) ;
ProgramRSChannel ( ) ;
SerialParamRec . OldIRQMask = ( unsigned char ) In ( I8259 + 1 ) ;
NewMask = SerialParamRec . OldIRQMask & ( unsigned char ) 0xF7 ;
Out ( I8259 + 1 , NewMask ) ;
IRQArray = ( void far * ) 0L ;
SerialParamRec . OldIRQVector = * ( IRQArray + COM2IRQVector ) ;
* ( IRQArray + COM2IRQVector ) = SerialService ;
EnableInt ( ) ;
} /* OpenCOM2 */
void _cdecl CloseCOM ( )
{
/* zamkniecie myszki na COM1 */
IRQVectorProcT far * IRQArray ;
/* ---------------------------------- */
DisableInt ( ) ; /* blokada przerwan */
IRQArray = ( void far * ) 0L ;
if ( SerialParamRec . UARTAddress == COM1 )
/* jezeli byl to COM1, to: */
* ( IRQArray + COM1IRQVector ) = SerialParamRec . OldIRQVector ;
/* odkrecenie wektora przerwan na COM1 */
else
/* odkrecenie wektora przerwan na COM2 */
* ( IRQArray + COM2IRQVector ) = SerialParamRec . OldIRQVector ;
/* odkrecenie maski przerwan w kontrolerze 8259 */
Out ( I8259 + 1 , ( unsigned char ) SerialParamRec . OldIRQMask ) ;
EnableInt ( ) ; /* zezwolenie na przerwania */
} /* CloseCOM */
unsigned short _cdecl SerialChPresent ( )
{
/* funkcja zwraca informacje, czy jest w buforze cyklicznym
cos do odczytania */
DisableInt ( ) ;
if ( SerialParamRec . InpBuffer . Stop != SerialParamRec . InpBuffer . Start )
{
EnableInt ( ) ;
return ( 1 ) ;
} /* if ... */
else
{
EnableInt ( ) ;
return ( 0 ) ;
} /* if ... else */ ;
} /* SerialChPresent */
unsigned char _cdecl GetRSChar ( )
{
/* funkcja pobrania znakow z bufora cyklicznego */
unsigned char RetChar ;
/* ---------------------------------- */
DisableInt ( ) ;
if ( SerialParamRec . InpBuffer . Stop != SerialParamRec . InpBuffer . Start )
{
RetChar = SerialParamRec . InpBuffer . RSBuffer [ SerialParamRec . InpBuffer . Start ] ;
SerialParamRec . InpBuffer . Start ++ ;
SerialParamRec . InpBuffer . Start = SerialParamRec . InpBuffer . Start % IRSBuffSize ;
} /* if ... */
else
RetChar = 0 ;
EnableInt ( ) ;
return ( RetChar ) ;
} /* GetRSChar */
signed short ConvertChar ( unsigned char Ch )
{
/* zamiana 6-bitowego kodu U2 na
16-bitowy kod U2 (signed short/integer) */
unsigned short CnvV ;
/*--------------------------------*/
if ( Ch < 0x1F )
/* jezeli liczba jest mniejsza od 31, to
wynik jest zgodny z kodem naturalnym binarnym */
return ( ( signed short ) Ch ) ;
/* w przeciwnym wypadku */
CnvV = 0xFFC0 | ( unsigned short ) Ch ;
/* ustawic wszystkie bity na 1 z wyjatkiem
ostatnich 6 - otrzymamy ta sama liczbe
w 16-bitowym U2 */
return ( ( signed short ) CnvV ) ;
} /* ConvertChar */
void AktualizujPozycjeMyszy ( )
{
if ( SerialChPresent ( ) )
{ /* jezeli jest cos do odebrania,
to odbierz kolejny znak jako 1,2 lub 3
znak do interpretacji */
switch ( SerialParamRec . State )
{
case 0 :
SerialParamRec . Char1 = GetRSChar ( ) ;
break ;
case 1 :
SerialParamRec . Char2 = GetRSChar ( ) ;
break ;
case 2 :
SerialParamRec . Char3 = GetRSChar ( ) ;
break ;
default :
;
} /* switch */ ;
SerialParamRec . State ++ ; /* zwieksz liczbe odebranych znakow */
if ( SerialParamRec . State == 3 )
{ /* jezeli odebrano 3 bajty to */
SerialParamRec . XPosition += ConvertChar ( SerialParamRec . Char2 ) ;
/* dosumowac przyrost X */
SerialParamRec . YPosition += ConvertChar ( SerialParamRec . Char3 ) ;
/* dosumowac przyrost Y */
if ( SerialParamRec . XPosition < 0 )
SerialParamRec . XPosition = 0 ;
if ( SerialParamRec . YPosition < 0 )
SerialParamRec . YPosition = 0 ;
if ( SerialParamRec . XPosition > MaxX )
SerialParamRec . XPosition = MaxX ;
if ( SerialParamRec . YPosition > MaxY )
SerialParamRec . YPosition = MaxY ;
/* ograniczyc pozycje do polozenia
w zadanym obszarze */
SerialParamRec . LeftButton = FALSE ;
SerialParamRec . RightButton = FALSE ;
if ( SerialParamRec . Char1 & 0x20 )
SerialParamRec . LeftButton = TRUE ;
if ( SerialParamRec . Char1 & 0x10 )
SerialParamRec . RightButton = TRUE ;
/* okreslic nacisniecie klawiszy */
SerialParamRec . State = 0 ;
SerialParamRec . Valid = TRUE ; /* ustawic wskaznik waznosci danych */
} /* if */ ;
} /* if */ ;
} /* AktualizujPozycjeMyszy */
void PokazPozycjeMyszy ( )
{
/* wyswietlic informacje o polozeniu i stanie myszy */
unsigned char LChar ;
unsigned char RChar ;
/*--------------------------------*/
LChar = ' ' ;
RChar = ' ' ;
if ( SerialParamRec . LeftButton )
LChar = '+' ;
if ( SerialParamRec . RightButton )
RChar = '+' ;
printf ( "X= %4d Y=%4d lewy kl.=%c prawy kl.=%c\n" , SerialParamRec . XPosition ,
SerialParamRec . YPosition , LChar , RChar ) ;
} /* PokazPozycjeMyszy */
main ( )
{
/*--------------------------------*/
OpenCOM1 ( ) ;
// OpenCOM2 ( ) ;
printf ( "Program jest dla DOS\n" ) ;
printf ( "Wcisnij ESC aby skonczyc program.\n" ) ;
for ( ; ; )
{
AktualizujPozycjeMyszy ( ) ;
if ( SerialParamRec . Valid )
{
PokazPozycjeMyszy ( ) ;
SerialParamRec . Valid = FALSE ;
} /* if */ ;
if ( kbhit ( ) )
if ( getch ( ) == 27 )
break ;
} /* for */ ;
CloseCOM ( ) ;
} /* main */
/* procedura programowania UART do
pracy w trybie 1200 N71
patrz: dokumentacja UART 16450 */
{
unsigned char Data ;
unsigned char SpeedH ;
unsigned char SpeedL ;
unsigned char UARTMode ;
unsigned short Speed ;
/* ---------------------------------- */
UARTMode = 0x02 ; /* tryb pracy UART: tu konkretnie N71 */
Speed = 96 ; /* podzielnik czestotliwosci do uzyskania
predkosci 1200 */
SpeedH = ( unsigned char ) ( Speed / 256 ) ;
SpeedL = ( unsigned char ) ( Speed % 256 ) ;
/* tak na prawde potrzebny jest bajt starszy i mlodszy */
Out ( SerialParamRec . UARTAddress + LineControlRegister , ( unsigned char ) 0x080 ) ;
/* ustawienie w UART rozszerzenia adresowego
do zaprogramowania predkosci */
Out ( SerialParamRec . UARTAddress + DataRegister , SpeedL ) ;
/* mlodszy bajt podzielnika predkosci */
Out ( SerialParamRec . UARTAddress + InterruptEnRegister , SpeedH ) ;
/* starszy bajt podzielnika predkosci */
Out ( SerialParamRec . UARTAddress + LineControlRegister , UARTMode ) ;
/* zaprogramowania trybu transmisji (N71) */
Out ( SerialParamRec . UARTAddress + ModemControlRegister , ( unsigned char ) 0x00B ) ;
/* zaprogramowania stanu linii modemowych,
tu ustawienie wyjsciowych na taki stan
aby myszka miala z czego sie zasilic */
Data = In ( SerialParamRec . UARTAddress + LineStatusRegister ) ;
/* wygarniecie smieci z roznych rejestrow */
Data = In ( SerialParamRec . UARTAddress + ModemStatusRegister ) ;
/* wygarniecie smieci z roznych rejestrow */
Data = In ( SerialParamRec . UARTAddress + DataRegister ) ;
/* wygarniecie smieci z roznych rejestrow */
Data = In ( SerialParamRec . UARTAddress + DataRegister ) ;
/* wygarniecie smieci z roznych rejestrow */
Data = In ( SerialParamRec . UARTAddress + DataRegister ) ;
/* wygarniecie smieci z roznych rejestrow */
Data = In ( SerialParamRec . UARTAddress + DataRegister ) ;
/* wygarniecie smieci z roznych rejestrow */
Data = In ( SerialParamRec . UARTAddress + InterruptIdRegister ) ;
/* wygarniecie smieci z roznych rejestrow */
Out ( SerialParamRec . UARTAddress + InterruptEnRegister , ( unsigned char ) 0x003 ) ;
/* zezwolenie dla UART na przerwania od transmisji */
} /* ProgramRSChannel */
void _cdecl InitSerial ( )
{
/* zainicjowanie zmiennych programu */
/* ---------------------------------- */
SerialParamRec . InpBuffer . Start = 0 ;
SerialParamRec . InpBuffer . Stop = 0 ;
SerialParamRec . UARTAddress = 0 ;
SerialParamRec . State = 0 ;
SerialParamRec . XPosition = 0 ;
SerialParamRec . YPosition = 0 ;
} /* InitSerial */
static void __interrupt __far SerialService ( )
{
/* procedura obslugi przerwan od UART */
unsigned short SerialStatus ;
unsigned short IntIdentReg ;
unsigned char Data ;
/* ---------------------------------- */
for ( ; ; )
{
IntIdentReg = ( ( unsigned short ) In ( SerialParamRec . UARTAddress + InterruptIdRegister ) ) % 8 ;
/* wczytanie rejestru do identyfikacji przerwania
najmlodszy bit=0 oznacza, ze jest przerwanie
nastepne dwa okreslaja rodzaj przerwania */
switch ( IntIdentReg )
{
case 0 : /* 0 0 0 - Modem status */
SerialStatus = ( unsigned short ) In ( SerialParamRec . UARTAddress + ModemStatusRegister ) ;
/* przerwanie od modemu - odczytac rejestr i zignorowac */
break ;
case 1 : /* 0 0 1 - brak przerwania */
goto EndLoop ;
case 2 : /* 0 1 0 - transmitter */
/* przerwanie od nadajnika - zignorowac, do myszki nie transmitujemy */
break ;
case 3 : /* 0 1 1 - brak przerwania */
goto EndLoop ;
case 4 : /* 1 0 0 - reciever data */
/* przerwanie od odbiornika - obsluga */
Data = In ( SerialParamRec . UARTAddress + DataRegister ) ;
/* odczytac odebrany znak */
SerialParamRec . InpBuffer . RSBuffer [ SerialParamRec . InpBuffer . Stop ] = Data ;
/* umiescic go w buforze cyklicznym */
SerialParamRec . InpBuffer . Stop = ( SerialParamRec . InpBuffer . Stop + 1 ) % IRSBuffSize ;
/* zwiekszyc pozycje w buforze cyklicznym */
break ;
case 5 : /* 1 0 1 - brak przerwania */
goto EndLoop ;
case 6 : /* 1 1 0 - reciever status */
/* przerwanie od bledow transmisji - odczytac rejestr i zignorowac */
SerialStatus = ( unsigned short ) In ( SerialParamRec . UARTAddress + LineStatusRegister ) ;
break ;
case 7 : /* 1 1 1 - brak przerwania */
goto EndLoop ;
default :
goto EndLoop ;
} /* switch */ ;
} /* loop */ ;
EndLoop :
Out ( I8259 , ( unsigned char ) 0x20 ) ;
/* potwierdzenie dla kontrolera 8259 zakonczenia
obslugi przerwania */
} /* SerialService */
void _cdecl OpenCOM1 ( )
{
/* zainicjowanie myszki na COM1 */
IRQVectorProcT far * IRQArray ;
unsigned char NewMask ;
/* ---------------------------------- */
InitSerial ( ) ; /* inicjacja poczatkowa zmiennych */
SerialParamRec . UARTAddress = COM1 ;
/* okreslenie adresu dla UART */
DisableInt ( ) ; /* blokada przerwan : nie mozna programowac
UARTA i kontrolera przerwan przy zezwoleniu
na przerwania */
ProgramRSChannel ( ) ; /* zaprogramowanie UART na prace z myszka */
SerialParamRec . OldIRQMask = ( unsigned char ) In ( I8259 + 1 ) ;
/* przechowanie maski przerwan */
IRQArray = ( void far * ) 0L ;
SerialParamRec . OldIRQVector = * ( IRQArray + COM1IRQVector ) ;
/* przechowanie wskazania na dotychczasowa
obsluge przerwan od UART */
* ( IRQArray + COM1IRQVector ) = SerialService ;
/* wstawienie wlasnej procedury do obslugi przerwan */
NewMask = SerialParamRec . OldIRQMask & ( unsigned char ) 0xEF ;
Out ( I8259 + 1 , NewMask ) ;
/* ustawienie maski tak by moglo przerywac od COM1 */
EnableInt ( ) ; /* zezwolenia na przerwania */
} /* OpenCOM1 */
void _cdecl OpenCOM2 ( )
{
/* zainicjowanie myszki na COM2 - analogicznie jak w COM1 */
IRQVectorProcT far * IRQArray ;
unsigned char NewMask ;
/* ---------------------------------- */
InitSerial ( ) ;
SerialParamRec . UARTAddress = COM2 ;
DisableInt ( ) ;
ProgramRSChannel ( ) ;
SerialParamRec . OldIRQMask = ( unsigned char ) In ( I8259 + 1 ) ;
NewMask = SerialParamRec . OldIRQMask & ( unsigned char ) 0xF7 ;
Out ( I8259 + 1 , NewMask ) ;
IRQArray = ( void far * ) 0L ;
SerialParamRec . OldIRQVector = * ( IRQArray + COM2IRQVector ) ;
* ( IRQArray + COM2IRQVector ) = SerialService ;
EnableInt ( ) ;
} /* OpenCOM2 */
void _cdecl CloseCOM ( )
{
/* zamkniecie myszki na COM1 */
IRQVectorProcT far * IRQArray ;
/* ---------------------------------- */
DisableInt ( ) ; /* blokada przerwan */
IRQArray = ( void far * ) 0L ;
if ( SerialParamRec . UARTAddress == COM1 )
/* jezeli byl to COM1, to: */
* ( IRQArray + COM1IRQVector ) = SerialParamRec . OldIRQVector ;
/* odkrecenie wektora przerwan na COM1 */
else
/* odkrecenie wektora przerwan na COM2 */
* ( IRQArray + COM2IRQVector ) = SerialParamRec . OldIRQVector ;
/* odkrecenie maski przerwan w kontrolerze 8259 */
Out ( I8259 + 1 , ( unsigned char ) SerialParamRec . OldIRQMask ) ;
EnableInt ( ) ; /* zezwolenie na przerwania */
} /* CloseCOM */
unsigned short _cdecl SerialChPresent ( )
{
/* funkcja zwraca informacje, czy jest w buforze cyklicznym
cos do odczytania */
DisableInt ( ) ;
if ( SerialParamRec . InpBuffer . Stop != SerialParamRec . InpBuffer . Start )
{
EnableInt ( ) ;
return ( 1 ) ;
} /* if ... */
else
{
EnableInt ( ) ;
return ( 0 ) ;
} /* if ... else */ ;
} /* SerialChPresent */
unsigned char _cdecl GetRSChar ( )
{
/* funkcja pobrania znakow z bufora cyklicznego */
unsigned char RetChar ;
/* ---------------------------------- */
DisableInt ( ) ;
if ( SerialParamRec . InpBuffer . Stop != SerialParamRec . InpBuffer . Start )
{
RetChar = SerialParamRec . InpBuffer . RSBuffer [ SerialParamRec . InpBuffer . Start ] ;
SerialParamRec . InpBuffer . Start ++ ;
SerialParamRec . InpBuffer . Start = SerialParamRec . InpBuffer . Start % IRSBuffSize ;
} /* if ... */
else
RetChar = 0 ;
EnableInt ( ) ;
return ( RetChar ) ;
} /* GetRSChar */
signed short ConvertChar ( unsigned char Ch )
{
/* zamiana 6-bitowego kodu U2 na
16-bitowy kod U2 (signed short/integer) */
unsigned short CnvV ;
/*--------------------------------*/
if ( Ch < 0x1F )
/* jezeli liczba jest mniejsza od 31, to
wynik jest zgodny z kodem naturalnym binarnym */
return ( ( signed short ) Ch ) ;
/* w przeciwnym wypadku */
CnvV = 0xFFC0 | ( unsigned short ) Ch ;
/* ustawic wszystkie bity na 1 z wyjatkiem
ostatnich 6 - otrzymamy ta sama liczbe
w 16-bitowym U2 */
return ( ( signed short ) CnvV ) ;
} /* ConvertChar */
void AktualizujPozycjeMyszy ( )
{
if ( SerialChPresent ( ) )
{ /* jezeli jest cos do odebrania,
to odbierz kolejny znak jako 1,2 lub 3
znak do interpretacji */
switch ( SerialParamRec . State )
{
case 0 :
SerialParamRec . Char1 = GetRSChar ( ) ;
break ;
case 1 :
SerialParamRec . Char2 = GetRSChar ( ) ;
break ;
case 2 :
SerialParamRec . Char3 = GetRSChar ( ) ;
break ;
default :
;
} /* switch */ ;
SerialParamRec . State ++ ; /* zwieksz liczbe odebranych znakow */
if ( SerialParamRec . State == 3 )
{ /* jezeli odebrano 3 bajty to */
SerialParamRec . XPosition += ConvertChar ( SerialParamRec . Char2 ) ;
/* dosumowac przyrost X */
SerialParamRec . YPosition += ConvertChar ( SerialParamRec . Char3 ) ;
/* dosumowac przyrost Y */
if ( SerialParamRec . XPosition < 0 )
SerialParamRec . XPosition = 0 ;
if ( SerialParamRec . YPosition < 0 )
SerialParamRec . YPosition = 0 ;
if ( SerialParamRec . XPosition > MaxX )
SerialParamRec . XPosition = MaxX ;
if ( SerialParamRec . YPosition > MaxY )
SerialParamRec . YPosition = MaxY ;
/* ograniczyc pozycje do polozenia
w zadanym obszarze */
SerialParamRec . LeftButton = FALSE ;
SerialParamRec . RightButton = FALSE ;
if ( SerialParamRec . Char1 & 0x20 )
SerialParamRec . LeftButton = TRUE ;
if ( SerialParamRec . Char1 & 0x10 )
SerialParamRec . RightButton = TRUE ;
/* okreslic nacisniecie klawiszy */
SerialParamRec . State = 0 ;
SerialParamRec . Valid = TRUE ; /* ustawic wskaznik waznosci danych */
} /* if */ ;
} /* if */ ;
} /* AktualizujPozycjeMyszy */
void PokazPozycjeMyszy ( )
{
/* wyswietlic informacje o polozeniu i stanie myszy */
unsigned char LChar ;
unsigned char RChar ;
/*--------------------------------*/
LChar = ' ' ;
RChar = ' ' ;
if ( SerialParamRec . LeftButton )
LChar = '+' ;
if ( SerialParamRec . RightButton )
RChar = '+' ;
printf ( "X= %4d Y=%4d lewy kl.=%c prawy kl.=%c\n" , SerialParamRec . XPosition ,
SerialParamRec . YPosition , LChar , RChar ) ;
} /* PokazPozycjeMyszy */
main ( )
{
/*--------------------------------*/
OpenCOM1 ( ) ;
// OpenCOM2 ( ) ;
printf ( "Program jest dla DOS\n" ) ;
printf ( "Wcisnij ESC aby skonczyc program.\n" ) ;
for ( ; ; )
{
AktualizujPozycjeMyszy ( ) ;
if ( SerialParamRec . Valid )
{
PokazPozycjeMyszy ( ) ;
SerialParamRec . Valid = FALSE ;
} /* if */ ;
if ( kbhit ( ) )
if ( getch ( ) == 27 )
break ;
} /* for */ ;
CloseCOM ( ) ;
} /* main */
Kto jest online
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 0 gości