Control de dispositivos a través del módulo USB del PIC18F45/2550

Hola Moyano mil gracias por lo que nos das, sos un capo, estoy capturando datos con el CAD del micro y mandando a la PC para que los grafique, pero las lecturas son muy lentas, estoy usando un ejemplo tuyo de HID (el de los 8 rele, 3entradas y el CAD), tendrias algun ejemplo con el que pueda capturar los datos mucho mas rapido?, tengo que presentar en la U un osciloscopio, gracias
 
@guillerusso hola como estás, mirá dale una mirada a este proyecto de fin de carrera: http://pablohoffman.com/cgi-bin/twiki/bin/view/Oscusb/WebHomehttps://www.forosdeelectronica.com/miembros/85276-guillerusso/

Bueno acá les pongo 2 funciones importantes dentro del programa anterior. La primera me devuelve un valor del tipo bool ( 1 o 0 ) que me dice si el dispositivo , que coincide con el VID y PID descripto en el programa está conectado fisicamente con el handler o "manejador".
Código:
bool CheckIfPresentAndGetUSBDevicePath()
        {
            /* 
            Before we can "connect" our application to our USB embedded device, we must first find the device.
            A USB bus can have many devices simultaneously connected, so somehow we have to find our device only.
            This is done with the Vendor ID (VID) and Product ID (PID).  Each USB product line should have
            a unique combination of VID and PID.  

            Microsoft has created a number of functions which are useful for finding plug and play devices.  Documentation
            for each function used can be found in the MSDN library.  We will be using the following functions (unmanaged C functions):

            SetupDiGetClassDevs()                    //provided by setupapi.dll, which comes with Windows
            SetupDiEnumDeviceInterfaces()            //provided by setupapi.dll, which comes with Windows
            GetLastError()                            //provided by kernel32.dll, which comes with Windows
            SetupDiDestroyDeviceInfoList()            //provided by setupapi.dll, which comes with Windows
            SetupDiGetDeviceInterfaceDetail()        //provided by setupapi.dll, which comes with Windows
            SetupDiGetDeviceRegistryProperty()        //provided by setupapi.dll, which comes with Windows
            CreateFile()                            //provided by kernel32.dll, which comes with Windows

            In order to call these unmanaged functions, the Marshal class is very useful.
             
            We will also be using the following unusual data types and structures.  Documentation can also be found in
            the MSDN library:

            PSP_DEVICE_INTERFACE_DATA
            PSP_DEVICE_INTERFACE_DETAIL_DATA
            SP_DEVINFO_DATA
            HDEVINFO
            HANDLE
            GUID

            The ultimate objective of the following code is to get the device path, which will be used elsewhere for getting
            read and write handles to the USB device.  Once the read/write handles are opened, only then can this
            PC application begin reading/writing to the USB device using the WriteFile() and ReadFile() functions.

            Getting the device path is a multi-step round about process, which requires calling several of the
            SetupDixxx() functions provided by setupapi.dll.
            */

            try
            {
                IntPtr DeviceInfoTable = IntPtr.Zero;
                SP_DEVICE_INTERFACE_DATA InterfaceDataStructure = new SP_DEVICE_INTERFACE_DATA();
                SP_DEVICE_INTERFACE_DETAIL_DATA DetailedInterfaceDataStructure = new SP_DEVICE_INTERFACE_DETAIL_DATA();
                SP_DEVINFO_DATA DevInfoData = new SP_DEVINFO_DATA();

                uint InterfaceIndex = 0;
                uint dwRegType = 0;
                uint dwRegSize = 0;
                uint dwRegSize2 = 0;
                uint StructureSize = 0;
                IntPtr PropertyValueBuffer = IntPtr.Zero;
                bool MatchFound = false;
                uint ErrorStatus;
                uint LoopCounter = 0;

                //Use the formatting: "Vid_xxxx&Pid_xxxx" where xxxx is a 16-bit hexadecimal number.
                //Make sure the value appearing in the parathesis matches the USB device descriptor
                //of the device that this aplication is intending to find.
                String DeviceIDToFind = "Vid_04d8&Pid_003f";

                //First populate a list of plugged in devices (by specifying "DIGCF_PRESENT"), which are of the specified class GUID. 
                DeviceInfoTable = SetupDiGetClassDevs(ref InterfaceClassGuid, IntPtr.Zero, IntPtr.Zero, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

                if(DeviceInfoTable != IntPtr.Zero)
                {
                    //Now look through the list we just populated.  We are trying to see if any of them match our device. 
                    while(true)
                    {
                        InterfaceDataStructure.cbSize = (uint)Marshal.SizeOf(InterfaceDataStructure);
                        if(SetupDiEnumDeviceInterfaces(DeviceInfoTable, IntPtr.Zero, ref InterfaceClassGuid, InterfaceIndex, ref InterfaceDataStructure))
                        {
                            ErrorStatus = (uint)Marshal.GetLastWin32Error();
                            if (ErrorStatus == ERROR_NO_MORE_ITEMS)    //Did we reach the end of the list of matching devices in the DeviceInfoTable?
                            {    //Cound not find the device.  Must not have been attached.
                                SetupDiDestroyDeviceInfoList(DeviceInfoTable);    //Clean up the old structure we no longer need.
                                return false;        
                            }
                        }
                        else    //Else some other kind of unknown error ocurred...
                        {
                            ErrorStatus = (uint)Marshal.GetLastWin32Error();
                            SetupDiDestroyDeviceInfoList(DeviceInfoTable);    //Clean up the old structure we no longer need.
                            return false;    
                        }

                        //Now retrieve the hardware ID from the registry.  The hardware ID contains the VID and PID, which we will then 
                        //check to see if it is the correct device or not.

                        //Initialize an appropriate SP_DEVINFO_DATA structure.  We need this structure for SetupDiGetDeviceRegistryProperty().
                        DevInfoData.cbSize = (uint)Marshal.SizeOf(DevInfoData);
                        SetupDiEnumDeviceInfo(DeviceInfoTable, InterfaceIndex, ref DevInfoData);

                        //First query for the size of the hardware ID, so we can know how big a buffer to allocate for the data.
                        SetupDiGetDeviceRegistryProperty(DeviceInfoTable, ref DevInfoData, SPDRP_HARDWAREID, ref dwRegType, IntPtr.Zero, 0, ref dwRegSize);

                        //Allocate a buffer for the hardware ID.
                        //Should normally work, but could throw exception "OutOfMemoryException" if not enough resources available.
                        PropertyValueBuffer = Marshal.AllocHGlobal((int)dwRegSize);

                        //Retrieve the hardware IDs for the current device we are looking at.  PropertyValueBuffer gets filled with a 
                        //REG_MULTI_SZ (array of null terminated strings).  To find a device, we only care about the very first string in the
                        //buffer, which will be the "device ID".  The device ID is a string which contains the VID and PID, in the example 
                        //format "Vid_04d8&Pid_003f".
                        SetupDiGetDeviceRegistryProperty(DeviceInfoTable, ref DevInfoData, SPDRP_HARDWAREID, ref dwRegType, PropertyValueBuffer, dwRegSize, ref dwRegSize2);

                        //Now check if the first string in the hardware ID matches the device ID of the USB device we are trying to find.
                        String DeviceIDFromRegistry = Marshal.PtrToStringUni(PropertyValueBuffer); //Make a new string, fill it with the contents from the PropertyValueBuffer

                        Marshal.FreeHGlobal(PropertyValueBuffer);        //No longer need the PropertyValueBuffer, free the memory to prevent potential memory leaks

                        //Convert both strings to lower case.  This makes the code more robust/portable accross OS Versions
                        DeviceIDFromRegistry = DeviceIDFromRegistry.ToLowerInvariant();    
                        DeviceIDToFind = DeviceIDToFind.ToLowerInvariant();                
                        //Now check if the hardware ID we are looking at contains the correct VID/PID
                        MatchFound = DeviceIDFromRegistry.Contains(DeviceIDToFind);        
                        if(MatchFound == true)
                        {
                            //Device must have been found.  In order to open I/O file handle(s), we will need the actual device path first.
                            //We can get the path by calling SetupDiGetDeviceInterfaceDetail(), however, we have to call this function twice:  The first
                            //time to get the size of the required structure/buffer to hold the detailed interface data, then a second time to actually 
                            //get the structure (after we have allocated enough memory for the structure.)
                            DetailedInterfaceDataStructure.cbSize = (uint)Marshal.SizeOf(DetailedInterfaceDataStructure);
                            //First call populates "StructureSize" with the correct value
                            SetupDiGetDeviceInterfaceDetail(DeviceInfoTable, ref InterfaceDataStructure, IntPtr.Zero, 0, ref StructureSize, IntPtr.Zero);
                            //Need to call SetupDiGetDeviceInterfaceDetail() again, this time specifying a pointer to a SP_DEVICE_INTERFACE_DETAIL_DATA buffer with the correct size of RAM allocated.
                            //First need to allocate the unmanaged buffer and get a pointer to it.
                            IntPtr pUnmanagedDetailedInterfaceDataStructure = IntPtr.Zero;  //Declare a pointer.
                            pUnmanagedDetailedInterfaceDataStructure = Marshal.AllocHGlobal((int)StructureSize);    //Reserve some unmanaged memory for the structure.
                            DetailedInterfaceDataStructure.cbSize = 6; //Initialize the cbSize parameter (4 bytes for DWORD + 2 bytes for unicode null terminator)
                            Marshal.StructureToPtr(DetailedInterfaceDataStructure, pUnmanagedDetailedInterfaceDataStructure, false); //Copy managed structure contents into the unmanaged memory buffer.

                            //Now call SetupDiGetDeviceInterfaceDetail() a second time to receive the device path in the structure at pUnmanagedDetailedInterfaceDataStructure.
                            if (SetupDiGetDeviceInterfaceDetail(DeviceInfoTable, ref InterfaceDataStructure, pUnmanagedDetailedInterfaceDataStructure, StructureSize, IntPtr.Zero, IntPtr.Zero))
                            {
                                //Need to extract the path information from the unmanaged "structure".  The path starts at (pUnmanagedDetailedInterfaceDataStructure + sizeof(DWORD)).
                                IntPtr pToDevicePath = new IntPtr((uint)pUnmanagedDetailedInterfaceDataStructure.ToInt32() + 4);  //Add 4 to the pointer (to get the pointer to point to the path, instead of the DWORD cbSize parameter)
                                DevicePath = Marshal.PtrToStringUni(pToDevicePath); //Now copy the path information into the globally defined DevicePath String.
                                
                                //We now have the proper device path, and we can finally use the path to open I/O handle(s) to the device.
                                SetupDiDestroyDeviceInfoList(DeviceInfoTable);    //Clean up the old structure we no longer need.
                                Marshal.FreeHGlobal(pUnmanagedDetailedInterfaceDataStructure);  //No longer need this unmanaged SP_DEVICE_INTERFACE_DETAIL_DATA buffer.  We already extracted the path information.
                                return true;    //Returning the device path in the global DevicePath String
                            }
                            else //Some unknown failure occurred
                            {
                                uint ErrorCode = (uint)Marshal.GetLastWin32Error();
                                SetupDiDestroyDeviceInfoList(DeviceInfoTable);    //Clean up the old structure.
                                Marshal.FreeHGlobal(pUnmanagedDetailedInterfaceDataStructure);  //No longer need this unmanaged SP_DEVICE_INTERFACE_DETAIL_DATA buffer.  We already extracted the path information.
                                return false;    
                            }
                        }

                        InterfaceIndex++;    
                        //Keep looping until we either find a device with matching VID and PID, or until we run out of devices to check.
                        //However, just in case some unexpected error occurs, keep track of the number of loops executed.
                        //If the number of loops exceeds a very large number, exit anyway, to prevent inadvertent infinite looping.
                        LoopCounter++;
                        if(LoopCounter == 10000000)    //Surely there aren't more than 10 million devices attached to any forseeable PC...
                        {
                            return false;
                        }
                    }//end of while(true)
                }
                return false;
            }//end of try
            catch
            {
                //Something went wrong if PC gets here.  Maybe a Marshal.AllocHGlobal() failed due to insufficient resources or something.
                return false;    
            }
        }
Luego la otra función se encarga de gestionar las interrupciones que produce windows cuando un dispositivo USB es conectado o desconectado...trabaja en conjunto con la anterior.

Código:
 protected override void WndProc(ref Message m)
        {
            if (m.Msg == WM_DEVICECHANGE)
            {
                if (((int)m.WParam == DBT_DEVICEARRIVAL) || ((int)m.WParam == DBT_DEVICEREMOVEPENDING) || ((int)m.WParam == DBT_DEVICEREMOVECOMPLETE) || ((int)m.WParam == DBT_CONFIGCHANGED))
                {
                    //WM_DEVICECHANGE messages by themselves are quite generic, and can be caused by a number of different
                    //sources, not just your USB hardware device.  Therefore, must check to find out if any changes relavant
                    //to your device (with known VID/PID) took place before doing any kind of opening or closing of handles/endpoints.
                    //(the message could have been totally unrelated to your application/USB device)

                    if (CheckIfPresentAndGetUSBDevicePath())    //Check and make sure at least one device with matching VID/PID is attached
                    {
                        //If executes to here, this means the device is currently attached and was found.
                        //This code needs to decide however what to do, based on whether or not the device was previously known to be
                        //attached or not.
                        if ((AttachedState == false) || (AttachedButBroken == true))    //Check the previous attachment state
                        {
                            uint ErrorStatusWrite;
                            uint ErrorStatusRead;

                            //We obtained the proper device path (from CheckIfPresentAndGetUSBDevicePath() function call), and it
                            //is now possible to open read and write handles to the device.
                            WriteHandleToUSBDevice = CreateFile(DevicePath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
                            ErrorStatusWrite = (uint)Marshal.GetLastWin32Error();
                            ReadHandleToUSBDevice = CreateFile(DevicePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
                            ErrorStatusRead = (uint)Marshal.GetLastWin32Error();

                            if ((ErrorStatusWrite == ERROR_SUCCESS) && (ErrorStatusRead == ERROR_SUCCESS))
                            {
                                AttachedState = true;        //Let the rest of the PC application know the USB device is connected, and it is safe to read/write to it
                                AttachedButBroken = false;
                                StatusBox_txtbx.Text = "Device Found, AttachedState = TRUE";
                            }
                            else //for some reason the device was physically plugged in, but one or both of the read/write handles didn't open successfully...
                            {
                                AttachedState = false;        //Let the rest of this application known not to read/write to the device.
                                AttachedButBroken = true;    //Flag so that next time a WM_DEVICECHANGE message occurs, can retry to re-open read/write pipes
                                if (ErrorStatusWrite == ERROR_SUCCESS)
                                    WriteHandleToUSBDevice.Close();
                                if (ErrorStatusRead == ERROR_SUCCESS)
                                    ReadHandleToUSBDevice.Close();
                            }
                        }
                        //else we did find the device, but AttachedState was already true.  In this case, don't do anything to the read/write handles,
                        //since the WM_DEVICECHANGE message presumably wasn't caused by our USB device.  
                    }
                    else    //Device must not be connected (or not programmed with correct firmware)
                    {
                        if (AttachedState == true)        //If it is currently set to true, that means the device was just now disconnected
                        {
                            AttachedState = false;
                            WriteHandleToUSBDevice.Close();
                            ReadHandleToUSBDevice.Close();
                        }
                        AttachedState = false;
                        AttachedButBroken = false;
                    }
                }
            } //end of: if(m.Msg == WM_DEVICECHANGE)

            base.WndProc(ref m);
        } //end of: WndProc() function

Bueno acá tenemos el nucleo principal del programa este conjunto de instrucciones corre en un hilo de ejecución diferente al del resto del programa...esto se hace para que todas las operaciones de entrada/salida de datos se haga a mayor velocidad.....se podría intentar hacerlas correr en el mismo hilo de ejecución que el programa original pero queda a criterio del programador :unsure:

Código:
private void ReadWriteThread_DoWork(object sender, DoWorkEventArgs e)
        {
            //-------------------------------------------------------------------------------------------------------------------------------------------------------------------
            //-------------------------------------------------------BEGIN CUT AND PASTE BLOCK-----------------------------------------------------------------------------------

            /*This thread does the actual USB read/write operations (but only when AttachedState == true) to the USB device.
            It is generally preferrable to write applications so that read and write operations are handled in a separate
            thread from the main form.  This makes it so that the main form can remain responsive, even if the I/O operations
            take a very long time to complete.

            Since this is a separate thread, this code below executes independently from the rest of the
            code in this application.  All this thread does is read and write to the USB device.  It does not update
            the form directly with the new information it obtains (such as the ANxx/POT Voltage or pushbutton state).
            The information that this thread obtains is stored in atomic global variables.
            Form updates are handled by the FormUpdateTimer Tick event handler function.

            This application sends packets to the endpoint buffer on the USB device by using the "WriteFile()" function.
            This application receives packets from the endpoint buffer on the USB device by using the "ReadFile()" function.
            Both of these functions are documented in the MSDN library.  Calling ReadFile() is a not perfectly straight
            foward in C# environment, since one of the input parameters is a pointer to a buffer that gets filled by ReadFile().
            The ReadFile() function is therefore called through a wrapper function ReadFileManagedBuffer().

            All ReadFile() and WriteFile() operations in this example project are synchronous.  They are blocking function
            calls and only return when they are complete, or if they fail because of some event, such as the user unplugging
            the device.  It is possible to call these functions with "overlapped" structures, and use them as non-blocking
            asynchronous I/O function calls.  

            Note:  This code may perform differently on some machines when the USB device is plugged into the host through a
            USB 2.0 hub, as opposed to a direct connection to a root port on the PC.  In some cases the data rate may be slower
            when the device is connected through a USB 2.0 hub.  This performance difference is believed to be caused by
            the issue described in Microsoft knowledge base article 940021:
            http://support.microsoft.com/kb/940021/en-us 

            Higher effective bandwidth (up to the maximum offered by interrupt endpoints), both when connected
            directly and through a USB 2.0 hub, can generally be achieved by queuing up multiple pending read and/or
            write requests simultaneously.  This can be done when using    asynchronous I/O operations (calling ReadFile() and
            WriteFile()    with overlapped structures).  The Microchip    HID USB Bootloader application uses asynchronous I/O
            for some USB operations and the source code can be used    as an example.*/


            Byte[] OUTBuffer = new byte[65];    //Allocate a memory buffer equal to the OUT endpoint size + 1
            Byte[] INBuffer = new byte[65];        //Allocate a memory buffer equal to the IN endpoint size + 1
            uint BytesWritten = 0;
            uint BytesRead = 0;

            while(true)
            {
                try
                {
                    if (AttachedState == true)    //Do not try to use the read/write handles unless the USB device is attached and ready
                    {
                        //Get ANxx/POT Voltage value from the microcontroller firmware.  Note: some demo boards may not have a pot
                        //on them.  In this case, the firmware may be configured to read an ANxx I/O pin voltage with the ADC
                        //instead.  If this is the case, apply a proper voltage to the pin.  See the firmware for exact implementation.
                        OUTBuffer[0] = 0x00;    //The first byte is the "Report ID" and does not get sent over the USB bus.  Always set = 0.
                        OUTBuffer[1] = 0x37;    //READ_POT command (see the firmware source code), gets 10-bit ADC Value
                        //Initialize the rest of the 64-byte packet to "0xFF".  Binary '1' bits do not use as much power, and do not cause as much EMI
                        //when they move across the USB cable.  USB traffic is "NRZI" encoded, where '1' bits do not cause the D+/D- signals to toggle states.
                        //This initialization is not strictly necessary however.
                        for (uint i = 2; i < 65; i++)
                            OUTBuffer[i] = 0xFF;

                        //To get the ADCValue, first, we send a packet with our "READ_POT" command in it.
                        if (WriteFile(WriteHandleToUSBDevice, OUTBuffer, 65, ref BytesWritten, IntPtr.Zero))    //Blocking function, unless an "overlapped" structure is used
                        {
                            INBuffer[0] = 0;
                            //Now get the response packet from the firmware.
                            if (ReadFileManagedBuffer(ReadHandleToUSBDevice, INBuffer, 65, ref BytesRead, IntPtr.Zero))        //Blocking function, unless an "overlapped" structure is used    
                            {
                                //INBuffer[0] is the report ID, which we don't care about.
                                //INBuffer[1] is an echo back of the command (see microcontroller firmware).
                                //INBuffer[2] and INBuffer[3] contains the ADC value (see microcontroller firmware).  
                                if (INBuffer[1] == 0x37)
                                {
                                    ADCValue = (uint)(INBuffer[3] << 8) + INBuffer[2];    //Need to reformat the data from two unsigned chars into one unsigned int.
                                }
                            }
                        }



                        //Get the pushbutton state from the microcontroller firmware.
                        OUTBuffer[0] = 0;            //The first byte is the "Report ID" and does not get sent over the USB bus.  Always set = 0.
                        OUTBuffer[1] = 0x81;        //0x81 is the "Get Pushbutton State" command in the firmware
                        for (uint i = 2; i < 65; i++)    //This loop is not strictly necessary.  Simply initializes unused bytes to
                            OUTBuffer[i] = 0xFF;                //0xFF for lower EMI and power consumption when driving the USB cable.

                        //To get the pushbutton state, first, we send a packet with our "Get Pushbutton State" command in it.
                        if (WriteFile(WriteHandleToUSBDevice, OUTBuffer, 65, ref BytesWritten, IntPtr.Zero))    //Blocking function, unless an "overlapped" structure is used
                        {
                            //Now get the response packet from the firmware.
                            INBuffer[0] = 0;
                            {
                                if (ReadFileManagedBuffer(ReadHandleToUSBDevice, INBuffer, 65, ref BytesRead, IntPtr.Zero))    //Blocking function, unless an "overlapped" structure is used    
                                {
                                    //INBuffer[0] is the report ID, which we don't care about.
                                    //INBuffer[1] is an echo back of the command (see microcontroller firmware).
                                    //INBuffer[2] contains the I/O port pin value for the pushbutton (see microcontroller firmware).  
                                    if ((INBuffer[1] == 0x81) && (INBuffer[2] == 0x01))
                                    {
                                        PushbuttonPressed = false;
                                    }
                                    if ((INBuffer[1] == 0x81) && (INBuffer[2] == 0x00))
                                    {
                                        PushbuttonPressed = true;
                                    }
                                }
                            }
                        }



                        //Check if this thread should send a Toggle LED(s) command to the firmware.  ToggleLEDsPending will get set
                        //by the ToggleLEDs_btn click event handler function if the user presses the button on the form.
                        if (ToggleLEDsPending == true)
                        {
                            OUTBuffer[0] = 0;                //The first byte is the "Report ID" and does not get sent over the USB bus.  Always set = 0.
                            OUTBuffer[1] = 0x80;            //0x80 is the "Toggle LED(s)" command in the firmware
                            for (uint i = 2; i < 65; i++)    //This loop is not strictly necessary.  Simply initializes unused bytes to
                                OUTBuffer[i] = 0xFF;        //0xFF for lower EMI and power consumption when driving the USB cable.
                            //Now send the packet to the USB firmware on the microcontroller
                            WriteFile(WriteHandleToUSBDevice, OUTBuffer, 65, ref BytesWritten, IntPtr.Zero);    //Blocking function, unless an "overlapped" structure is used
                            ToggleLEDsPending = false;
                        }
                    } //end of: if(AttachedState == true)
                    else
                    {
                        Thread.Sleep(5);    //Add a small delay.  Otherwise, this while(true) loop can execute very fast and cause 
                                            //high CPU utilization, with no particular benefit to the application.
                    }
                }
                catch
                {
                    //Exceptions can occur during the read or write operations.  For example,
                    //exceptions may occur if for instance the USB device is physically unplugged
                    //from the host while the above read/write functions are executing.

                    //Don't need to do anything special in this case.  The application will automatically
                    //re-establish communications based on the global AttachedState boolean variable used
                    //in conjunction with the WM_DEVICECHANGE messages to dyanmically respond to Plug and Play
                    //USB connection events.
                }

            } //end of while(true) loop
            //-------------------------------------------------------END CUT AND PASTE BLOCK-------------------------------------------------------------------------------------
            //-------------------------------------------------------------------------------------------------------------------------------------------------------------------
        }


También el programa muestra un timer donde cada cierto tiempo se actualizan los estados de las diferentes variables ....se testea la conexion USB...etc.
Código:
private void FormUpdateTimer_Tick(object sender, EventArgs e)
        {
            //-------------------------------------------------------------------------------------------------------------------------------------------------------------------
            //-------------------------------------------------------BEGIN CUT AND PASTE BLOCK-----------------------------------------------------------------------------------
            //This timer tick event handler function is used to update the user interface on the form, based on data
            //obtained asynchronously by the ReadWriteThread and the WM_DEVICECHANGE event handler functions.

            //Check if user interface on the form should be enabled or not, based on the attachment state of the USB device.
            if (AttachedState == true)
            {
                //Device is connected and ready to communicate, enable user interface on the form 
                StatusBox_txtbx.Text = "Device Found: AttachedState = TRUE";
                PushbuttonState_lbl.Enabled = true;    //Make the label no longer greyed out
                ANxVoltage_lbl.Enabled = true;
                ToggleLEDs_btn.Enabled = true;
            }
            if ((AttachedState == false) || (AttachedButBroken == true))
            {
                //Device not available to communicate. Disable user interface on the form.
                StatusBox_txtbx.Text = "Device Not Detected: Verify Connection/Correct Firmware";
                PushbuttonState_lbl.Enabled = false;    //Make the label no longer greyed out
                ANxVoltage_lbl.Enabled = false;
                ToggleLEDs_btn.Enabled = false;

                PushbuttonState_lbl.Text = "Pushbutton State: Unknown";
                ADCValue = 0;
                progressBar1.Value = 0;
            }

            //Update the various status indicators on the form with the latest info obtained from the ReadWriteThread()
            if (AttachedState == true)
            {
                //Update the pushbutton state label.
                if (PushbuttonPressed == false)
                    PushbuttonState_lbl.Text = "Pushbutton State: Not Pressed";        //Update the pushbutton state text label on the form, so the user can see the result 
                else
                    PushbuttonState_lbl.Text = "Pushbutton State: Pressed";            //Update the pushbutton state text label on the form, so the user can see the result 

                //Update the ANxx/POT Voltage indicator value (progressbar)
                progressBar1.Value = (int)ADCValue;
            }
            //-------------------------------------------------------END CUT AND PASTE BLOCK-------------------------------------------------------------------------------------
            //-------------------------------------------------------------------------------------------------------------------------------------------------------------------
        }


Por último tenemos la función que lee un handler de lectura de datos y devuelve los datos leidos desde el dispositivo y nos dá un OK en caso de que la lectura fue correcta o un false en caso de error...

Código:
 //--------------------------------------------------------------------------------------------------------------------------
        //FUNCTION:    ReadFileManagedBuffer()
        //PURPOSE:    Wrapper function to call ReadFile()
        //
        //INPUT:    Uses managed versions of the same input parameters as ReadFile() uses.
        //
        //OUTPUT:    Returns boolean indicating if the function call was successful or not.
        //          Also returns data in the byte[] INBuffer, and the number of bytes read. 
        //
        //Notes:    Wrapper function used to call the ReadFile() function.  ReadFile() takes a pointer to an unmanaged buffer and deposits
        //          the bytes read into the buffer.  However, can't pass a pointer to a managed buffer directly to ReadFile().
        //          This ReadFileManagedBuffer() is a wrapper function to make it so application code can call ReadFile() easier
        //          by specifying a managed buffer.
        //--------------------------------------------------------------------------------------------------------------------------
        public unsafe bool ReadFileManagedBuffer(SafeFileHandle hFile, byte[] INBuffer, uint nNumberOfBytesToRead, ref uint lpNumberOfBytesRead, IntPtr lpOverlapped)
        {
            IntPtr pINBuffer = IntPtr.Zero;

            try
            {
                pINBuffer = Marshal.AllocHGlobal((int)nNumberOfBytesToRead);    //Allocate some unmanged RAM for the receive data buffer.

                if (ReadFile(hFile, pINBuffer, nNumberOfBytesToRead, ref lpNumberOfBytesRead, lpOverlapped))
                {
                    Marshal.Copy(pINBuffer, INBuffer, 0, (int)lpNumberOfBytesRead);    //Copy over the data from unmanged memory into the managed byte[] INBuffer
                    Marshal.FreeHGlobal(pINBuffer);
                    return true;
                }
                else
                {
                    Marshal.FreeHGlobal(pINBuffer);
                    return false;
                }

            }
            catch
            {
                if (pINBuffer != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pINBuffer);
                }
                return false;
            }
        }

        //-------------------------------------------------------END CUT AND PASTE BLOCK-------------------------------------------------------------------------------------
        //-------------------------------------------------------------------------------------------------------------------------------------------------------------------


    } //public partial class Form1 : F


Ya teniendo esto en claro tendríamos que aplicarlo a nuestro ejemplo para tener una base y poder comenzar a trabajar con el firmware del microcontrolador.
 
Última edición:
Esto lo saque del Microchip aplication library 2010 ......buscalo por google y te va a aparecer el link ...luego cuando te lo bajes instalá el paquete completo o selecciona los archivos correspondientes al framework USB.
 
Si meta, en esa página se dan las pautas para que puedas crear una aplicación usando la dll MUSBAPI.dll en conjunto con una aplicación en C# .

He comenzado el firmware pero todavía está dando un funcionamiento erratico acá lo voy a poner...en cuanto lo tenga andando se lo muestro con un video:
Código:
// Aplicación de prueba USB para la entrenadora MoyaPIC_USB_28.
// Programa: Ejemplo básico para realizar programas de control a través del puerto USB.
// Programador: Moyano Jonathan.
// Fecha: Noviembre del 2010.
// Compilador: C de CCS.
////////////////////////////////////////////////////////////////////////////////////////

#include <18F2550.h> // Definición de registros internos del PIC18F2550.
#fuses NOMCLR,XTPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN,NOPBADEN
// NOMCLR: No vamos ha usar el PIN MCLR, el reset se hará por soft.
// XTPLL: Vamos a usar un cristal de 4.00Mhz.
// NOWDT: No vamos a usar el perro guardian.
// NOPROTECT: Memoria no protejida contra lecturas.
// NODEBUG: No utilizamos código para debugear.
// NOLVP: No utilizamos el modo de programación con bajo voltaje.
// USBDIV: signfica que el clock del usb se tomará del PLL/2 = 96Mhz/2 = 48Mhz.
// PLL1: significa que el PLL prescaler no dividirá la frecuencia del cristal. para XT = 4Mhz.
// CPUDIV1: El PLL postscaler decide la división en 2 de la frecuencia de salida del PLL de 96MHZ, si queremos 48MHZ, lo dejamos como está.
// VREGEN: habilita el regulador de 3.3 volts que usa el módulo USB.
// NOPBADEN: Deshabilitamos el módulo conversor ADC del puerto B.
#use delay(clock=48000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, bits=8) // Declaramos el uso del puerto serie.

#DEFINE USB_HID_DEVICE TRUE // Vamos a utilizar el protocolo HID.

#define USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT 
#define USB_EP1_TX_SIZE 64 // Definición del tamaño del buffer de salida.

#define USB_EP1_RX_ENABLE USB_ENABLE_INTERRUPT 
#define USB_EP1_RX_SIZE 64 // Definición del tamaño del buffer de entrada.

/*********************************************************************************************************/

// Definición de las librerías utilizadas.
#include <pic18_usb.h>    // Drivers's USB del PIC18F2550.
#include <USB_MICROCHIP_descriptores.h> // Descriptores USB para la placa MoyaPIC_USB28.
#include <usb.c> // Funciones del USB.
#include <74HC165.c> // Función que permite leer 8 entradas multiplexadas.
#include <74HC164.C> // Función que permite activar 8 salidas multiplexadas.

/*********************************************************************************************************/

// Variables globales.

// Declaramos las variables globales usadas por el programa.


// Definimos las funciones que se utilizan en el programa.
void config_adcon2(void); // Función que utilizamos para configurar el registro ADCON2.

void main() { // Cuerpo principal del programa.

// Variables locales del main.
int valor_bajo; // Variable que guarda la parte baja del dato leido.
int valor_alto; // Variable que guarda la parte alta del dato leido.
int envia[8]; // Variable que contiene al valor del ADC y de los pulsadores.
int recibe[1]; // Variable que contiene los datos que se van a visualizar en los led's.
long valor_adc; // Variable que contiene el valor del CAD.
int interruptores; // Variable utilizada en un contador.
// Definimos las variables locales usadas dentro del cuerpo principal del programa.

// Configuramos los puertos del microcontrolador:
set_tris_a (0b000111);   //Define el puerto A. // RA0,RA1,RA2,RA5 como entradas.....RA3,RA4 como salidas.
set_tris_b (0b11000000); //Define el puerto B. // Todo el puerto B como salida.
set_tris_c (0b01110100); //Define el puerto C. // RC2,RC4,RC5,RC6, como entradas....RC0,RC1,RC7 como salidas.

output_b(0x00); // Limpiamos el puerto B.
output_a(0x00); // Limpiamos el puerto A.
output_c(0x00); // Limpiamos el puerto C.

// Otras configuraciones:
   disable_interrupts(global);
   disable_interrupts(int_timer1);
   disable_interrupts(int_rda);
   disable_interrupts(int_ext);
   disable_interrupts(int_ext1);
   disable_interrupts(int_ext2);
   setup_spi(FALSE);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   port_b_pullups(FALSE);    


// Configuramos el conversor analógico digital:
   setup_adc_ports(ALL_ANALOG || VSS_VDD);
   setup_adc(ADC_CLOCK_DIV_64);

/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Pantalla de bienvenida:
                puts("Programa de control por USB HID DEMO v1.0");         
      puts("=========================================\n");
      puts("Programador: Moyano Jonathan.\n");
                puts("Fecha: Noviembre de 2010.\n");
                puts("VISOR DE EVENTOS POR RS232.\n");
      
//*****************************************************************************************************

puts("inicia el bus USB y sale.\n");
usb_init_cs();               // inicia el USB y sale. Va de la mano con usb_task().
puts("Configuramos el USB...\n");
usb_task();                  // Configuramos el puerto USB.
puts("Dispositivo enumerado y listo para trabajar.\n");
config_adcon2();             // Configuramos el conversor analógico digital.

   while(true) {

    if (usb_enumerated()) {
     puts("Cargamos el valor de todos los canales analógicos y enviamos dichos valores por el EP1.\n");
      set_adc_channel(0); // Selecciono el canal de conversión 0.
       puts("Selecciono el canal 0 ...\n");
        valor_adc = read_adc(); // Leemos el CAD...
          printf("Valor del CAD0:%Lu",valor_adc); // Imprimimos el valor leido en el hyperterminal.
            valor_bajo = (Valor_adc>>8); // Guardamos la parte alta y baja del dato leido del cad..
             valor_alto = (Valor_adc);
          envia[1] = valor_bajo; // Cargamos el dato al buffer de transmisión del USB.
          envia[2] = valor_alto; 
            set_adc_channel(1); // Selecciono el canal de conversión 1.
       puts("Selecciono el canal 1 ...\n");
        valor_adc = read_adc(); // Leemos el CAD...
          printf("Valor del CAD1:%Lu",valor_adc); // Imprimimos el valor leido en el hyperterminal.
            valor_bajo = (Valor_adc>>8); // Guardamos la parte alta y baja del dato leido del cad..
             valor_alto = (Valor_adc);
          envia[3] = valor_bajo; // Cargamos el dato al buffer de transmisión del USB.
          envia[4] = valor_alto; 
      set_adc_channel(2); // Selecciono el canal de conversión 2.
       puts("Selecciono el canal 2 ...\n");
        valor_adc = read_adc(); // Leemos el CAD...
          printf("Valor del CAD2:%Lu",valor_adc); // Imprimimos el valor leido en el hyperterminal.
            valor_bajo = (Valor_adc>>8); // Guardamos la parte alta y baja del dato leido del cad..
             valor_alto = (Valor_adc);
          envia[5] = valor_bajo; // Cargamos el dato al buffer de transmisión del USB.
          envia[6] = valor_alto; 
                   
                      puts("Leemos las entradas digitales..\n");
                      interruptores = read_input_expander();
                       delay_ms(500);
                        printf("Valor obtenido:%u",interruptores);
                          envia[7] = interruptores;

        usb_put_packet(1,envia,8,USB_DTS_TOGGLE);   // Enviamos los datos por USB.

      if (usb_kbhit(1)) // Si hay un paquete de datos en el buffer lo tomamos y guardamos en la variable data.
                  {
                           usb_get_packet(1, recibe, 1);

             puts("Activamos led's según dato entrante..\n");

                        switch(recibe[0]){ // vemos que el valor del dato de entrada coincida con el numero de led y cambia su estado.
                        case 1:
                        output_74HC164(0x01);
                        puts("Activamos led 1.\n");
                        break;
                        case 2:
                        output_74HC164(0x02);
                        puts("Activamos led 2.\n");
                        break;
                        case 3:
                        output_74HC164(0x04);
                        puts("Activamos led 3.\n");
                        break;
                        case 4:
                        output_74HC164(0x08);
                        puts("Activamos led 4.\n");
                        break;
                        case 5:
                        output_74HC164(0x10);
                        puts("Activamos led 5.\n");
                        break;
                        case 6:
                        output_74HC164(0x20);
                        puts("Activamos led 6.\n");
                        break;
                        case 7:
                        output_74HC164(0x40);
                        puts("Activamos led 7.\n");
                        break;
                        case 8:
                        output_74HC164(0x80);
                        puts("Activamos led 8.\n");
                        break;
                        case 9: // Si llega el valor 9...
                        output_74HC164(0x00); // Borra todos los led's.
                        puts("Llega comando 9: apagamos todos los led's.");
                        break;
                         } 
                     }                                 
                 }
  

}
}

// Funciones definidas por el usurio:

// Esta función configura el registro ADCON2.
void config_adcon2() {
   #asm
   movlw 0b10111110 ; justificacion_derecha,20Tad,Fosc/64
   iorwf 0xFC0,1    ; direccion de ADCON2.
   #endasm
}

Hay que poner estos descriptores:

Código:
// Librería de descriptores HID modificadas para funcionar con la aplicación de Microchip.

#IFNDEF __USB_DESCRIPTORS__
#DEFINE __USB_DESCRIPTORS__

#include <usb.h> // Incluimos las funciones de control del puerto USB.

const char USB_CLASS_SPECIFIC_DESC[] = {
      6, 0, 255,       // Usage Page = Vendor Defined
      9, 1,            // Usage = IO device
      0xa1, 1,         // Collection = Application
      0x19, 1,         // Usage minimum
      0x29, 8,         // Usage maximum

      0x15, 0x80,        // Logical minimum (-128)
      0x25, 0x7F,        // Logical maximum (127)

      0x75, 8,        // Report size = 8 (bits)
      0x95, 2,        // Report count = 16 bits (2 bytes)
      0x81, 2,        // Input (Data, Var, Abs)
      0x19, 1,        // Usage minimum
      0x29, 8,        // Usage maximum
      0x75, 8,        // Report size = 8 (bits)
      0x95, 2,        // Report count = 16 bits (2 bytes)
      0x91, 2,        // Output (Data, Var, Abs)
      0xc0            // End Collection
   };

   // Descriptor extra.

   const int16 USB_CLASS_SPECIFIC_DESC_LOOKUP[USB_NUM_CONFIGURATIONS][1] =
   {
   //config 1
      //interface 0
         0
   };

   // Longitud del descriptor extra.

   const int16 USB_CLASS_SPECIFIC_DESC_LOOKUP_SIZE[USB_NUM_CONFIGURATIONS][1] =
   {
   //config 1
      //interface 0
         32
   };


//////////////////////////////////////////////////////////////////
/// Configuración de los diferentes descriptores.
//////////////////////////////////////////////////////////////////

   #DEFINE USB_TOTAL_CONFIG_LEN      41  // Longitud total de los descriptores.

   const char USB_CONFIG_DESC[] = {
  
   // Descriptor de configuración.

         USB_DESC_CONFIG_LEN, 
         USB_DESC_CONFIG_TYPE, 
         USB_TOTAL_CONFIG_LEN,0, 
         1, 
         0x01, 
         0x00, 
         0xC0, 
         0x32, // Corriente que va entregar el bus: 100mA (50mA * 2) (0x32mA*2)

   // Descriptor de interface.

         USB_DESC_INTERFACE_LEN, // Longitud del descriptor.
         USB_DESC_INTERFACE_TYPE, //Constante INTERFACE (INTERFACE 0x04)
         0x00, // Numero de definición de la interface (Si tenemos más de una interfaz)
         0x00, 
         2, // Número de endpoint's.
         0x03, // Código de clase: 0x03 = HID
         0x00, // Subcódigo de clase.
         0x00, // Protocolo de clase.
         0x00, // Descriptor específico para la interfaz.

   // Descriptor de la clase HID.

         USB_DESC_CLASS_LEN, // Longitud del descriptor.
         USB_DESC_CLASS_TYPE, // Tipo de descriptor (0x21 == HID)      
         0x00,0x01, // Versión de la clase HID: 1.0
         0x00, 
         0x01, 
         0x22, // Tipo de descriptor HID.
         USB_CLASS_SPECIFIC_DESC_LOOKUP_SIZE[0][0], 0x00, // Longitud del descriptor.

   // Descriptor del endpoint de salida.

         USB_DESC_ENDPOINT_LEN, // Longitud del descriptor.
         USB_DESC_ENDPOINT_TYPE, // Constante ENDPOINT. (ENDPOINT 0x05) 
         0x81, // Número del endpoint y dirección (0x81 = EP1 IN)       
         0x03, // Tipo de transferencia (0x03 = interruptiva)
         USB_EP1_TX_SIZE,0x00, // Tamaño del buffer de salida.
         10, // Intervalo de polling = 10ms.

   // Descriptor del endpoint de entrada.

         USB_DESC_ENDPOINT_LEN, // Longitud del descriptor.
         USB_DESC_ENDPOINT_TYPE, // Constante ENDPOINT. (ENDPOINT 0x05)          
         0x01, // Número del endpoint y dirección (0x01 = EP1 OUT).      
         0x03, // Tipo de transferencia (0x03 = interruptiva)
         USB_EP1_RX_SIZE,0x00, // Tamaño del buffer de entrada.
         10 // Intervalo de polling = 10ms.
   };

   #define USB_NUM_HID_INTERFACES   1 // Definimos el número de interfaces.
   #define USB_MAX_NUM_INTERFACES   1 // Definimos el número máximo de interfaces.

   const char USB_NUM_INTERFACES[USB_NUM_CONFIGURATIONS]={1};

   const int16 USB_CLASS_DESCRIPTORS[USB_NUM_CONFIGURATIONS][1][1]=
   {
   //config 1
      //interface 0
         //class 1
         18
   };

   #if (sizeof(USB_CONFIG_DESC) != USB_TOTAL_CONFIG_LEN)
      #error USB_TOTAL_CONFIG_LEN not defined correctly
   #endif


//////////////////////////////////////////////////////////////////
///
///   Descriptores del dispositivo
///
//////////////////////////////////////////////////////////////////

   const char USB_DEVICE_DESC[USB_DESC_DEVICE_LEN] ={
         USB_DESC_DEVICE_LEN, // Longitud del reporte.
         0x01, // Constante del dispositivo = 1
         0x10,0x01, // Versión del USB 1.10.
         0x00, // Código de clase.
         0x00, // Código de subclase.
         0x00, // Código de protocolo.
         USB_MAX_EP0_PACKET_LENGTH, // Tamaño máximo del paquete de datos del endpoint 0 = 8 para HID.
         0xD8,0x04, // Vendor  id =  decimal(1240), hexadecimal(04d8) // Identificadores de Microchip.
         0x3F,0x00, // Product id =  decimal(63), hexadecimal(003f)
         0x00,0x01, // Número del dispositivo.
         0x01, 
         0x02, 
         0x00, 
         USB_NUM_CONFIGURATIONS  // Número de posibles configuraciones.
   };


//////////////////////////////////////////////////////////////////
/// Descriptores del fabricante
//////////////////////////////////////////////////////////////////


char USB_STRING_DESC_OFFSET[]={0,4,12};

char const USB_STRING_DESC[]={
   // Primer descriptor.
         4, // Longitud del descriptor.
         USB_DESC_STRING_TYPE, 
         0x09,0x04,   // Lenguaje id = Inglés (Definido por microsoft).
   // Segundo descriptor.
         8, // Longitud del descriptor.
         USB_DESC_STRING_TYPE, // Descriptor del compilador utilizado. (STRING) (Puede ser el nombre de la compañía)
         'C',0,
         'C',0,
         'S',0,
   // Tercer descriptor.
         34, // Longitud del descriptor.
         USB_DESC_STRING_TYPE, // Descriptor del fabricante: MoyaPIC_HID_DEMO. (STRING)
         'M',0,
         'o',0,
         'y',0,
         'a',0,
         'P',0,
         'I',0,
         'C',0,
         '_',0,
         'H',0,
         'I',0,
         'D',0,
         '_',0,
         'D',0,
         'E',0,
         'M',0,
         'O',0
};

#ENDIF

Y usar las siguientes librerías de control:
Código:
// Librería de control para un expansor de 8 entradas digitales con 74HC165.
// Librería de CCS modificada por Moyano Jonathan.


#define INPUT_ENA       PIN_A3
#define CKL_exp         PIN_A4
#define DATA_exp        PIN_A5
#define NUMBER_OF_74165 1

char read_input_expander(void) {
  int8 i,dato;

  output_high(CKL_exp);
  output_low(INPUT_ENA);      // Guarda el estado actual de las entradas.
  output_high(INPUT_ENA);

  for(i=1;i<=8;++i) {      
    shift_left(dato,1,input(DATA_exp)); // Desplaza los datos y los guarda en la variable.
    output_low(CKL_exp);
    output_high(CKL_exp);
  }
  output_low(INPUT_ENA);

return(dato);
}

Código:
// Librería de control para el expansor de 8 salidas con 74HC164.
// Programador: Moyano Jonathan
// Versión: 1.0
// Funciones:
// escribe_registro(); Muestra un valor de 0 a 255 en el puerto.

// Definiciones de los puertos utilizados en el PIC.

// Pines intercambiables según necesidades del usuario.

#define relog PIN_A3 
#define datos PIN_A2
#define reset PIN_A1

void output_74HC164(int valor); // Definimos la función.

void output_74HC164(int valor) {

int contador; // Contador para escribir los datos al registro de desplazamiento.

  output_low(relog);
  output_high(reset);
  output_low(datos);

  for(contador=0;contador!=8;contador++) {  
  output_bit(datos,bit_test(valor,contador));
   output_high(relog);
   delay_cycles(1);
   output_low(relog);
  }
output_low(relog);
delay_ms(1);
}
 
Última edición:
Si solo me falta pulir algunos detalles y sale andando ....:)...luego de estar toda la noche en ello ...me tiene que andar :eek:

Ahora a seguir leyendo he investigando para poder sacar a flote el proyecto completo (y)
 
lamentablemente mis conocimientos en visual y C# no son buenos muy interesante poniendole ganas ojala pueda saber un poquito mas de lo que estan hablando por el momento para mi esto es un poco distante sigan asi ojala los novatos podamos aprender alguito muchas gracias por los aportes
 
lamentablemente mis conocimientos en visual y C# no son buenos muy interesante poniendole ganas ojala pueda saber un poquito mas de lo que estan hablando por el momento para mi esto es un poco distante sigan asi ojala los novatos podamos aprender alguito muchas gracias por los aportes

Prueba un poco por aquí y será mejor. También estoy pobre con ello.
http://electronica-pic.blogspot.com

Muy útil si tienes muchas dudas.
http://social.msdn.microsoft.com/Forums/es-es/categories/

Edito:

Moyano.

gpic_usb_v2.png


Puedes preguntar a esta web como hizo lo del ASCII y binarios.
http://www.sitionica.com.ar/gpic-usb-programador-download.htm
 
Última edición:
Ya pude hacer que la interfaz me reconiera la placa de desarrollo en HID....lo bueno de usar HID nativo es que no hace falta conectar/deconectar el dispositivo.....o cargar el VID/PID....ni tampoco manejar los eventos de interrupción del USB...por que eso lo hace el sistema asi que la interfaz se simplifica mucho.

Voy a preguntarle a willy el creador de ese programador si me puede orientar en el uso del datagrid.
 
Buenas:

Parece que has descubierto de una forma muy simplificada de hacer con el USB. Lo bueno para no liar a la gente, centrarte en endencer y apagar los led por USB e¡con entradas y salidas digitales. Lo mismo para los ADC.

Por cierto. ¿Lo estás preparando para el 18F2550 o el 18F4550 o los dos?

:)
 
no me lo tomen a mal... pero yo si ya me lie.....

que si los HID de los VID/PID de nativos del no se que del USB :confused:

me parece que si es haaaaarrrrrta tecnología para mi....:oops:
Suerte!... a ver si mas delante comprendo algo...
 
Para meta:
Mi entrenadora USB tiene el PIC18F2550 asi que el firmware va para ese....ahora si le modificas algunas cosas básicas corre sin problemas en un PIC18F4550.
PD: La aplicación está compilada para que corra en sistemas de 32 como de 64 bits....pero habrá que probarla para que no presente fallos..

Para lubeck:
Hola te paso a explicar rapidamente lo que se está haciendo:

1° - Esta idea del programa surgió de meta cuando planteó la necesidad de tener algo más entendible para el programador novato y que saque con facilidad su programa de control.

2° - Luego de plantear muchas ideas...pude encontrarme con una aplicación de microchip que explica (en inglés) como implementar la comunicación con el host (PC o ordenador ) de forma nativa ( Con los drivers que trae de fábrica windows )...con esto se logra una gran compatiblidad y facilidad a la hora de programar ya que todo el "trabajo sucio" se lo lleva windows.... y nosotros solo nos encargamos de las comunicaciones.

3° - El VID/PID de un dispositivo USB es un identificador que muestra Quien fabrico el dispositivo "VID : Vendor ID" .....y un identificador de producto (PID: Product ID) para mostrarnos de que se trata...

Algo a tener en cuenta sobre el proceso de comunicación del dispositivo con el host:

1° - En primera instancia el dispositivo es enumerado por el host cargando en el registro toda la información sobre dicho dispositivo para que cuando se lo vuelva a conectar no pida continuamente drivers...sino que los pide una vez y luego cada vez que se conecta el host busca la información del dispostivo en el registro.

2° - La aplicación funciona de una manera muy sencilla:

A - A través de llamados a funciones de windows...el sistema busca un dispositivo conectado al host...por lo tanto windows genera una interrupción que es leida por la aplicación y en función del valor leído ejecuta diferentes procesos programados por el usuario.

B - Una vez que el sistema encuentra al dispositivo , crea handlers o manejadores que no son más que archivos donde una podrá leer o escribir información que será enviada al puerto USB.

C - Los handlers están asociados a buffers de comunicaciones (DONDE ENTRAMOS NOSOTROS) que nos permitirán mediante sencillas instrucciones poder enviar o recibir datos.


- Por razones de velocidad en la ejecución de datos la aplicación corre las instrucciones principales del programa ( comunicaciones con el puerto USB ) en un hilo diferente al de la aplicación central..
 
Última edición:
:)

Se trata de hacer un buen manual para que aprendamos hacer nuestra propia Interfaz con Visual Studio .net y la comunicación del USB con el PIC y PC. Se aprenderá hacer estas cosas como dijo Moyano.

- 8 x salidas digitales multiplexadas.
- 8 x entradas digitales multiplexadas.
- 3 x entradas analógicas con potenciómetros.
- 1 x Memoria EEPROM I2C.
- 1 x RS232 para debug.


Muy buena idea para cosas básicas y Moyano por lo que veo en todo el foro es el más que ha puesto empeño y dedicación. Por eso está el dicho. "A las personas se les conoce por sus obras, no por sus palabras".

Está haciendo un buen trabajo. Para que te hagas una idea, hice un manual del puerto serie y otro del puerto paralelo. Con él aprenderás paso a paso lo que necesitas saber y hacer tus proyectos.

Ahora desde el 2008, por fin hay frutos con lo que me encanta los USB gracias a Moyano y otros ayudantes.

La veradad, con las 3 pirmeras obsiones me conformo. Tampco quiero pedirle mucho, ni aprovechándome de su buena fe.

- 8 x salidas digitales multiplexadas.
- 8 x entradas digitales multiplexadas.
- 3 x entradas analógicas con potenciómetros.

;)
 
Igualmente. Tengo el 18F2550 y el 18F4550. Con el tiempo se arpovechará todo lo que se pueda, eso si, primero lo primero, poco a poco. A ver si nos sale todo antes de que llegue el USB 3.0, hablando de él, he leído por ahí que el protocolo ha cambiado un poco e incluso es más fácil para los programadores. Eso hay qu everlo si es verdad.
 
Atrás
Arriba