📄 lptregistar.cpp
字号:
// LPTRegistar.cpp: implementation of the CLPTRegistar class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "LPTRegistar.h"
#include <limits>
/* Prototipovi funkcija za direktan pristup LPT portu (Inp32 i Outp32).
* Funkcije su definisane u 'inpout32.dll':
* - treba da se ubaci fajl 'inpout32.lib' u direktorijum projekta
* - treba da se linkuje sa 'inpout32.dll':
* - meni 'Project/Settings...',
* - tab 'Link'
* - polje 'Object/Library modules' (u spisak dodati inpout32.lib)
* - 'inpout32.dll' treba da postoji u System direktorijumu Windowsa
*/
short _stdcall Inp32(short PortAddress);
void _stdcall Out32(short PortAddress, short data);
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CLPTRegistar::CLPTRegistar(int adresaPorta)
: adresa_m(adresaPorta)
, sadrzaj_m(0)
{
MoguceCitanje(true);
MogucUpis(true);
}
CLPTRegistar::~CLPTRegistar()
{
}
short CLPTRegistar::DajSadrzaj(void)
{
return sadrzaj_m;
}
short CLPTRegistar::DajStanjePinova(void)
{
int sadrzajPinova = DajSadrzaj();
spisakBitova.InvertujPinoveSaInverznomLogikom(sadrzajPinova);
return sadrzajPinova;
}
short CLPTRegistar::Procitaj(bool posmatrajPinove)
{
// Procitaj registar
if (MoguceCitanje()) {
PostaviSadrzaj(Inp32(adresa_m));
}
// Vrati ono sto se trazi
if (posmatrajPinove) {
return DajStanjePinova();
}
else {
return DajSadrzaj();
}
}
void CLPTRegistar::Posalji(short sadrzaj, bool posmatrajPinove)
{
if (MogucUpis()) {
int sadrzajZaSlanje = sadrzaj;
if (posmatrajPinove) {
spisakBitova.InvertujPinoveSaInverznomLogikom(sadrzajZaSlanje);
}
Out32(adresa_m, sadrzajZaSlanje);
PostaviSadrzaj(sadrzajZaSlanje);
}
}
bool CLPTRegistar::AdresiranMaskom(int bitMaska)
{
return (0 != (bitMaska & FormirajMaskuZaRegistar()));
}
int CLPTRegistar::RasporediBitoveSadrzajaUMasku(bool posmatrajPinove)
{
int maska = FormirajMaskuZaRegistar();
int izdvojeniBit;
int pozicijaUMasci;
int rezultat = 0;
for (int i = 0; i < BrojBitovaSadrzaja(); ++i) {
// 1. izvadi i-ti bit iz sadrzaja i pomeri ga udesno
// (na poziciju bita najmanje tezine)
izdvojeniBit = IzdvojiBitIPomeriNaLSB(i, DajSadrzaj());
// 2. sracunaj poziciju i-te jedinice maske
pozicijaUMasci = DajPozicijuJedinice(i, maska);
if (pozicijaUMasci == -1) {
break;
}
// 3. proveri da li se radi o inverznoj logici
int maskaBita = 0x01;
maskaBita <<= pozicijaUMasci;
if (posmatrajPinove && PinInvertovan(maskaBita)) {
NegirajLSB(izdvojeniBit);
}
// 4. bit pripremljen u koraku 1. postavi na poziciju odredjenu u koraku 2.
izdvojeniBit <<= pozicijaUMasci;
// 5. ugradi obradjeni bit u rezultat
rezultat |= izdvojeniBit;
}
return rezultat;
}
bool CLPTRegistar::Postavljen(int bitMaska, bool posmatrajPinove)
{
// najpre iscitaj sadrzaj sa LPT porta !!!
Procitaj();
// odredi poziciju bita sadrzaja koji odgovara datom bitu maske
//(0 za bit najmanje tezine, 1 za sledeci ... , 7 za bit najvece tezine)
int pozicijaBita = PozicijaBitaUSadrzaju(bitMaska);
// izdvoji dati bit sdrzaja
int bitSadrzaja = (DajSadrzaj() >> pozicijaBita) & 0x01;
// ako je invertovana logika, komplementiraj bit
if (posmatrajPinove && PinInvertovan(bitMaska)){
NegirajLSB(bitSadrzaja);
}
return (bitSadrzaja == 0x01);
}
void CLPTRegistar::Postavi(int bitMaska, bool posmatrajPinove)
{
NasetujIzabraneBitove(bitMaska, true, posmatrajPinove);
}
void CLPTRegistar::Obori(int bitMaska, bool posmatrajPinove)
{
NasetujIzabraneBitove(bitMaska, false, posmatrajPinove);
}
bool CLPTRegistar::MoguceCitanje(void)
{
return moguceCitanje_m;
}
bool CLPTRegistar::MogucUpis(void)
{
return mogucUpis_m;
}
void CLPTRegistar::MoguceCitanje(bool omoguci)
{
moguceCitanje_m = omoguci;
}
void CLPTRegistar::MogucUpis(bool omoguci)
{
mogucUpis_m = omoguci;
}
void CLPTRegistar::Inicijalizuj(bool moguceCitanje, bool mogucUpis)
{
// odredi adresu registra
adresa_m += Offset();
// definisi dozvole pristupa
MoguceCitanje(moguceCitanje);
MogucUpis(mogucUpis);
// definisi bitove
FormirajSpisakBitova();
}
int CLPTRegistar::FormirajMaskuZaRegistar(void)
{
return (spisakBitova.FormirajMaskuZaSveBitove());
}
int CLPTRegistar::BrojBitovaMaske(void)
{
return (std::numeric_limits<int>::digits);
}
int CLPTRegistar::BrojBitovaSadrzaja(void)
{
return (std::numeric_limits<int>::digits);
}
int CLPTRegistar::PozicijaBitaUSadrzaju(int bitMaska)
{
return (spisakBitova.PozicijaBita(bitMaska));
}
bool CLPTRegistar::PinInvertovan(int bitMaska)
{
return (spisakBitova.PinInvertovan(bitMaska));
}
int CLPTRegistar::PrviBitMaske(int bitMaska)
{
return (spisakBitova.IzdvojiMaskuZaBitSaNajnizomPozicijom(bitMaska));
}
//////////////////////////////////////////////////////////////////////
// Pomocne funkcije
//////////////////////////////////////////////////////////////////////
void CLPTRegistar::PostaviSadrzaj(short noviSadrzaj)
{
sadrzaj_m = noviSadrzaj;
}
int CLPTRegistar::IzdvojiBitIPomeriNaLSB(unsigned int pozicija, int sadrzaj)
{
sadrzaj >>= pozicija;
return (sadrzaj & 0x01);
}
int CLPTRegistar::DajPozicijuJedinice(unsigned int indeks, int maska)
{
int pomMaska;
int indeksJedinice = 0;
int pozicija = -1;
const int brojBitovaMaske = BrojBitovaMaske();
for (int i = 0; i < brojBitovaMaske; ++i ) {
pomMaska = maska >> i;
if (pomMaska & 0x01) {
if (indeksJedinice == indeks) {
pozicija = i;
break;
}
else {
++indeksJedinice;
}
}
}
return pozicija;
}
void CLPTRegistar::NasetujIzabraneBitove(int bitMaska, bool postaviNaJedinicu, bool posmatrajPinove)
{
if (!MogucUpis()) return;
short sadrzajZaSetovanje = DajSadrzaj();
// uzmi samo bitove maske koji se odnose na konkretni registar
int maska = bitMaska & FormirajMaskuZaRegistar();
// uzmi prvi bit koji je na redu
int izdvojeniBitMaske = PrviBitMaske(maska);
int pozicijaBita;
bool inverznaLogika;
int brojacBitovaMaske = 0; // 'sigurnosni' brojac
const int maxBrojBitovaMaske = BrojBitovaMaske(); // maksimalna vrednost sigurnosnog brojaca
while ((izdvojeniBitMaske != 0) && (brojacBitovaMaske < maxBrojBitovaMaske)) {
// odredi poziciju bita sadrzaja koji odgovara datom bitu maske
// (0 za bit najmanje tezine, 1 za sledeci ... , 7 za bit najvece tezine)
pozicijaBita = PozicijaBitaUSadrzaju(izdvojeniBitMaske);
// setuj bit
inverznaLogika = posmatrajPinove && PinInvertovan(izdvojeniBitMaske);
// bit se postavlja na jedinicu u dva slucaja :
// - ako je postaviNaJedinicu == true i inverznaLogika == false ili
// - ako je postaviNaJedinicu == false i inverznaLogika == true
// znaci kad je jedan fleg true, drugi treba da je false, a to je XOR :
if (postaviNaJedinicu ^ inverznaLogika) {
// postavi bit na jedinicu
sadrzajZaSetovanje |= (0x01 << pozicijaBita);
}
else {
// postavi bit na nulu
sadrzajZaSetovanje &= (~(0x01 << pozicijaBita));
}
// ocisti bit maske koji je upravo obradjen ...
maska &= (~izdvojeniBitMaske);
// .. da bi mogao da predje na sledeci bit
izdvojeniBitMaske = PrviBitMaske(maska);
++brojacBitovaMaske;
}
// Snimi novu vrednost u registar
Posalji(sadrzajZaSetovanje, false); // 'false', jer nije potrebno invertovanje pre slanja
// (a nije ni moguce jer samo u ovoj proceduri
// znam koje bitove da setujem a koje ne diram) !
}
void CLPTRegistar::NegirajLSB(int& vrednost)
{
vrednost ^= 0x01; // XOR sa 1 je negacija
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -