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;
}