Kontrol af extrene enheder via lpd port !!!??:/

Tags:    c++ php

For nogle år siden lavde jeg et program i c++ som styrede nogle reler fra printerporten.
Kort sagt var det bare et ja nej program hele vejen igennem og temligt simpelt.
Men på grund af personlige ting blev jeg nød til at droppe programmeringen, i næsten 3 år helt.
Jeg har nu først fået trækket mig op igen (lækkert ;)-) og har nu lige brug for lidt genopfriskelse.

Jeg mener at jeg brugte flowcontrol via lpd porten.. men er ret lost angåene hvad jeg lige skal starte ud med ...

Hvis der sidder nogle der ude som har et par minutter til at skrive et forslag til hvad jeg skal kikke efter på noget opsumering osv ville det være cool..

Mange hilzner og tak.

[ jomfru indlæget på dette forum ;-) ]
---------------------------------
-Information will set you free.



3 svar postet i denne tråd vises herunder
2 indlæg har modtaget i alt 7 karma
Sorter efter stemmer Sorter efter dato

Hvis du kører NT/Win2K/Xp - skal du bruge en kernel ting - man får nemlig ik lov at lave direct access.


I NT/2000/XT kan bruges "CreateFile" et API kald. Hvis det altså er LPT porten.

Jeg brugte selv
"
outpb(378(hex),data);
//og
inpb(378);
"

Hvad angår RS232 kan dette også gøres via. "CreateFile". En af mine lærer har skrevet en klasse til førmålet som jeg lige syntes jeg ville skrive her..... (Der skal lidt kode til at få den til at virke, men den virker...) Den laver et event når der kommer data...... Hygge


// Serial.h: interface for the CSerial class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_SERIAL_H__308D7E20_BB3F_11D4_8D78_00608CF3F72D__INCLUDED_)
#define AFX_SERIAL_H__308D7E20_BB3F_11D4_8D78_00608CF3F72D__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CSerial;

struct structReceiverThreadParam {
CSerial* pSerial;
CWnd* pTargetWnd;
TCHAR cStop;
CCriticalSection* pCS;
};

struct structSenderThreadParam {
CSerial* pSerial;
CWnd* pTargetWnd;
TCHAR cStop;
};

class CSerial
{
public:
int m_SenderSpeed;
CString m_SenderData;
BOOL bReceiver;
CString getFrame();
CCriticalSection cs;
bool bReceived;
int nFrameOverrun; // No of lost frames
CString FrameBuffer1;
CString FrameBuffer;
HANDLE hCOM;
bool stopReceiving();
bool startReceiving();
bool stopSending();
bool startSending(CString strData, int charSpeed=10);
bool bReceiving, bSending;
int portNo;
TCHAR charIn();
bool charOut(TCHAR ch);
CSerial(CWnd* pTargetWnd, TCHAR cStop=_T('#'), int port=1);
virtual ~CSerial();
private:
CString strError;
structReceiverThreadParam RecvThreadParam;
structSenderThreadParam SendThreadParam;
CWinThread* pReceiver;
CWinThread* pSender;
};

#endif // !defined(AFX_SERIAL_H__308D7E20_BB3F_11D4_8D78_00608CF3F72D__INCLUDED_)

// Serial.cpp: implementation of the CSerial class.
//
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
//
// CSerial receives frames of characters on a specified serial port.
// The port must be specified as 1 (for COM1, default) or 2 (for COM2).
// The frames are terminated by a specified stop character (default '#').
//
// A WM_APP message is sent to a specified window for each received frame.
// The window is specified in a CSerial constructor parameter.
//
// Received frames are obtained by calling the CSerial function getFrame().
// getFrame() returns the frame as a CString value.

// The CSerial data member nFrameOverrun contains the number of lost frames
// since the latest frame returned by getFrame().
//
// Other CSerial receiver functions are startReceiving() and stopReceiving().
//
// When not receiving, CSerial can be used to send frames of characters at a
// specified speed - between 1 and 20 char/second (10 is default) - by calling
// startSending(CString Frame, int charSpeed).
//
// A WM_APP+1 message is sent to a specified window (CSerial parameter) when
// all characters in the frame are sent.
//
// The CSerial data members bReceiving and bSending indicate the state of the
// receiver and the sender. (Only one can be true).
//
// Low level I/O is supported by the methods charIn() and charOut();
//
//
// Custom designed by Bendt Hansen, ECC eit
// Rev. December 2000.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Serial.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////////////
// Receiver thread function

#define READ_TIMEOUT 100 // 100 msec

bool g_bTerminateReceiver = false;

UINT Receiver(LPVOID lpvParam)
{
CSerial* pSerial = ((structReceiverThreadParam*)lpvParam)->pSerial;
CWnd* pTargetWnd = ((structReceiverThreadParam*)lpvParam)->pTargetWnd;
TCHAR cStop = ((structReceiverThreadParam*)lpvParam)->cStop;
CCriticalSection* pCS = ((structReceiverThreadParam*)lpvParam)->pCS;
TCHAR RxData = 0;
UINT pos=0;
COMMTIMEOUTS timeouts;

while (!g_bTerminateReceiver) {
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = READ_TIMEOUT;

SetCommTimeouts(pSerial->hCOM, &timeouts);

while (!g_bTerminateReceiver && !RxData) {
RxData = pSerial->charIn();
Sleep(0);
}
if (RxData) {
if (RxData != cStop)
pSerial->FrameBuffer1 += RxData; // Write received char to buffer
else { // Stop character received
pCS->Lock(); // Begin critical section
pSerial->FrameBuffer = pSerial->FrameBuffer1; // Copy to FrameBuffer
pSerial->nFrameOverrun = (!pSerial->bReceived)?
++pSerial->nFrameOverrun:pSerial->nFrameOverrun;
pSerial->bReceived = false;
pCS->Unlock(); // End critical section
pSerial->FrameBuffer1 = _T(""); // Clear buffer
pTargetWnd->PostMessage(WM_APP, (WPARAM)pSerial->portNo);
}
RxData = 0;
}
}
return 0;
}

//////////////////////////////////////////////////////////////////////////////
// Sender thread function

bool g_bTerminateSender = false;

UINT Sender(LPVOID lpvParam)
{
CString TxBuffer = _T("");
TCHAR TxData;
CSerial* pSerial = ((structSenderThreadParam*)lpvParam)->pSerial;
CWnd* pTargetWnd = ((structSenderThreadParam*)lpvParam)->pTargetWnd;
TCHAR cStop = ((structSenderThreadParam*)lpvParam)->cStop;

while (!g_bTerminateSender) {
TxBuffer = pSerial->m_SenderData;
if (TxBuffer.GetLength()) {
for (int pos=0; pos<TxBuffer.GetLength(); pos++) {
TxData = TxBuffer[pos];
if (TxData == cStop) break;
pSerial->charOut(TxData);
Sleep(1000/pSerial->m_SenderSpeed);
}
pSerial->charOut(cStop);
}
pTargetWnd->PostMessage(WM_APP+1, (WPARAM)pSerial->portNo);
Sleep(0);
}
return 0;
}

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSerial::CSerial(CWnd* pTargetWnd, TCHAR cStop, int port)
{
strError = _T("CSerial error: ");
bReceiving = false;
bSending = false;
m_SenderSpeed = 10;
nFrameOverrun = 0;
bReceived = true;
bReceiver = true;
FrameBuffer = _T("");
FrameBuffer1 = _T("");
portNo = (port==2)?2:1; // COM1 is default

// Configure and initialize COM port
DCB dcb; // Device Control Block for COM port
CString strPort = (port==1)?CString(_T("COM1:")):CString(_T("COM2:"));
hCOM = CreateFile(
strPort,
GENERIC_READ|GENERIC_WRITE,
0, // a must for COM devices
NULL, // no security attrs
OPEN_EXISTING, // a must for COM devices
0, // not overlapped I/O
NULL // a must for COM devices
);
if (hCOM == INVALID_HANDLE_VALUE) {
CString message;
message.Format(strError + _T("Couldn't open COM port %d"), port);
AfxMessageBox(message);
pTargetWnd->PostMessage(WM_CLOSE);
}
GetCommState(hCOM, &dcb);
CString str = _T("baud=9600 parity=N data=8 stop=1");
BuildCommDCB(str, &dcb);
// dcb.fDtrControl = DTR_CONTROL_ENABLE;
// dcb.fRtsControl = RTS_CONTROL_ENABLE;
SetCommState(hCOM, &dcb);

// Create Receiver thread in suspended state
RecvThreadParam.pSerial = this;
RecvThreadParam.pTargetWnd = pTargetWnd;
RecvThreadParam.cStop = cStop;
RecvThreadParam.pCS = &cs;
pReceiver = AfxBeginThread(Receiver, (LPVOID)&RecvThreadParam,
THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
pReceiver->m_bAutoDelete = false; // Don't delete thread object when thread terminates

// Create Sender thread in suspended state
SendThreadParam.pSerial = this;
SendThreadParam.pTargetWnd = pTargetWnd;
SendThreadParam.cStop = cStop;
pSender = AfxBeginThread(Sender, (LPVOID)&SendThreadParam,
THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
pSender->m_bAutoDelete = false; // Don't delete thread object when thread terminates
}

CSerial::~CSerial()
{
int result;
DWORD exitCode;

// Close down receiver thread
g_bTerminateReceiver = true;
ResumeThread(pReceiver->m_hThread);
result = GetExitCodeThread(pReceiver->m_hThread, &exitCode);
while (!result || (exitCode == STILL_ACTIVE)) {
Sleep(0);
result = GetExitCodeThread(pReceiver->m_hThread, &exitCode);
}
// Delete CWinThread object
delete pReceiver;

// Close down sender thread
g_bTerminateSender = true;
ResumeThread(pSender->m_hThread);
result = GetExitCodeThread(pSender->m_hThread, &exitCode);
while (!result || (exitCode == STILL_ACTIVE)) {
Sleep(0);
result = GetExitCodeThread(pSender->m_hThread, &exitCode);
}
// Delete CWinThread object
delete pSender;

// Close handle to COM port
CloseHandle(hCOM);
}

TCHAR CSerial::charIn()
{
TCHAR ch = _T('0');
DWORD NoOfBytesRe;

ReadFile(hCOM, &ch, 1, &NoOfBytesRe, NULL);
return NoOfBytesRe?ch:0;
}

bool CSerial::charOut(TCHAR ch)
{
DWORD NoOfBytesWr;

WriteFile(hCOM, &ch, 1, &NoOfBytesWr, NULL);
return NoOfBytesWr?true:false;
}

bool CSerial::startReceiving()
{
bool result = false;

if (!bSending && !bReceiving) {
bReceiving = true;
pReceiver->ResumeThread();
result = true;
}
return result;
}

bool CSerial::stopReceiving()
{
bool result = false;

if (bReceiving) {
bReceiving = false;
pReceiver->SuspendThread();
result = true;
}
return result;
}

bool CSerial::startSending(CString strData, int charSpeed)
{
bool result = false;

if (!bReceiving && !bSending) {
m_SenderData = strData;
m_SenderSpeed = ((charSpeed>=1)&&(charSpeed<=20))?charSpeed:10;
bSending = true;
pSender->ResumeThread();
result = true;
}
return result;
}

bool CSerial::stopSending()
{
bool result = false;

if (bSending) {
bSending = false;
pSender->SuspendThread();
result = true;
}
return result;
}

CString CSerial::getFrame()
{
CString Frame;
cs.Lock(); // Begin critical section
Frame = FrameBuffer;
bReceived = true;
nFrameOverrun = 0;
cs.Unlock(); // End critical section
return Frame;
}





User
Bruger #24 @ 16.08.02 10:57

Du skal skrive til 0x378. Husk at sætte kontrol registeret op..
Hvis du kører NT/Win2K/Xp - skal du bruge en kernel ting - man får nemlig ik lov at lave direct access.

jeg har noget kode til windows - der kan man om ikke andet se hvad der skal til
Håber det kunne bruges.

Mvh
Daniel

Jody Rice has provided this code for using inpout32 with Visual C++ v6:

typedef UINT (CALLBACK* LPFNDLLFUNC1)(INT,INT);
typedef UINT (CALLBACK* LPFNDLLFUNC2)(INT);
HINSTANCE hDLL; // Handle to DLL
LPFNDLLFUNC1 Output; // Function pointer
LPFNDLLFUNC2 Input; // Function pointer
INT Addr;
INT AddrIn;
INT Value;
hDLL = LoadLibrary("Inpout32");
if (hDLL != NULL)
{
Output = (LPFNDLLFUNC1)GetProcAddress(hDLL,"Out32");
Input = (LPFNDLLFUNC2)GetProcAddress(hDLL,"Inp32");
if (!Output || !Input)
{
// handle the error FreeLibrary(hDLL);
}
}
Addr = 0x378;
AddrIn = 0x379;
Value = 0;
Output(Addr, Value);
INT somenum = Input(Addr);



Hvis dette ikke er nok så prøv WinDriver det er et godt program til at lave Windows Hardware driver....

JSA



t