Чтение из Lpt

  • Автор темы SotM
  • Дата начала
Статус
Закрыто для дальнейших ответов.
S

SotM

Гость
#1
Значится так, задача такая: есть некоторое устройство подключенное к LPT порту, и оно генерит сигнал. Мне нужно прочитать данные и записать в файл. В принципе всё просто.

В чистом ДОСе эта программа работает, т.е. выходной счетчик будет постоянно равен 4096. В Досе я естественно использую обычные средства доступа к порту (outportb/inportb). Если стоит ее сделать под виндой (пусть даже и консольная версия), то данные не будут постоянными, а будут «плавать» где-то от 3800 до 4090. А почему так происходит никто мне не может дать ответа :)

Я использую библиотеку Porttalk для получения доступа к LPT через драйвер. Также использовал Winio, и NTPort – результат один и тот же. Я даже отключал порт принтера в Устройствах, и также менял режим его (EPP/ECP) в БИОСе. Такое ощущение, что во время обращения к устройству Windows что-то делает в этот момент с портом, и поэтому не доходят все данные до моей программы.

Вот текст:

Код:
// lpt_read.cpp : 

#include <stdio.h>
#include <conio.h>
#include <winuser.h>

#include "stdafx.h"

//#define __USE_PORTTALK__

#ifdef __USE_PORTTALK__
#include "porttalk/PortTalk_IOCTL.h"
#else
#include "winio/winio.h"
#endif

float	RotAngle_Step, RotAngle_Start, RotAngle_End, RotAngle;
FILE	*file_output;

// Initialiazes the LPT port
void LPT_Init( void )
{
#ifdef __USE_PORTTALK__
outportb( 0x378, 0x08 );
outportb( 0x378, 0x0C );
#else
SetPortVal( 0x378, 0x08, 1 );
SetPortVal( 0x378, 0x0C, 1 );
#endif
}

// Writes to the LPT port
void LPT_Write( unsigned char value )
{
#ifdef __USE_PORTTALK__
outportb( 0x378, value );
#else
SetPortVal( 0x378, value, 1 );
#endif
}

// Gets status from the LPT port
unsigned char LPT_GetStatus( void )
{
#ifdef __USE_PORTTALK__
return inportb( 0x379 );
#else
DWORD	d_port_data;
GetPortVal( 0x379, &d_port_data, 1 );
return (unsigned char)d_port_data;
#endif
}

// Receives necessary data 
long Receive( void )
{
unsigned char value;
long counter = 0;

printf( "Reading data from LPT port ... " );
do
{
value = LPT_GetStatus();
if ( value & 32 )
{	
counter++;
// Skip all the numbers which have the 6th bit set
do
{
value = LPT_GetStatus();
} while ( value & 32 );
}
// do until the 5th bit is not set
value = LPT_GetStatus();
} while ( value & 16 );
printf( "\r" );

return counter;
}

void Init( void )
{
printf( "Rotation angle step, Step = " );
scanf( "%f", &RotAngle_Step );
printf( "Initial angle, Start = " );
scanf( "%f", &RotAngle_Start );
printf( "End angle, End = " );
scanf( "%f", &RotAngle_End );

RotAngle = RotAngle_Start - RotAngle_Step;

file_output = fopen( "output.txt", "w" );

printf( "\n" );
}

int __cdecl main( void )
{
unsigned char	status;
long			counter;


#ifdef __USE_PORTTALK__
if ( OpenPortTalk() == -1 )
{
printf( "OpenPortTalk() failed to install the porttalk.sys driver\n\n" );
return 1;
}
#else
if ( InitializeWinIo() == false )
{
printf( "InitializeWinIo() failed to install the WinIo.sys driver\n\n" );
return 1;
}
#endif

Init();

LPT_Write( 0 );
LPT_Init();

do 
{
status = LPT_GetStatus();
if ( status & 16 )
{
counter = Receive();
RotAngle += RotAngle_Step;
printf( "Angle: %5.3f	 Value: %ld\n", RotAngle, counter );
fprintf( file_output, "%5.3f	 %ld\n", RotAngle, counter );
}
} while ( RotAngle + RotAngle_Step <= RotAngle_End );

LPT_Write( 1 );

#ifdef __USE_PORTTALK__
ClosePortTalk();
#else
ShutdownWinIo();
#endif
fclose( file_output );
printf( "\nDone\n" );

return 0;
}
 
S

Sensei

Гость
#2
Я б советовал самому написать код работы с портом (чтение и запись данных такаяже как и с COM портом), а не пользоваться "готовыми" продуктами

Открыть порт - CreateFile
Закрыть - CloseHandle
Записать данные - WriteFile
считать - ReadFile

вот дополнительная инфа --- ищи, может чтото полезное для тебя будет

инфа по LPT
 
S

SotM

Гость
#3
А вот как мне считать данные из регистра состояния? (0x379)
 
A

alexplev

Гость
#4
Привожу цитату из своего справочного архива.
"Работа с портом как с файлом в данном случае не подходит, т.к. нужно не данные читать, а опрашивать состояния. Тем не менее, после длительного изучения MSDN, легальный доступ к некоторым линиям порта был обнаружен! Способ этот — доступ к порту через функцию DeviceIoControl(…, IOCTL_PAR_QUERY_INFORMATION, …). "
 
Статус
Закрыто для дальнейших ответов.