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

buen dia tengan todos los seguidores de este temas.
me disculpo si ya alguien a preguntado asi, pero he leido cerca de 10 paginas y no veo un problema similar, sin embargo aqui voy con mi problema: compre el pic18f2450 que traer hardware USB, es la primera ves que programamo el USB de un pic, estoy utilizando un cristal de 8Mhz con el PLL activo lo que genera que el clock del pic sea de 48Mhz, el USB esta configurado con el high speed y desactive el voltaje regulator, sin envargo no logro hacer que el pic sea reconocido por el PC y en proteus no veo que este enviando datos a USB virtual, estoy utilizando el enumer_picusb para generar la informacion que requier el windows pero el driver no es reconocido por el pc, les adjunto el programa para que le hechen una ojeada y me digan si esta bien o si lo estoy haciendo mal, el programa es solo de prueba basica, lo que hace es enviar los datos del cdc para crear un puerto serie virtual y luego pasa a encender un led y apagalo esto es solo para yo llevar el control:

Código:
#include <18F2450.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL2,CPUDIV1, VREGEN,MCLR
#use delay(clock=48000000)

#include "usb_cdc.h"
#include "usb_desc_cdc.h"

#define LED1 (pin_c0)
#define  LED_ON  output_high
#define  LED_OFF  output_low

void main (){ 
         delay_ms (500);
         usb_cdc_init();
         usb_init();
            while(true){
               LED_ON (LED1);
               delay_ms (500);
               LED_OFF (LED1);
               delay_ms (500);}
         }
les agradesco si pueden ayudarme, aconsejarme o si me van a regañar jajajaja...
 
Última edición por un moderador:
Hola rald lamento decirle que en tu codigo no solo por agregar las librerias de trabajo de usb #include "usb_cdc.h" #include "usb_desc_cdc.h" te va a reconocer el micro como usb en ningún momento ni las llamas, ni utilizas ninguna de las funciones que estas traen para tal fin, te recomiendo que leas los primeros mensajes de este hilo que ahí se trabajo esto y moyano aporto varios ejemplos.
https://www.forosdeelectronica.com/f24/control-dispositivos-traves-modulo-usb-pic18f2550-17458/
si tienes mas dudas nos las comunica.
saludos
 
gracias por tu pronta respuesa FRYCK, he leido las paginas que explican como configurar el USB en el pic pero no entiendo a que te refieres con llamar a la libreria?? en una de las paginas habla de llamar a la libreria utilizando este comando "usb_init()" pero esos comandos ya estan en mi programa entonces no veo en que me estoy equivocando, si fueses tan amable de guiarme por donde leer te lo agradeceria....
 
Hola rald guíese del ejemplo del cual puse el link https://www.forosdeelectronica.com/f24/control-dispositivos-traves-modulo-usb-pic18f2550-17458/ te recomiendo que leas las primeras partes de este hilo en la pagina 1 y que te descargues el manual echo por moyano. Búscalo esta en la pagina anterior. el siguiente programa es básico para comunicación por puerto serial virtual.


// Ejercicio Nº1: Genera un COM virtual y se comunica bidireccionalmente con el a través del PIC18F2550.
#include <18F2550.h> // Definición de registros internos.

#fuses HSPLL,NOMCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN

// Fuses utilizados:
/*
HSPLL: utilizamos un cristal HS de alta velocidad, en conjunto con el PLL para generar los 48Mhz.
NOMCLR: Utilizamos reset por software, y dejamos el pin 1 del micro como entrada/salida digital.
NOWDT: No utilizamos el perro guardían.
NOPROTECT: Desactivamos la protección de código.
NOLVP: Desactivamos la programación a bajo voltaje.
NODEBUG: No entramos al modo debug.
USBDIV: signfica que el clock del usb se tomará del PLL/2 = 96Mhz/2 = 48Mhz.
PLL5: significa que el PLL prescaler dividirá en 5 la frecuencia del cristal. para HS = 20Mhz/5 = 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
*/

#use delay(clock=48000000) // Frecuencia máxima de trabajo.

#include "usb_cdc.h" // Descripción de funciones del USB.
#include "usb_desc_cdc.h" // Descriptores del dispositivo USB.

void main() {
usb_cdc_init(); // Configuramos al puerto virtual.
usb_init(); // Inicializamos el stack USB.
while(!usb_cdc_connected()) {}
// espera a detectar una transmisión de la PC (Set_Line_Coding).
do{
usb_task();
if (usb_enumerated()){ // Espera a que el dispositivo sea enumerado por el host.
if(usb_cdc_kbhit()){ // En espera de nuevos caracteres en el buffer de recepción.
if(usb_cdc_getc()=='x'){ //¿lo que llegó fué el caracter x?
printf(usb_cdc_putc, "Se recibe el caracter x.\n\r");
//si, entonces envía una cadena hacia el PC
}
if(usb_cdc_getc()=='a'){ //¿lo que llegó fué el caracter a?
printf(usb_cdc_putc, "Se recibe el caracter a.\n\r");
//si, entonces envía una cadena hacia el PC
}
}
}
}while (TRUE); // bucle infinito.
}
 
Lo que FRYCK quiere decir es que tu programa no usa ninguna función que este en las librerias(a excepción del usb_init), podrias quitar esas lineas y funcionaria igual. Lo que tenes que hacer es incluir algunas funciones por ejemplo:
Código:
usb_task();

printf(usb_cdc_putc, "Conexion CDC via USB .\n\r"); 

if(usb_cdc_getc()=='a')

tendrias que fijarte que funcion hace lo que vos queres, existe, pero no recuerdo cuál es...

Moya te darás cuenta que estuve practicando esto del usb y la verdad sos un capo, gracias por la informacion anda todo re bien y re claro. Seguro dentro de poco me tendran molestando preguntando algo que no me salga ;)

saludos
 
Amigo pkdos.:unsure:
Realice todas las pruebas y la simulacion funciona full.
Tendrias que armarlo en un protoboard y probarlo a ver como te va
depronto es algun problema con la version isis que tienes.
De todas maneras; el amigo moyano subio unos ej en modo bullk usb
intenta con con el primer ejemplo a simularlo, logicamente tienes que instalar otor drivers
y comentas los resultados.si te funciona bien; depronto tiene problemas con los otros drivers:apreton:
 
Buenas, soy nuevo en esto de pic-usb....
alguien tendra un proyecto todo mascadito?
codigo VB codigo pic y proteus

algo asi como prender un led, mover un motor, cositas asi.

de ante mano muchas gracias
 
Hola colegas del mundo de la electrónica,

Permitid que me presente. Me llamo Héctor y resido en Valencia, España. Tras haber cursado un Ciclo Formativo de Grado Superior de Desarrollo de Productos Electrónicos, estoy haciendo las FCT en la universidad con un proyecto en el cual requerimos de la comunicación de un PIC18F2550 con un PC para adquirir los datos de unas señales analógicas.

Antes de nada me gustaria agradecer a Moyano y demás usuarios del foro por los ejemplos dados en este hilo que me han sido de gran ayuda para poder desarrollar el firmware del PIC con la clase CDC.

Actualmente me hallo en la tarea de portar todo el código que tenemos para CDC a la libreria EasyHID, por lo cual estoy portando la interfaz de la DLL a C# (y con un conversor seguramente también VB.NET). Tan solo me gustaría dejar por aquí la clase intefaz que he hecho (con mis escasos conocimientos de C#) con la esperanza de que también os resulte de ayuda a vosotros, además de que así podríamos ayudarnos mutuamente y mejorarla.

Por ahora las funciones básicas están implementadas y he probado un pequeño software para el PIC para comprobar que la lectura y escritura se realiza correctamente. Me falta por ver que parámetros serían los más correctos para poder recoger las strings de producto y demás, que en los proximos días trataré de averiguar.

Sin más dilación, el código de la clase es el siguiente:
PHP:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.ComponentModel;
using System.Runtime.InteropServices;

namespace MecaniqueUK
{
    class EasyHID
    {
        // HID specific...
        public const UInt32 VENDOR_ID       = 6017;
        public const UInt32 PRODUCT_ID      = 2000;
        public const int BUFFER_IN_SIZE     = 8;
        public const int BUFFER_OUT_SIZE    = 8;

        // HID events...
        private const int WM_APP            = 0x8000;
        public const int WM_HID_EVENT       = WM_APP + 200;
        public const int NOTIFY_PLUGGED     = 0x0001;
        public const int NOTIFY_UNPLUGGED   = 0x0002;
        public const int NOTIFY_CHANGED     = 0x0003;
        public const int NOTIFY_READ        = 0x0004;

        // HID interface...
        [DllImport("mcHID.dll")]
        public static extern bool Connect(IntPtr pHostWin);
        [DllImport("mcHID.dll")]
        public static extern bool Disconnect();
        [DllImport("mcHID.dll")]
        public static extern UInt32 GetItem(UInt32 pIndex);
        [DllImport("mcHID.dll")]
        public static extern UInt32 GetItemCount();
        [DllImport("mcHID.dll")]
        public static extern bool Read(UInt32 pHandle, IntPtr pData);
        [DllImport("mcHID.dll")]
        private static extern bool Write(UInt32 pHandle, IntPtr pData);
        [DllImport("mcHID.dll")]
        private static extern bool ReadEx(UInt32 pVendorId, UInt32 pProductId, IntPtr pData);
        [DllImport("mcHID.dll")]
        private static extern bool WriteEx(UInt32 pVendorId, UInt32 pProductId, IntPtr pData);
        [DllImport("mcHID.dll")]
        public static extern UInt32 GetHandle(UInt32 pVendorID, UInt32 pProductId);
        [DllImport("mcHID.dll")]
        public static extern UInt32 GetVendorID(UInt32 pHandle);
        [DllImport("mcHID.dll")]
        public static extern UInt32 GetProductID(UInt32 pHandle);
        [DllImport("mcHID.dll")]
        public static extern UInt32 GetVersionID(UInt32 pHandle);
        [DllImport("mcHID.dll")]
        public static extern UInt32 GetInputReportLength(UInt32 pHandle);
        [DllImport("mcHID.dll")]
        public static extern UInt32 GetOutputReportLength(UInt32 pHandle);
        [DllImport("mcHID.dll")]
        public static extern void SetReadNotify(UInt32 pHandle, bool pValue);
        [DllImport("mcHID.dll")]
        public static extern bool IsReadNotifyEnabled(UInt32 pHandle);
        [DllImport("mcHID.dll")]
        public static extern bool IsAvailable(UInt32 pVendorId, UInt32 pProductId);

		// Managed version of the read/write functions.
        public static bool Read(UInt32 pHandle, out byte[] pData)
        {
            IntPtr unmanagedBuffer = Marshal.AllocHGlobal(BUFFER_IN_SIZE);
            bool result = Read(pHandle, unmanagedBuffer);

            try { pData = new byte[BUFFER_IN_SIZE]; Marshal.Copy(unmanagedBuffer, pData, 0, BUFFER_IN_SIZE); }
            finally { Marshal.FreeHGlobal(unmanagedBuffer); }

            return result;
        }

        public static bool Write(UInt32 pHandle, byte[] pData)
        {
            IntPtr unmanagedBuffer = Marshal.AllocHGlobal(BUFFER_OUT_SIZE);
            bool result;

            try { Marshal.Copy(pData, 0, unmanagedBuffer, BUFFER_OUT_SIZE); result = Write(pHandle, unmanagedBuffer); }
            finally { Marshal.FreeHGlobal(unmanagedBuffer); }

            return result;
        }
		
        public static bool ReadEx(UInt32 pVendorId, UInt32 pProductId, out byte[] pData)
        {
            IntPtr unmanagedBuffer = Marshal.AllocHGlobal(BUFFER_IN_SIZE);
            bool result = ReadEx(pVendorId, pProductId, unmanagedBuffer);

            try { pData = new byte[BUFFER_IN_SIZE]; Marshal.Copy(unmanagedBuffer, pData, 0, BUFFER_IN_SIZE); }
            finally { Marshal.FreeHGlobal(unmanagedBuffer); }

            return result;
        }

        public static bool WriteEx(UInt32 pVendorId, UInt32 pProductId, byte[] pData)
        {
            IntPtr unmanagedBuffer = Marshal.AllocHGlobal(BUFFER_OUT_SIZE);
            bool result;

            try { Marshal.Copy(pData, 0, unmanagedBuffer, BUFFER_OUT_SIZE); result = WriteEx(pVendorId, pProductId, unmanagedBuffer); }
            finally { Marshal.FreeHGlobal(unmanagedBuffer); }

            return result;
        }
    }
}

Ejemplo de utilización análogo al funcionamiento del ejemplo en Visual Basic (aun incompleto, no he podido probar aún la lectura de datos del PIC):
PHP:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using MecaniqueUK;

namespace WindowsFormsApplication1
{
    public partial class FormMain : Form
    {
        public FormMain()
        {
            InitializeComponent();
        }

        private void FormMain_Load(object sender, EventArgs e)
        {
            EasyHID.Connect(Handle);
        }


        private void FormMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            EasyHID.Disconnect();
        }

        private void OnPlugged(UInt32 handle)
        {
            if (EasyHID.GetVendorID(handle) == EasyHID.VENDOR_ID && EasyHID.GetProductID(handle) == EasyHID.PRODUCT_ID)
            {
                Console.WriteLine("Conectado al dispositivo.");
                EasyHID.SetReadNotify(handle, true);

                // Enviar dato de prueba
                byte[] test = new byte[EasyHID.BUFFER_OUT_SIZE];
                test[0] = 0;      // Report ID
                test[1] = 0x11;   // Dato aleatorio
                if (EasyHID.Write(handle, test) == true)
                {
                    Console.WriteLine("Dato enviado correctamente.");
                }
            }
        }

        private void OnUnplugged(UInt32 handle)
        {
            if (EasyHID.GetVendorID(handle) == EasyHID.VENDOR_ID && EasyHID.GetProductID(handle) == EasyHID.PRODUCT_ID)
            {
                Console.WriteLine("Desconectado del dispositivo.");
            }
        }

        protected override void WndProc(ref Message message)
        {
            // Intercept the HID message.
            if (message.Msg == EasyHID.WM_HID_EVENT)
            {
                switch (message.WParam.ToInt32())
                {
                    case EasyHID.NOTIFY_PLUGGED:
                        OnPlugged((UInt32) message.LParam.ToInt32());
                        break;
                    case EasyHID.NOTIFY_UNPLUGGED:
                        OnUnplugged((UInt32) message.LParam.ToInt32());
                        break;
                    case EasyHID.NOTIFY_CHANGED:
                        break;
                    case EasyHID.NOTIFY_READ:
                        break;
                }
            }

            // Run the base procedure.
            base.WndProc(ref message);
        }
    }
}

Espero que os sirva de ayuda :)
 
Última edición:
@ElGiganteDeYeso aunque te parezca mentira me has resuelto un gran problema ...yo hasta ahora no había podido portar el código de EasyHID a VC# y me has puesto la solución ....muchas gracias !!!
 
Amigos meta y moyano.
No se si pueda preguntarles aqui; pero creo que entre prueba y prueba
de los ejemplos usb. se me crearon una cantidad de puertos virtuales
que solo estan en uso al conectar los dispositivos. lo digo por que cuando conecto el usb
aparecen en puertos com, debe haber un poco de estos ya que al simular me aparece
el com 110, esta el 12,11,2 y 1 es logico que del 110 para abajo deben estar
pero no los puedo ver..como hago para quitar estos puertos, sera posible con alguna aplicacion vb..:unsure:
Gracias..:apreton:
 
Atrás
Arriba