What is it:
This is a minimalist library based on the inpout32 DLL
Basically I wrapped the original library and added a whole bunch of useful constants to easily access the Control and Status registers while keeping things clean and simple.
This library is currently being used on a side project I’ve been working on with a friend, since he doesn’t have any μController experience we decided to use LPT for the time being.
The code:
; Minimalist Library for Parallel port access based on inpout32.dll ; by Gustavo J. Fiorenza AKA GuShH (info@gushh.net - info@gushh.com.ar) ; Version 1.0 - 11/01/2011 EnableExplicit ; Default LPT Addresses. #PARALLEL_PORT_LPT1 = $3BC #PARALLEL_PORT_LPT2 = $378 #PARALLEL_PORT_LPT3 = $278 ; Register offsets. #PARALLEL_PORT_STATUS = $01 #PARALLEL_PORT_CONTROL = $02 ; Shared with Data Register. #PARALLEL_PORT_OFF = $00 #PARALLEL_PORT_BIT0 = $01 #PARALLEL_PORT_BIT1 = $02 #PARALLEL_PORT_BIT2 = $04 #PARALLEL_PORT_BIT3 = $08 #PARALLEL_PORT_BIT4 = $10 #PARALLEL_PORT_BIT5 = $20 #PARALLEL_PORT_BIT6 = $40 #PARALLEL_PORT_BIT7 = $80 XIncludeFile "ParallelPort_Constants.pbi" ; All of the helper, non-essential constants are defined here. Structure PARALLEL_PORT Handle.i Port.i LastData.i EndStructure ;- Instance construction and destruction Procedure.i ParallelPort_Create( Port.i = #PARALLEL_PORT_LPT2 ) Define.PARALLEL_PORT *this = AllocateMemory( SizeOf(PARALLEL_PORT) ) If *this *this\Port = port *this\Handle = OpenLibrary( #PB_Any, "inpout32.dll" ) If IsLibrary( *this\Handle ) ProcedureReturn *this Else Debug "Couldn't load inpout32.dll" FreeMemory(*this) ProcedureReturn #Null EndIf EndIf EndProcedure Procedure.i ParallelPort_Destroy( *this.PARALLEL_PORT ) If *this If IsLibrary( *this\Handle ) CloseLibrary( *this\Handle ) EndIf FreeMemory( *this ) *this = #Null ProcedureReturn *this EndIf EndProcedure ;- Communication Functions Procedure.i ParallelPort_Out( *this.PARALLEL_PORT, Bits.w = $00 ) If *this *this\LastData = Bits & $FF ProcedureReturn CallFunction( *this\handle, "Out32", *this\Port, Bits ) EndIf EndProcedure Procedure.i ParallelPort_In( *this.PARALLEL_PORT, Type.i ) If *this ProcedureReturn CallFunction( *this\handle, "Inp32", *this\Port + Type ) EndIf EndProcedure ;- Getter Functions Procedure.i ParallelPort_GetHandle( *this.PARALLEL_PORT ) If *this ProcedureReturn *this\Handle EndIf EndProcedure Procedure.i ParallelPort_GetPort( *this.PARALLEL_PORT ) If *this ProcedureReturn *this\Port EndIf EndProcedure Procedure.i ParallelPort_GetLastData( *this.PARALLEL_PORT ) If *this ProcedureReturn *this\LastData EndIf EndProcedure ;- Helper Functions Procedure.i ParallelPort_Clear( *this.PARALLEL_PORT ) If *this ParallelPort_Out( *this ) ; The default data parameter is $00 EndIf EndProcedure |
And the constants include:
; Read Only Status Register. #PARALLEL_PORT_STATUS_IRQ = #PARALLEL_PORT_BIT2 #PARALLEL_PORT_STATUS_ERROR = #PARALLEL_PORT_BIT3 #PARALLEL_PORT_STATUS_SELECT = #PARALLEL_PORT_BIT4 #PARALLEL_PORT_STATUS_PAPEROUT = #PARALLEL_PORT_BIT5 #PARALLEL_PORT_STATUS_ACK = #PARALLEL_PORT_BIT6 #PARALLEL_PORT_STATUS_BUSY = #PARALLEL_PORT_BIT7 ; Read / Write Control Register. #PARALLEL_PORT_CONTROL_STROBE = #PARALLEL_PORT_BIT0 #PARALLEL_PORT_CONTROL_LINEFEED = #PARALLEL_PORT_BIT1 #PARALLEL_PORT_CONTROL_RESET = #PARALLEL_PORT_BIT2 ; AKA Initialize Printer OR Init. #PARALLEL_PORT_CONTROL_SELECT = #PARALLEL_PORT_BIT3 ; These constants are icluded for completeness. All pin numbers are relative to D-Type 25, Centronics pins are between parentheses. #PARALLEL_PORT_D0 = #PARALLEL_PORT_BIT0 ; PIN2 #PARALLEL_PORT_D1 = #PARALLEL_PORT_BIT1 ; PIN3 #PARALLEL_PORT_D2 = #PARALLEL_PORT_BIT2 ; PIN4 #PARALLEL_PORT_D3 = #PARALLEL_PORT_BIT3 ; PIN5 #PARALLEL_PORT_D4 = #PARALLEL_PORT_BIT4 ; PIN6 #PARALLEL_PORT_D5 = #PARALLEL_PORT_BIT5 ; PIN7 #PARALLEL_PORT_D6 = #PARALLEL_PORT_BIT6 ; PIN8 #PARALLEL_PORT_D7 = #PARALLEL_PORT_BIT7 ; PIN9 #PARALLEL_PORT_C0 = #PARALLEL_PORT_CONTROL_STROBE ; PIN 1 #PARALLEL_PORT_C1 = #PARALLEL_PORT_CONTROL_LINEFEED ; PIN 14 #PARALLEL_PORT_C2 = #PARALLEL_PORT_CONTROL_RESET ; PIN 16 (31) #PARALLEL_PORT_C3 = #PARALLEL_PORT_CONTROL_SELECT ; PIN 17 (36) #PARALLEL_PORT_S3 = #PARALLEL_PORT_STATUS_ERROR ; PIN 15 (32) #PARALLEL_PORT_S4 = #PARALLEL_PORT_STATUS_SELECT ; PIN 13 #PARALLEL_PORT_S5 = #PARALLEL_PORT_STATUS_PAPEROUT ; PIN 12 #PARALLEL_PORT_S6 = #PARALLEL_PORT_STATUS_ACK ; PIN 10 #PARALLEL_PORT_S7 = #PARALLEL_PORT_STATUS_BUSY ; PIN 11 ; PINS 18-25 (19-30) Are all tied to GND. |
The hardware:
You don’t need any special hardware other than a Centronics or similar cable and a PC with a Parallel port (I’m sure some of you keep older PCs around for a good reason!) — Aside from this if you’re planning on running the examples you might want to get some LEDs and Switches.
Something to download:
The entire sources and support files including the examples can be found Here. Remember to exit the demo programs with the ESC key so the program gets a chance to reset the output bits.
Useful companion:
During development you may want to keep an eye on the status of each pin, however not everyone has a breakout board for this particular interface so you may want to use a software version of this concept instead, one of my favourite ones is LPT.exe — It works fairly well and there are several ports to different languages in case you’re interested in modifying it to suit your own needs.
Closing up:
That’s all for now, hopefully I’ll be able to finish the project and post some of the code here. Hint: it involves controlling unipolar steppers, computer vision and webcams!
Can you guess what it is?
Cheers.