Usb Hid Mchid

21
USB_HID MODO HID Este modo es el que utilizan los Mouse USB y los teclados USB, incluso hay ejemplos en la red para simular estos dispositivos, para este modo no es necesario instalar drivers en windows. Haremos un sencillo ejemplo, haremos encender y apagar un LED conectado al pin B0 del PIC, y en el PIC tendremos un botón conectado a B1, el cual al ser pulsado encenderá un Shape en el formulario de Visual Basic. FORMULARIO VISUAL BASIC

Transcript of Usb Hid Mchid

Page 1: Usb Hid Mchid

USB_HID

 

MODO  HID

 Este modo es el que utilizan los Mouse USB y los teclados USB, incluso hay ejemplos en la red para simular estos dispositivos, para este modo no es necesario instalar drivers en windows.

Haremos un sencillo ejemplo, haremos encender y apagar un LED conectado al pin B0 del PIC, y en el PIC tendremos un botón conectado a B1,  el cual al ser pulsado encenderá un Shape en el formulario de Visual Basic.

 

FORMULARIO VISUAL BASIC

 

Page 2: Usb Hid Mchid

 CIRCUITO BASICO USB

 

PROGRAMACION: 

Comenzamos por explicar el código en el PIC, para esto necesitamos el archivo “hid 8-byte” el cual incluyo en el archivo que descargaron, este archivo es necesario para compilar el proyecto,  en este archivo se encuentran definiciones para que el dispositivo sea reconocido por Windows, así como el nombre que queremos que se muestre al conectar el dispositivo  en este caso “USB_HID” también tenemos el VID y el PID los cuales son los identificadores que reconoce Windows, en este caso el VID es 0×0461 y el PID es 0×0020 en el código los marque en rojo para reconocerlos, noten que esta invertidos los bytes es decir en el VID en lugar de decir:  0×04, 0×61, dice: 0×61,0×04.

 

 

////////////////////////////////////////////////////////////////////////   start device descriptors

Page 3: Usb Hid Mchid

/////////////////////////////////////////////////////////////////////

constchar USB_DEVICE_DESC[USB_DESC_DEVICE_LEN] ={//starts of with device configuration. only one possibleUSB_DESC_DEVICE_LEN, //the length of this report   ==10×01, //the constant DEVICE (DEVICE 0×01)  ==20×10,0×01, //usbversionin bcd(pic167xx is 1.1) ==3,40×00, //class code ==50×00, //subclass code ==60×00, //protocol code ==7USB_MAX_EP0_PACKET_LENGTH, //max packet size for endpoint 0. (SLOW SPEED SPECIFIES 8 ) ==80×61,0×04, //vendor id (0x04D8 is Microchip, or is it 0×0461 ??)0×20,0×00,//product id   ==11,12  //don’t use ffffsays usb-by-example guy.  oops0×00,0×01, //device release number  ==13,140×01, //index of string description of manufacturer. therefore we point to string_1 array (see below)  ==150×02, //index of stringdescriptor of the product  ==160×00, //index of stringdescriptor of serial number  ==17USB_NUM_CONFIGURATIONS  //number of possible configurations  ==18};

 

 

Para cambiar el nombre del dispositivo debemos tener en cuenta varias cosas, la primera es la parte que puse en azul en ella se indica en donde están los índices de cada palabra que ponemos, pero lo que nos importa esta después del índice 4 que es la palabra “Ezkybel” y “USB_HID”  por ejemplo la palabra “Ezkybel” tiene 7 letras pero como a toda letra le agregamos un “0”( “’E’,0,”) entonces la longitud de esa palabra será de 14 bytes y le sumamos 2 bytes mas por lo que nuestra palabra será de 16 bytes, es por eso que  {0,4,20} significa que la primer palabra de configuración comienza en el índice 0 y es: “0×09,0×04, “   luego la segunda palabra (“Ezkybel”) comienza en el índice 4, y la tercera palabra “USB_HID” comienza en el índice 20.

char USB_STRING_DESC_OFFSET[ ={0,4,20};

char const USB_STRING_DESC[]={//string 04, //length of string indexUSB_DESC_STRING_TYPE, //descriptor type 0×03 (STRING)0×09,0×04,   //Microsoft Defined for US-English//string 116, //length of string indexUSB_DESC_STRING_TYPE, //descriptor type 0×03 (STRING)

Page 4: Usb Hid Mchid

‘E’,0,‘z’,0,‘k’,0,‘y’,0,‘b’,0,‘e’,0,‘l’,0,//string 216, //length of string indexUSB_DESC_STRING_TYPE, //descriptor type 0×03 (STRING)‘U’,0,‘S’,0,‘B’,0,‘_’,0,‘H’,0,‘I’,0,‘D’,0,

 

la modificacion de este archivo solo es nesesaria para cuando queremos cambiar de VID y/o de PID pero pueden dejarla asi sin problema alguno.

La programacion de su aplicacion esta en el archivo llamado “USB_HID.c” en el cual escribiran su programa especifico, ahi comente lo mas importante, pero aqui menciono las funciones mas importantes

 

 

//********************************************************************//                      Ejemplo en USB HID//// www.wix.com/ezkybel/electronica//********************************************************************

#include <18F2550.h>#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN#use delay(clock=48000000) // siempre ponemos (48000000)

// CCS Library dynamic defines#DEFINE USB_HID_DEVICE  TRUE //Tells the CCS PIC USB firmware to include HID handling code.#define USB_EP1_TX_ENABLE  USB_ENABLE_INTERRUPT   //turn on EP1 for

Page 5: Usb Hid Mchid

IN bulk/interrupt transfers#define USB_EP1_TX_SIZE    8 //Numero de byte de envio (maximo 64 bytes)#define USB_EP1_RX_ENABLE  USB_ENABLE_INTERRUPT   //turn on EP1 for OUT bulk/interrupt transfers#define USB_EP1_RX_SIZE    8 //Numero de byte de Recepcion (maximo 64 bytes)

// CCS USB Libraries#include <pic18_usb.h>   //Microchip 18Fxx5x hardware layer for usb.c#include <hid 8-byte.h>   //USB Configuration and Device descriptors for this UBS device#include <usb.c>        //handles usb setup tokens and get descriptor reports

void main() {int8 in_data[8];  //Declaramos la variable de entrada y su tamañano de 8 bytesint8 out_data[8]; //Declaramos la variable de salida y su tamañano de 8 bytes

usb_init(); // inicializa el modulo USB.while(1){usb_task();if (usb_enumerated()){ // si windows reconocio el dispositivo.if (usb_kbhit(1)) { // Si el pic recibio algun dato de la PCusb_get_packet(1, in_data, ;// Guarda en in_data los datos de la PCif (in_data[0]==0xAA){     // si el dato recibido fue 0xAAoutput_high(pin_B0);    // Enciende el LED en B0}if (in_data[0]==0×66){     // si el dato recibido fue 0×66output_low(pin_B0);     // Apaga el LED en B0}}

if (input(pin_B1)){   // Si se presiono el boton out_data[0]=0×55;  // out_data[0]= 0×55usb_put_packet(1, out_data, 8, USB_DTS_TOGGLE); // lo enviamos por USB a la PC}} }}

 

Lo mas importante lo puse en rojo y lo que esta en verde siempre debe ir al igual que la configuracion del PIC como es el reloj a 48Mhz, aunque usemos un cristal de 20 Mhz, al momento de grabar nuestro pic debemos decirle en las configuraciones del programa que lo graba que divida el reloj para obtener 4Mhz, lo que hace es que configura en el PIC un divisor de frecuencia para obtener 4Mhz del cristal que usemos, posteriormente un PLL aumenta esa frecuencia a 48 Mhz, por eso es que trabajaremos siempre 48Mhz, pero eso ya lo hace el programa del grabador sin embargo es importante que se configure bien.

Page 6: Usb Hid Mchid

 

 

 Ejemplo de configuracion del divisor en mi grabador en este caso tengo un cristal de 20Mhz

 

En la parte:#define USB_EP1_TX_SIZE    8#define USB_EP1_RX_SIZE    8int8 out_data[8];int8 in_data[8];se define el tamaño buffer de recepcion y del de transmision en este caso son 8 bytes cada uno. si se cambian aqui habria que cambiarlo tambien en visual basic.

Estas dos funciones siempre deben ir y son para inicializar el puerto y ponerlo a funcionar.usb_init();usb_task();

En nuestro ejemplo manejamos dos arrays in_data[x]  y  out_data[x], cada uno de ellos de 8 bytes, la “x” representa el indice de cada array,en nuestro ejemplo solo utilizaremos un byte de cada array para enviar datos y leer los recibidos, pero podemos trabajar asi, en este caso serán  in_data[0]  y out_data[0], si ustedes quieren trabajar con mas datos no hay problema pero recuerden que ente caso solo tenemos de limite 8 bytes.

“if(usb_enumerated())”  Es para saber si se ha reconocido el dispositivo por la PC“if (usb_kbhit(1)) “   Es para saber si se ha recibido un dato desde el PC

Page 7: Usb Hid Mchid

 Y estas son las dos principales funciones de envio y recepcion

 

Para recibir datos:

el formato es este:    usb_get_packet(1, array para guardar datos, numero de datos a recibir);

ejemplo:

usb_get_packet(1, in_data, 8);

note que unque solo utilizamos un byte para nuestro ejemplo debemos pedir los 8 para evitar errores.

 

Para transmitir datos:

el formato es este:    usb_put_packet(1, array para enviar datos, numero de datos a enviar,USB_DTS_TOGGLE);

ejemplo:

usb_put_packet(1, out_data, 8, USB_DTS_TOGGLE);

para ambos casos solo modificaremos la parte en rojo, el “1″ significa el endpoint del arreglo, por lo tanto siempre sera el mismo (un 1), tampoco modificarems   “USB_DTS_TOGGLE”

En nuestro ejemplo si presionamos el boton por B1, enviaremos a la PC el dato “”0×55″ por medio de out_data[0], y estara esperando que le envien datos el cual guardara en in_data[0], si el dato que envia la PC es “0xAA” encendera el LED, pero si envia “0×66″ entonces lo apagara,estos datos pueden ser cualquier valor de 0a 255.

 

VISUAL BASIC

Se puede hacer el programa en diferentes lenguajes (Visual Basic.net, Visual C++, Visual C#, etc) sin ambago aqui solo veremos en visual basic, yo no tengo ejemplos en otros lenguajes y elegi este por que hay muchos ejemplos para manejar este entorno. nesecitaremos un modulo .bas llamado “mcHIDInterface.bas” el cual viene incluido en los

Page 8: Usb Hid Mchid

archivos que descargaste,  la plantilla que utilizo para hacer aplicaciones HID en Visual Basic esta comentada totalmente (en ingles), por lo que solo explicare lo mas importante.

 ENVIO

Aqui vemos como se envian datos al PIC por  USB, tenemos el codigo de los dos botones usado en este ejemplo uno de ellos apaga el led y el otro lo enciende.

Private Sub Command1_Click()    BufferOut(1) = &HAA    hidWriteEx VendorID, ProductID, BufferOut(0)End Sub

Private Sub Command2_Click()   BufferOut(1) = &H66   hidWriteEx VendorID, ProductID, BufferOut(0)End Sub

 Explicacionponemos en  BufferOut(1)  el dato 0xAABufferOut(1) = &HAA  

y con la siguiente funcion sacamos el dato por USB  a esta funcion no le cambiamos nada,hidWriteEx VendorID, ProductID, BufferOut(0)

 RECEPCION

Esta funcion es la que se encarga de recibir datos y guardarlos en el array  “BufferIn”

‘*****************************************************************‘ on read event…‘*****************************************************************Public Sub OnRead(ByVal pHandle As Long)     ‘ read the data (don’t forget, pass the whole array)…   If hidRead(pHandle, BufferIn(0)) Then      ‘ ** YOUR CODE HERE **      ‘ first byte is the report ID, e.g. BufferIn(0)      ‘ the other bytes are the data from the microcontrolller…   End IfEnd Sub

Page 9: Usb Hid Mchid

pero ya esta definida en la plantilla por lo que no tenemos que preocuparnos por hacerla, solo leemos el byte que nos interesa en este caso “BufferIn(1)”, podemos leer el arreglo en cualquier momento y lugar de el codigo, pues esta funcion es como una interrupcion.

en el ejemplo lo leemos desde un timer “Timer1″ el cual esta configurado en intevalos de 100 ms.

Private Sub Timer1_Timer()                  ‘ Si lo que envio el PIC es “0×55″  If BufferIn(1) = &H55 Then     Shape1.BackColor = &HFF00&        ‘cambia el color de “Shape1″  Else    Shape1.BackColor = &H4000&          ‘cambia el color de “Shape1″  End If BufferIn(1) = 0End Sub

Nota.

Algo en lo que debemos tener cuidado es que en visual basic, la variable de el array de recepcion como de transmision siempre sera mayor en1 alos indices de los array en el PIC por ejemplo si enviamos desde el pic el dato “0xFF”  por la variable out_data[0],seria asi:

out_data[0]=0xFF;usb_put_packet(1, out_data, 8, USB_DTS_TOGGLE);

y en visual basic lo recibimos en el indice 1 , quedaria asi:

If BufferIn(1) = &HFF  ThenEnd   If

De igual manera al enviar un dato de V. Basic a la variable in_data[0] del PIC se haria de esta manera:

si le enviamos el dato 0xFF al arreglo seria asi:

BufferOut(1) = &HFFhidWriteEx VendorID, ProductID, BufferOut(0)

y el PIC lo recibiria asi:

if (in_data[0]==0xFF)

 Por ultimo compilan el codigo del PIC y el archivo .hex generado, lo graban cuidando la configuracion de su cristal como lo mencione anteriormente para que le pueda funcionar, tambien lo pueden simular en Proteus con el  USB Virtual y la PC lo detectara como si estuvieran realmente conectando un dispositivo fisicamente.

Page 10: Usb Hid Mchid

Al conectar su pic a la PC debera salir la siguiete notificacion como cuando conectan un dispositivo nuevo.

 Descarga del proyecto:

——->USB_HID_Ezkybel.zip<——–

    Saludos…

 

14 Responses to “USB_HID”

Janet Benites:

October 25, 2010 at 6:55 pm

Felicidades por un paso mas en tu escalalera, y que tu lucha nunca cese para que logres tus objetivos; estamos contigo siempre y en cada momento, gracias por nunca dejar de sorprendernos y por que eres un orgullo para nosotras. TE AMO.

Reply

Arturo:

October 30, 2010 at 7:17 pm

Este aporte está muy bien explicado. Gracias por tan buen proyecto para aprendisaje. Lo voy a armar y ya dire como me fue. Gracias

Reply

Luis:

Page 11: Usb Hid Mchid

December 22, 2010 at 3:45 pm

Hola ezkybel, gracias por tus aportes, me impresiona lo que se puede hacer con los microcontroladores, yo tengo conocimientos basicos (ya que voy empezando) de la programacion, estoy utilizando el lenguaje PBP, pero ando buscando informacion de como utilizar la programacion en C ya que me llama la atencion de como se utiliza no se si sea dificil de entender (aunque no lo e utlizado) aunque los temas que publicaste lo hacen ver sencillo de emplear y bueno los aportes que das me ayudan mucho en esto que comento, vi lo publicado con un termostato y me quede impresionado ahora estoy leyendo este del USB, no pensaba que se pudiera hacer esto con este lenguaje. Gracias por tus aportes.Saludos desde México!

Reply

Ezkybel:

December 22, 2010 at 3:56 pm

Hola Luis, claro que se puede hacer, de hecho y comence a trabajar con PBP y HID, con un programa llamado “Easy HID” si te fijas el codigo en visual basic que posteo esta generado con este programa, es decir combiné la parte de visual basic con la programacion en CCS, y no es dificil entender este lenguaje, yo me mude de PBP a CCS por que se me hizo mejor lenguaje, pero sin embargo estuve trabajando mucho con PBP, lo bueno de CCS es que hay infinidad de ejemplos y tutoriales en la red hacerca de este lenguaje y lo que yo presento en esta pagina son aplicaciones, te invito a leer el nuevo proyecto “Ceradura con tarjetas telefonicas” es un ejemplo mas real creativo y sencillo que los otros dos que ya publique.

Saludos tambien desde Mexico (S.L.P) Luis.

Reply

Nextar:

August 6, 2011 at 1:03 pm

Ketal Ezkybel, primero que nada felicitarte por tus aportes.bien.. te escribo por que en la parte de oscilador no entiendo muy bien. Por que? el reloj siempre lo debemos poner a 48Mhz cuando en realidad es de 20Mhz; si entiendo la función que hace el PLL y si por ejemplo pongo un xtal de 20Mhz y el PLL lo divide entre 5, tendré los 4Mhz los cuales son los que necesito para usar el (USB clock selection) para que el pic divida los 96Mhz entre 2 y asi obtendría los

Page 12: Usb Hid Mchid

48Mhz que necesita el pic para que pueda funcionar el usb..y pues es aquí mi duda por que se debe configurar el reloj a 48Mhz y no a 20Mhz? aun así no me queda claro.

otra cosa quisiera saber si me puedes ayudar.. lo que quiero hacer es: recibir una cadena de caracteres por el puerto serial ya sea con el 18F2550 o con el 18F4550 y posteriormente enviar esos mismos datos a una aplicación en la pc vía usb.

La aplicación de visual basic ya la hice, y en un principio utilice el codigo de ejemplo de CCS (ex_usb_hid.c) en el cual lee un puerto analógico y el estado de un push button, la modificación que hice fue quitar la rutina del ADC y el testeo del push button y en lugar de ellos poner una rutina que tome los datos por el puerto serial con [gets(buffer); ] y posteriormente enviarlo via usb con [ out_data[0] =buffer[0]; ] donde buffer va desde 0 hasta la longitud de mi cadena de caracteres (son 10 en total). la velocidad que utilizo es de 2400 baudios con un cristal de 20Mhz y aquí el problema, todo esto ya lo simule en proteus y todo funciona perfecto pero implementado físicamente no funciona. lo único que puedo recibir es la primer cadena de caracteres que llega al pic y claro la muestra en la pc correctamente pero despues de eso ya no regresa a tomar la siguiente cadena de caracteres la cual nunca es la misma.También ya lo hice con tu código e igual en la simulación todo funciona perfectamente pero físicamente no lo hace, pareciera que el programa se queda “colgado” y pues yo no creo que sea eso por que no se pierde la conexión usb con la pc.es por eso que te pido ayuda haber si me puedes ayudar.. por lo menos tomar un dato por el puerto serie del pic y enviar ese mismo dato a la pc.

no se como subir mi código o la simulación en proteus para que sea mas fácil de entender lo que quiero hacer

bueno espero que me puedas ayudar la verdad ya tengo meses con esto y no encuentro solución por ningún lado.

Reply

o Ezkybel:

August 6, 2011 at 11:19 pm

Hola Nextar, mira en cuanto a lo de la frecuencia de los 48 Mhz debo confesarte que no lo he hestudiado bien pero estuve estudiando sobre el tema en esta pagina la cual te recomiendo: http://picmania.garcia-cuervo.net/conceptos.php#USB4Mhz , debo decirte que yo jamas cambio los valores en el codigo de CCS es decir siempre lo pongo a 48Mhz segun entendi hay un postscaler el cual vuelve a configurar

Page 13: Usb Hid Mchid

la frecuencia para el programa, pero no tuve mucho tiempo de leerlo, espero que si logras entenderlo mejo no lo expliques por favor te lo agradeceria.

En cuanto a el problema de tu programa con la comunicacion serial se me hace algo raro, si quieres enviame a mi correo tu programa para analizarlo y ayudarte mejormi correo es: [email protected]

saludos

Reply

Nextar:

August 9, 2011 at 9:50 pm

Hola ketal Ezkybel, primero que nada pues agradecerte por tu pronta respuesta..

En cuanto a lo del cristal a utilizar y a la selección de la frecuencia de reloj ya me quedo claro y aquí la explicación espero poder darme a entender.

Primero que nada podría decirse que el microcontrolador va a trabajar con dos frecuencias en caso de que utilicemos el modulo USB ya sea, que sean iguales o no. Por lo tanto el valor que pongamos en esta directiva “#use delay(clock=48000000)” no corresponde al valor del cristal, sino a la frecuencia a la que trabajara el microcontrolador; la cual estará determinada por la directiva CPUDIV, la función de este postcaler es tomar la frecuencia del PLL de 96Mhz y dividirla ya sea en 2,3,4 o 6 y esta será finalmente la frecuencia a la que estarán ejecutando las instrucciones el microcontrolador. En el caso de que se configure como CPUDIV1 se le estará indicando al microcontrolador que la frecuencia de reloj será de 48Mhz “96Mhz/2”; paralelo a ello, la misma frecuencia proveniente del PLL de 96Mhz es dividida automáticamente por 2, y utilizando la directiva USBDIV tomara esta frecuencia que será de 48Mhz para la operación del modulo USB.

Como conclusión se puede decir que si se tiene como ejemplo un cristal de 8Mhz la configuración de bits será la siguiente:

#fuses HSPLL,PLL2,USBDIV,CPUDIV2,…

Con HSPLL estaremos indicando que utilizaremos el un cristal de alta frecuencia y el PLL PrescalerCon PLL2 dividimos la frecuencia del cristal de 8Mhz en 2 para obtener 4Mhz que son necesarios para el PLL de 96Mhz, para obtener 96Mhz el cual tomara dos caminos:

Page 14: Usb Hid Mchid

1.- Con USBDIV se estarán tomando 48Mhz (96Mhz/2) para el uso del modulo USB2.- Con CPUDIV2 se estará indicando que la frecuencia de reloj será de 32Mhz (en la hoja de datos CPUDIV2 . corresponde a dividir la frecuencia del PLL de 96Mhz entre 3 lo que nos da como resultado 32Mhz). Lo que . finalmente será este dato lo que pondremos en la siguiente instrucción:

#use delay(clock=32000000)

Y es aquí donde les comentaba que el microcontrolador puede estar trabajando a frecuencias “diferentes” 48Mhz para el funcionamiento del USB y 32Mhz para la ejecución de sus instrucciones.

Espero haberme dado a entender… además de que esto me resolvió varios problemas que tenia en la conexión USB.Por otro lado..voy a ordenar mis programas e información de lo que pretendo hacer y te lo mando a tu correo, espero que con tu ayuda pueda sacar este pequeño proyecto.De antemano muchas gracias

Saludos desde Puebla

Reply

o Ezkybel:

August 10, 2011 at 6:18 am

Al contrario gracias por la respuesta y la aclaracion de la duda en cuanto al cristal, tu respuesta es muy clara y entendible, y enviame tu codigo para checarlo, he trabajado mucho con el puerto serial y me ha funcionado bien, espero poder ayudare, antes de eso recorde que tuve un problema similar que me dio muchos dolores de cabeza ya que en la simulacion funcionaba perfectamente pero en mi caso no era un proyecto de comunicacion sino mas bien era un programa que variaba la tension altena por medio de unos triacs ademas de eso tenia un ventilador de 12 V y cuando este encencia hacia que se reiniciara el microcontrolador, “el problema” era que los pics tienen una funcion muy util para casos de inestabilidad de la alimentacion, asi que cuando el motor arrancaba consumia mucha corriente y como el eliminador que tenia era de poca corriente le afectaba al micro, para deshabilitar esta funcion el PIC tiene un fusible llamado “BROWN OUT DETECT”, quisa sea tu problema, puedes probar deshabilitandolo.

Saludos

Page 15: Usb Hid Mchid

Reply

Nextar:

August 20, 2011 at 6:05 pm

ketal ezkybel, ya dashabilite el fusible que me dijiste ya también estuve analizando la configuración de bits y nada..ya te envié a tu correo el código que tengo espero que me puedas ayudar..gracias.. buen día

Reply

o Ezkybel:

August 23, 2011 at 6:53 am

Hoy lo voy a checar

Reply

Crs:

September 26, 2011 at 4:17 pm

Muy buen ejemplo, tengo una duda si tengo una entrada analógica AN0 como puedo desplegar el valor an tu programa de vb? Gracias y saludos.

Reply

o Ezkybel:

September 26, 2011 at 4:23 pm

Claro que si se puede, basicamente es esto: lees al ADC, lo pones en una variable de 8 bits o en dos bytes, y lo(s) envias por el puerto USB, lo recojes con visual basic, y haces las operaciones corespondientes segun lo que quieras leer, y lo muestras, y asi haces un ciclo infinito.

Page 16: Usb Hid Mchid

cualquier duda comentamela y si hay tiempo te ayudaresaludos

Reply

JUAN:

March 13, 2012 at 5:42 pm

Amigo me marca error en el compilador, la compilacion la estoy haciendo en PIC C. Me podrias decir cual es mi error o si tengo que pegar algun archivo en algun directorio de mi ordenador?

Reply

o Ezkybel:

March 13, 2012 at 8:55 pm

Hola quiza tu error sea, por que la compilacion la hice con PCWHD y tu lo estas haciendo con otro compilador,saludos

Reply