Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   Usar puerto paralelo (https://www.clubdelphi.com/foros/showthread.php?t=59475)

luis1980 28-08-2008 09:42:42

Usar puerto paralelo
 
Hola, me gustaria saber como puedo enviar un dato a través del puerto paralelo en Borland C++ Builder 6, gracias.

fjcg02 28-08-2008 11:15:40

Aqui encontraras una dll que te permite manejar el puerto paralelo.

http://www.clubdelphi.com/foros/show...uerto+paralelo

Saludos

luis1980 28-08-2008 12:22:22

Gracias
 
Gracias por responder, pero me da el siguiente error el programa de ejemplo: "Priviliged instruction".
He ledio que otra manera de usar el puerto sería el siguiente:

asm{
push dx
mov dx,0x378
mov al, 5
out dx,al
pop dx
}

Pero al probarlo me da el mismo error que la dll.

FGarcia 28-08-2008 21:38:06

Te recomiendo que bajes la DLL que aparece en esta pagina. No se si sea la misma que estas intentando ya que no mencionas el nombre de ella. Yo he tenido buenas experiencias con ella.

Aqui tienes un pequeño ejemplo de uso -delphi-

Saludos

luis1980 29-08-2008 07:57:54

Ya me funciona
 
1 Archivos Adjunto(s)
Gracias por responder, no he probado esa dll porque ya tengo la solución.
Al parecer el windows xp con según que procesador no permite manejar el ciertas funciones de input y output en modo user (esa es la explicación que he encontrado), pero usando este programita que adjunto ya se desbloquea y puedo usar el puerto paralelo. Lo hago de la siguiente manera (está comprobado que funciona):

asm{
mov dx,0x378
mov al, 0
out dx,al
}

krlox31416 28-02-2009 19:52:58

Como solucionaste el problema asm???
 
tengo el sig. codigo...

Código Delphi [-]
/// usando registros con codigo de ensamblador asm
procedure TForm1.Button1Click(Sender: TObject);
begin
asm
MOV AX,1 // bit que se quiere utilizar en mi caso el bit 1
MOV DX,378H // puerto paralelo 378h
OUT DX,AX // damos salida lo que tenga AX en mi caso es 1 bit a DX que es el puerto 378h

Todo ok's para el windows 98, 2000 pero no me jala para el xp... como soluciono mi problema??? quiero que jale este mismo código pero para el xp...:confused:

Yo ya he checado programas que utilizan la dll pero todos ellos agregan las funciones pero como le ago con la instrucción asm en xp...

Por adelantado mil gracias!!!:)

escafandra 01-03-2009 01:03:14

Si descargas el archivo adjunto que deja luis1980 y te lees el pdf, encontraras la solución que buscas. Basicamente se trata de instalar un driver para permitir el uso del puerto paralelo desde asm en modo usuario.

Saludos.

krlox31416 02-03-2009 01:33:44

ok's ya cheque el documento!!!
 
ya vi que se utiliza el driver userport...

lo busque en la sig. pagina pero no logro poder descargarlo:eek:...

http://wareseeker.com/download/userport-1.0.rar/438025

ojala y alguien pueda decirme en donde más lo pudeo descargar:D...

saludos...:)

escafandra 02-03-2009 02:06:37

Cita:

Empezado por krlox31416 (Mensaje 339774)
ya vi que se utiliza el driver userport...

lo busque en la sig. pagina pero no logro poder descargarlo:eek:...

http://wareseeker.com/download/userport-1.0.rar/438025

:confused::confused: Pues si has revisado el archivo adjunto de luis1980, habrás visto que en el mismo tienes el Driver, el cargador del driver, las fuentes del mismo y las instrucciones adjuntas.

Saludos.

krlox31416 02-03-2009 02:11:38

si apenas lo note una vez enviado mi mensaje
 
gracias!!!

apenas lo vi una vez enviado el mensaje...:D

ya es hora de hechar a andar esto!!!

1000 gracias...

saludos!!!

luis1980 02-03-2009 08:52:01

Puerto paralelo
 
Perdón por no responder antes, no vi el mensaje hasta hoy.
En cualquier caso veo que ya está resuelta la duda.

Un saludo.

krlox31416 03-03-2009 03:55:19

ya quedo solucionado mi problema!!!
 
gracias por aclarar mis dudas...:confused: sin ustedes y este foro jamas podria haber hechado a andar estas lineas de código...

y pensar que hace tiempo pude haber hecho esto...

me hubiera ahorrado formatear mi maquina e instalarle el win 98 y 2000

vasto hacer un Ctrl - c y un Ctrl - v al driver UserPort.sys en la ubicacion de mi maquina c:\windows\sistems32\drivers...

apenas corri el programa y note que el erro habia desaparecido...

ya solo le pedi a mi hermano que me armara el proto con 3 leds para ver que jalara bien...

y si funciona!!!:)

gracias!!! esta ha sido una más de mis dudas que me han aclarado... por lo que decidi subir un pequeño ejemplo a un problema que tambien fue resuelto en este foro y deseo contribuir a este foro:rolleyes:

el ejemplo que subi se llama Respaldar tablas con ShellTreeView.rar descargenlo ojala y les pueda serbir de algo y 1000 gracias sigan asi orientando al que no sabe jejeje...

aqui dejo el hilo:http://www.terawiki.clubdelphi.com/D...in32/Ejemplos/

yelian 05-03-2009 23:24:33

Me parece una buena informacion,
Pero alguien fuera tan amable y posteara algun code para trabajar con el puerto Paralelo pero que el code sea en C++ ya que paso mucho trabajo para traducir el codico y asi lo entenderia mejor.

Muchas Gracias de ante mano

[Saludo]...

krlox31416 06-03-2009 01:30:00

Aqui unos links que te podran servir!!!
 
http://www.modelo.edu.mx/univ/virtec...o/paralelo.htm

http://www.forosdeelectronica.com/about3890.html

http://www.codeproject.com/KB/cs/cspplcds.aspx

aunque yo me quedo con el código que hasta ahora se me hace más sencillo y sin tener que agregar muchas lineas de código para delphi 5 y 6 no lo he calado con otras versiones!!!...s:)ludos!!!!

y si buscas en internet encontraras más paginas y hasta foros de discusion

escafandra 06-03-2009 16:26:54

yelian, los link que te propone krlox31416 son muy buenos para tus propósitos:Esto sería la traducción a C++ Builder del código que usó, es sencillo:
Código:

// usando registros con codigo de ensamblador asm
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  _asm{
    mov AX,1 // bit que se quiere utilizar en mi caso el bit 1
    mov DX, 0x378 // puerto paralelo 378h
    out DX,AX // damos salida lo que tenga AX en mi caso es 1 bit a DX que es el puerto 378h
  }
}

Saludos.

PD. Al terminar de escribir este post me di cuenta de que no había hecho referencia a este otro interesante hilo. En él se expone otra forma interesante de conseguir manejar el puerto paralelo sin uso de componentes.

yelian 07-03-2009 16:22:43

Hola escafandra;
Ya ise el codigo, pero no me funciono hasta que no puse el UserPort.sys en %windir%\system32\driver y ejecute el UserPort.exe que descarge de unos de los hilos que ahi en el foros,
El codigo ya me funciona bien,
Solo quisiera pedir una cosa, "DISCULPEN LA COMODIDAD" , pero me gustaria que me digeran cuales son los bit que te tengo que poner para
controlar los ping de salida .

Ejemplo:
--------
-Quisiera crear crear 3 checkBox:

*El Primero es para que cuando este marcado me encienda un
diodo_led que tengo conectado en el Ping 2 del conector y cuando
este desmarcado me lo apage.
*El Segundo es para hacer la misma operacion pero el diodo_led esta
en el Ping 3 del Conector.
*El Tercero es igual pero el diodo_led esta en el Ping 4...

En fin lo que quiero hacer es encender y apagar tres diodo_led que tengo conectado en el Puerto Paralelo (Ping 2-3-4) con tres CheckBox que tengo en mi Aplicacion.

(No piensen mal de mi, por la comodidad, pero lo que pasa es que me interesaria terminar lo que estoy haciendo y no se mucho sobre la programacion en Ensamble, apezar de que e visto algunos temas y paginas sobre la coneccion del puerto Paralelo tengo dificultades para entender como funciona, pero ya estoy entendiendo algo, gracias a ustedes, no escatimen explicaciones aunque no lo piensen puede ser de gran ayuda para mi)

Gracias a todos de Antemano...

[Saludos]...

yelian 07-03-2009 17:17:38

Hola se me habia olvidado que si me pudieran explicaran tambien como trabajar con la "io.dll" en C++
(la io.dll la pusieron en otro Hilo y pusieron un code pero en Delphi y yo uso C++).
Mi objetivo es controlar el Puerto Paralelo pero en C++ sin utilizar codigos de Ensamble, pero bueno si fuera muy dificil entonces denmelos en Esamble.

Gracias...

cHackAll 07-03-2009 21:40:54

Código:

typedef short (*OUT32_PTR) (short Addr);
typedef void (*INP32_PTR) (short Addr, short Port);
 
// . . .
 HINSTANCE hModule = LoadLibrary("inpout32.dll");
 if (hModule)
  {
  INP32_PTR Inp32 = (INP32_PTR)GetProcAddress(hModule, "Inp32");
  OUT32_PTR Out32 = (OUT32_PTR)GetProcAddress(hModule, "Out32");

  Inp32(Outp32(0x378), 1); // example
  FreeLibrary(hModule);
  }

;)

escafandra 08-03-2009 00:25:30

Hombre cHackAll, hacia tiempo que no te dejabas caer por el subforo de C++ Builder.;) Me alegro de poder saludarte y de leer tus, siempre interesantes, comentarios.

Un saludo.

krlox31416 08-03-2009 02:21:24

Cita:

-Quisiera crear crear 3 checkBox:

*El Primero es para que cuando este marcado me encienda un
diodo_led que tengo conectado en el Ping 2 del conector y cuando
este desmarcado me lo apage.
*El Segundo es para hacer la misma operacion pero el diodo_led esta
en el Ping 3 del Conector.
*El Tercero es igual pero el diodo_led esta en el Ping 4...

En fin lo que quiero hacer es encender y apagar tres diodo_led que tengo conectado en el Puerto Paralelo (Ping 2-3-4) con tres CheckBox que tengo en mi Aplicacion.
si prestas atención al bit que estas mandando de salida veras que no es dificil saber que ping estas utilizando...

a lo que voy es esto:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
begin
asm
MOV AX,1 // bit que se quiere utilizar en mi caso el bit 1
MOV DX,378H // puerto paralelo 378h
OUT DX,AX // damos salida lo que tenga AX en mi caso es 1 bit a DX que es el puerto 378h
end;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
asm
MOV AX,1 // bit que se quiere utilizar en mi caso el bit 1
MOV DX,378H // puerto paralelo 378h
OUT DX,AX // damos salida lo que tenga AX en mi caso es 1 bit a DX que es el puerto 378h
end;
end;
 
procedure TForm1.Button2Click(Sender: TObject);
begin
asm
MOV AX,2 // bit que se quiere utilizar en mi caso el bit 2
MOV DX,378H // puerto paralelo 378h
OUT DX,AX // damos salida lo que tenga AX en mi caso es 2 bit a DX que es el puerto 378h
end;
end;
 
procedure TForm1.Button3Click(Sender: TObject);
begin
asm
MOV AX,3 // bit que se quiere utilizar en mi caso el bit 3
MOV DX,378H // puerto paralelo 378h
OUT DX,AX // damos salida lo que tenga AX en mi caso es 3 bit a DX que es el puerto 378h
end;
end;
 
procedure TForm1.Button4Click(Sender: TObject);
begin
asm
MOV AX,4 // bit que se quiere utilizar en mi caso el bit 4
MOV DX,378H // puerto paralelo 378h
OUT DX,AX // damos salida lo que tenga AX en mi caso es 4 bit a DX que es el puerto 378h
end;
end;
 
procedure TForm1.Button5Click(Sender: TObject);
begin
asm
MOV AX,5 // bit que se quiere utilizar en mi caso el bit 5
MOV DX,378H // puerto paralelo 378h
OUT DX,AX // damos salida lo que tenga AX en mi caso es 5 bit a DX que es el puerto 378h
end;
end;
 
// con el bit 0 apagamos todo... a la salida estamos mandado cero
procedure TForm1.Button6Click(Sender: TObject);
begin
asm
MOV AX,0 // bit que se quiere utilizar en mi caso el bit 0
MOV DX,378H // puerto paralelo 378h
OUT DX,AX // damos salida lo que tenga AX en mi caso es 0 bit a DX que es el puerto 378h
end;
end;

si tienes conectados los leds veras que si agregas los respectivos botones con el código notaras que ping estas utilizando al fin de cuentas es lo de menos como tengas conectado tu circuito el chiste es saber que bit estas utilizando... no se si me de a entender...
Cita:

Nota: lo que utilizamos es el codigo binario
0 // 0 bit
1 // 1 bit
10 // 2 bits
11 // 3 bits
100 // 4 bits
101 // 5 bits
Puedes utilizar el bit que quieras si quieres utilizar más existe un pequeño truco!!!:)

consiste en diseñar un ciruito que puede duplicar mas combinaciones para seguir utilizando más bits!!!....:D

SALUDOS!!!!!

escafandra 08-03-2009 02:44:19

Yo pensé que por cada bit puesto a uno tenias señal en un pin del puerto paralelo (pines del 2 al 9)
00000001 para el 0
00000010 para el 1
00000100 para el 2
............
10000000 para el 8
11111111 para todos

Tal y como se describe aquí.:rolleyes:

Saludos.

krlox31416 08-03-2009 03:05:10

checando esto!!!
 

CONTROLAR TODOS LOS BITS DE SALIDA

Cita:

Ya vimos como controlar un solo Bit, pues el proceso para hacerlo con todos es similar.

Disponemos de 8 bits de salida o lo que es igual a 1byte.

En fin, para encender el primer bit debíamos enviar un 1, para encender los demás debemos pensar en el puerto como un número binario, los 1 representan un estado "alto" y los 0 un estado "bajo".

Si quieremos, encender todos los 8 bits, entonces debemos mandar un 11111111, podemos mandarlo en decimal y el mismo programa lo pasa a binario, enviaremos entonces un 255.

Y así es para cada número.
000=00000000
001=00000001
002=00000010
...
255=11111111
Tienes los pines disponibles (pines del 2 al 9) 255=11111111 que son todas las combinaciones que puedes hacer para 255 osea estas utilizando 255 bits

de tu aplicacion y tu circuito dependera el bit que quieras utilizar del 0 al 255

para esto deberas implementar un circuito que te ayudara a formar más combinaciones...

s:)ludos!!!...

krlox31416 08-03-2009 03:14:27

aaa...
 
una cosa es el ping y otra el bit...

tenemos del (2 - 9) para convinaciones de hasta 255...

saludos!!!...

escafandra 08-03-2009 21:50:36

Perdoname, krlox31416, no se si por la mecánica de un anterior post tuyo, no termino de entenderte.
Cita:

Empezado por krlox31416 (Mensaje 340562)
Código Delphi [-]
procedure TForm1.Button3Click(Sender: TObject);   
begin asm    
MOV AX,3 // bit que se quiere utilizar en mi caso el bit 3    
MOV DX,378H // puerto paralelo 378h    
OUT DX,AX // damos salida lo que tenga AX en mi caso es 3 bit a DX que es el puerto 378h    
end;    
end;

Dime una cosa. ¿Ese código que pines activa?
El 3 es el 0011b, con lo que según yo creo, debería activar las salidas 2 y 3 del puerto paralelo. ¿Estoy en lo cierto?

Saludos.

krlox31416 09-03-2009 04:04:57

correcto!!!
 
sip...
los pines 2 y 3 son los que utilizas para el bit 3 de salida...
Código Delphi [-]
procedure TForm1.Button3Click(Sender: TObject);   
begin asm    
MOV AX,3 // bit 3 de salida utilizando los pines 2 y 3    
MOV DX,378H // puerto paralelo 378h    
OUT DX,AX // damos salida lo que tenga AX en este caso es el bit 3 (combinacion -> 00000011 del pin 2 y 3)a DX que es el puerto 378h    
end;    
end;
lo que hacemos es mandar un pulso de 5 volts que es lo que manda el cpu...
de tu aplicación dependera como vas a programar por ejemplo...

mandar un estado alto seria cualquier bit del 1-255 menos el 0...
y un estado bajo seria el 0...
los pines del 2-9 dan salidas o estados altos de 5 volts...

por eso es importante que antes de hacer pruebas le adaptes a tu circuito (el que va a controlar tu programa hecho con este código alimentado con una fuente segun lo que soporte el diseño del mismo)una etapa optoacopladora con el fin de no dañar tu puerto de salida de tu maquina...
Cita:

Tienes los pines disponibles (pines del 2 al 9) 255=11111111 que son todas las combinaciones que puedes hacer para 255 osea estas utilizando 255 bits
http://www.modelo.edu.mx/univ/virtec...o/paralelo.htm

como decia una cosa es usar los pines de salida y otra saber que bit voy a mandar de salida...

saludos!!!...

escafandra 09-03-2009 21:10:59

Bien, gracias veo que no estaba equivocado.

Saludos.;)

yelian 09-03-2009 21:30:51

Gracias a todas sus respuestas, pero aber si entiendo un poco de todos esos numeros, en generar no se puede activar y desactivar un puerto por separado,
por ejemplo yo pongo :
MOV AX,3 // bit que se quiere utilizar en mi caso el bit 3
MOV DX,378H // puerto paralelo 378h
OUT DX,AX // damos salida lo que tenga AX en mi caso es 3 bit a DX que es el puerto 378h
y lo que me hace es como dice escafandra me activa el ping de salida 2-3 pero yo no quisiera hacer eso, yo quisiera controlar los pines por separados, por que en el ping 2 quiciera poner un motor, en el 3 un bombillo, el 4 un Extractor, etc
Pero quisiera encender y apagar cada uno por separado, no que para poder apagar uno tenga que apagarlos todos ni que cuando enciendo el 2 se encienda tambien el 3, quisiera hacerlo todo por separado, que numeros de bit tendria que poner para logar todo eso...

(Se que para conectar todo eso a la PC tengo que poner un circuito electronico con transistores y relay.)

Les agrdeseria toda la ayuda pocible ...

[Saludos]...

escafandra 09-03-2009 22:18:10

yelian, No es complicado. El número 3 en binario es 0000 0011b esto quiere decir que de activan dos pines, pues dos están a "1".

Si quieres activar uno solo, pues pon a uno un sólo bit, es decir potencias enteras de 2.

Si quieres activar de forma combinada pues es fácil, realizar una operación or binaria.

Pin2 activo: 0000 0001 = 1
Pin3 activo: 0000 0010 = 2
Pin4 activo: 0000 0100 = 4
Pin5 activo: 0000 1000 = 8
...........

Si queremos activar el pin2 y el 3:
Pin2 | Pin3, es decir 1 | 2, es decir 0000 0011.

Así con cualquier pin o combinación.

Fácil, ¿no?

Saludos.

yelian 10-03-2009 01:01:22

Gracias escafandra;

Por Favor pudieras continuar la Tablita que pusistes:

Pin2 activo: 0000 0001 = 1
Pin3 activo: 0000 0010 = 2
Pin4 activo: 0000 0100 = 4
Pin5 activo: 0000 1000 = 8

-Aaaaaaa
Probe el codigo de Ensamble con los numeros que me distes y me funciona bien pero hace una cosa que no gusta es que cuando enciendo el ping 2, se enciende bien pero cuando enciendo el ping 3 se enciende, pero me apaga el 2 me gustaria que trabajaran individual...

[Saludos]...

escafandra 10-03-2009 02:15:41

yelian, esto es binario puro.

Como dice el chiste, existen 10 tipos de personas, las que saben binario y las que no.
Bueno, la tablita es así:
Pin2 activo: 0000 0001 = 1
Pin3 activo: 0000 0010 = 2
Pin4 activo: 0000 0100 = 4
Pin5 activo: 0000 1000 = 8
Pin6 activo: 0001 0000 = 16
Pin7 activo: 0010 0000 = 32
Pin8 activo: 0100 0000 = 64
Pin9 activo: 1000 0000 = 128

Esto enciende individualmente cada pin, y por lo tanto apaga todos menos el activo. Todos los que quieras activos deben estar a "1", y los inactivos a "0"

Todos activos sería 1111 1111 en binario es decir 0xFF en hexadecimal ó 255 en decimal.
Para mantenerlos activos a medida que enciendes otro, debes hacer una operación or antes de mandarlo al puerto, con esto pones los "unos" que te interesen.

Saludos.

yelian 12-03-2009 00:37:34

escafandra me pudiera mostrar un ejemplo como pudiera utilizar el XOR ,

escafandra 12-03-2009 00:55:58

Cita:

Empezado por yelian (Mensaje 341071)
escafandra me pudiera mostrar un ejemplo como pudiera utilizar el XOR ,

El XOR, es un or exclusivo, es decir si un bit de "sólo" uno o del otro operando es uno, entonces el resultado en ese bit es uno. Esta sería la tabla.

xor |0 1
___|____
0 ..|0 1
1 ..|1 0

En C ese operador binario se representa por "^"

Ejemplo:

.........5 = 0101
.........4 = 0100
__________________
5^4 = 1 = 0001

Saludos.

escafandra 12-03-2009 01:01:47

Bueno, no se si lo que realmente quieres es el operador XOR o el OR, pero no cuesta trabajo exponer el or:
Basta con que un bit de cualquiera de los dos operandos este a uno para que el resultado en ese bit sea uno.
Esta sería la tabla:

.or |0 1
___|____
0 ..|0 1
1 ..|1 1

En C ese operador binario se representa por "|"

Ejemplo:

.........5 = 0101
.........4 = 0100
__________________
5|4 = .5 = 0101

Saludos.

escafandra 12-03-2009 01:04:26

Y para no dejar nada, el operador and:
Los dos bits de cada operando deben ser uno para que el resultado sea uno.

Esta sería la tabla.

and|0 1
___|____
0 ..|0 0
1 ..|0 1

En C ese operador binario se representa por "&"

Ejemplo:

.........5 = 0101
.........4 = 0100
__________________
5&4 = 4 = 0100

Saludos.

yelian 14-03-2009 16:15:31

Gracias a krlox31416, escafandra, cHackAll por la ayuda brindad ,

Después de tanto buscar y buscar encontré unos códigos que me pueden servir para lo que quiero hacer, mezclando estos códigos con lo que me dio escafandra sobre (XOR, OR, AND).

Códigos Encontrados:
----------------------
// para salida
void outp(char x)
{
asm mov dx,0x378
asm mov al,x
asm out dx,al
}
//para entrada
char inp(void)
{
char x;
asm mov dx,0x378
asm mov al,x
asm in al,dx
asm mov x,al
return x;
}

-AAA Estos codicos los encontre en www.elrincondelc.com , espero que no tenga nada que ver que los ponga a qui no...

Despues les cuento como me ha ido con todo esto...

Gracias por toda la ayuda

[Saludos]...

krlox31416 17-03-2009 04:34:21

ok's hijo!!!... se agradecen las gracias...
 
yo casi no he tenido la oportunidad de ayudar o aportar algo de mi en este foro...

la verdad es que terde mucho en saber manejar las funciones de este foro y hasta hace poco le agarre ley...

y si se siente chido que alguien desonocido que esta a mucha distancias te agradesca por la ayuda...

= mete gracias a ti por seguir aportando ideas...

es mas gracias a todos no???

o que show???

bueno pues gracias a todos!!! y...

saludos a todos!!!...:D:):D:):D:)

yelian 17-03-2009 16:20:42

Solucionado
 
Hola a todos de nuevo;
Al final logre hacer lo que tanto queria, gracias a ustedes y a otras paginas que visite,
Aqui les dejo algo de mi code utilizado por si alguien le interesa y tienen la misma duda que yo tenia...

Code: (OnClick del Button)
------
int a=0;
int b=0;
int c=0;
int d=0;
int e=0;
int f=0;
int g=0;
int h=0;
int res=0;
char resul=0;
if (CheckBox1->Checked==true) a=1;
if (CheckBox2->Checked==true) b=2;
if (CheckBox3->Checked==true) c=4;
if (CheckBox4->Checked==true) d=8;
if (CheckBox5->Checked==true) e=16;
if (CheckBox6->Checked==true) f=32;
if (CheckBox7->Checked==true) g=64;
if (CheckBox8->Checked==true) h=128;
res=a+b+c+d+e+f+g+h;
//Convirtiendo de int a char
resul=(char)res;
//Abriendo y Cerrando los puertos con codico de ensamble
asm mov dx,0x378
asm mov al,resul
asm out dx,al

Explico un poco de lo utilizado:

Tengo 8 CheckBox,cada uno me enciende y apaga un puerto diferente
ejemplo si esta activado el CheckBox1 y 5 se te enciente el Ping 2 y 6 del puerto paralelo.
-Todo ese codico recuerden que se pone en el OnClick de un boton que es el que va a Actualizar los puertos (Es el que va a hacer la funcion de Encender y Apagar los puertos selecccionados)...

Espero que le sea de Utilidad .

[Saludos]...

escafandra 02-04-2009 14:27:55

He investigado el tema de leer y escribir en los puertos, dada la peculiar dificultad en XP que obliga al uso de librerías externas o al uso de drivers.

Voy a colocar un código que funciona sin librerías ni drivers. El único requisito es que seamos Administradores del sistema. Con un driver funciona sin ser administradores, pero para instalar dicho driver si debemos tener esos privilegios.

El truco está en usar una API poco conocida y que se usa para los Debuggers: ZwSystemDebugControl.

Código:

//---------------------------------------------------------------------------
#pragma hdrstop

//---------------------------------------------------------------------------
#pragma argsused

//------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>

//#pragma comment(lib, "advapi32")
//#pragma link "advapi32.lib"

#define NTAPI      __stdcall

typedef int NTSTATUS;

typedef enum _SYSDBG_COMMAND
{
  SysDbgSysReadIoSpace = 14,
  SysDbgSysWriteIoSpace = 15
}SYSDBG_COMMAND, *PSYSDBG_COMMAND;

typedef NTSTATUS (NTAPI * PZwSystemDebugControl) (
    SYSDBG_COMMAND ControlCode,
    PVOID InputBuffer,
    ULONG InputBufferLength,
    PVOID OutputBuffer,
    ULONG OutputBufferLength,
    PULONG ReturnLength
    );

PZwSystemDebugControl ZwSystemDebugControl = NULL;

typedef struct _IO_STRUCT
{
    DWORD IoAddr;      // IN: Aligned to NumBYTEs,I/O address
    DWORD Reserved1;    // Never accessed by the kernel
    PVOID pBuffer;      // IN (write) or OUT (read): Ptr to buffer
    DWORD NumBYTEs;    // IN: # BYTEs to read/write. Only use 1, 2, or 4.
    DWORD Reserved4;    // Must be 1
    DWORD Reserved5;    // Must be 0
    DWORD Reserved6;    // Must be 1
    DWORD Reserved7;    // Never accessed by the kernel
}
IO_STRUCT, *PIO_STRUCT;

BOOL EnablePrivilege (PCSTR name)
{
    HANDLE hToken;
    TOKEN_PRIVILEGES priv = {1, {0, 0, SE_PRIVILEGE_ENABLED}};

    LookupPrivilegeValue(0, name, &priv.Privileges[0].Luid);
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
    AdjustTokenPrivileges (hToken, FALSE, &priv, sizeof priv, 0, 0);
    CloseHandle (hToken);

    return (GetLastError() == ERROR_SUCCESS);
}

BOOL Inicializa()
{
    HMODULE hNtdll;
    hNtdll = LoadLibrary ("ntdll.dll");

    if(EnablePrivilege(SE_DEBUG_NAME)==FALSE){
      printf("Usted no tiene suficientes privilegios\n");
      return FALSE;
    }

    if(hNtdll){
      ZwSystemDebugControl = (PZwSystemDebugControl)GetProcAddress(hNtdll, "ZwSystemDebugControl");
      return TRUE;
    }
    return FALSE;
}

BYTE InPortB(int Port)
{
    BYTE Value;
    IO_STRUCT io;

    io.IoAddr = Port;
    io.Reserved1 = 0;
    io.pBuffer = (PVOID)(PULONG)&Value;
    io.NumBYTEs = sizeof(BYTE);
    io.Reserved4 = 1;
    io.Reserved5 = 0;
    io.Reserved6 = 1;
    io.Reserved7 = 0;

    ZwSystemDebugControl(SysDbgSysReadIoSpace, &io, sizeof(io), NULL, 0, NULL);
    return Value;
}

void OutPortB(int Port, BYTE Value)
{
    IO_STRUCT io;
   
    io.IoAddr = Port;
    io.Reserved1 = 0;
    io.pBuffer = (PVOID)(PULONG)&Value;
    io.NumBYTEs = sizeof(BYTE);
    io.Reserved4 = 1;
    io.Reserved5 = 0;
    io.Reserved6 = 1;
    io.Reserved7 = 0;
   
    ZwSystemDebugControl(SysDbgSysWriteIoSpace, &io, sizeof(io), NULL, 0, NULL);
};

void BeepOn (int Freq)
{
    BYTE b;

    if((Freq >= 20) && (Freq <= 20000)){
        Freq = 1193181 / Freq;
        b = InPortB(0x61);
        if((b & 3) == 0){
          OutPortB (0x61, (BYTE) (b | 3));
          OutPortB (0x43, 0xb6);
        }
        OutPortB (0x42, (BYTE)Freq);
        OutPortB (0x42, (BYTE)(Freq >> 8));
    }
}

void BeepOff (void)
{
    BYTE b;

    b = (InPortB(0x61) & 0xfc);
    OutPortB(0x61, b);
}

// Sólo funciona en Windows XP y superiores
// Se debe ser Administrador del Sistema
int main(void)
{
    if(Inicializa()==FALSE){
      printf("Error al inicializar los puertos\n");
      Sleep (2000);
      return 0;
    }

    // Aquí podemos utilizar las funciones InPortB y OutPortB

    // Activamos el altavoz del sistema durante 300ms con una frecuencia
    // de 1000Hz
    BeepOn(1000);  // frecuencia de 1000Hz
    Sleep (300);
    BeepOff();

    return 0;
}

La función main demuestra como usar las funciones para activar el altavoz del sistema.

Patra escribir y leer del puerto paralelo, basta con:
Código:

Inicializa();
BYTE B = InPort(0x378);  // Lee del puerto paralelo
OutPort(0x378, 3);      // Escribe en el puerto paralelo el valor 3

Saludos.

krlox31416 04-04-2009 03:48:39

lo malo es que hace tiempo no programo en c
 
interesante codigo!!!...
tendre que conseguirme el c...
jejeje...

saludos!!!...:D

escafandra 04-04-2009 10:27:08

Cita:

Empezado por krlox31416 (Mensaje 343847)
interesante codigo!!!...
tendre que conseguirme el c...
jejeje...

saludos!!!...:D

No necesariamente debe estar escrito en C.

Saludos.


La franja horaria es GMT +2. Ahora son las 09:56:51.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi