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

Hola

el OTG esta disponible solo para los pic24 y los pic32 que permite configurar el pic como host.
pero la aplicacion tambien funciona para generar codigo para perifericos.

probare esta herramienta y comentare los resultados.
ya programe una aplicacion con usb bulk transfer en visualC++ aunque no use sus librerias mfc sino las funciones del api de windows directamente y basandome en un ejemplo para borland C en la carpeta del driver.

salu2:)
 
JOJOJORGE dijo:
Hola

el OTG esta disponible solo para los pic24 y los pic32 que permite configurar el pic como host.
pero la aplicacion tambien funciona para generar codigo para perifericos.

probare esta herramienta y comentare los resultados.


salu2:)
huy jojorge eso estaria de lujos , ya habia escuchado del otg y quede interesado pero no eh sabido por donde empezar
 
hola amigos:

Estoy desarrollando un prog que adquiera datos analogicos con el ADC del pic18f4458(ADC de 12 bits), por usb y lo muestre en la pc me salio este codigo , que aun lo estoy puliendo
:cool: :

programa en el pic :
Código:
include <18F4458.h>
#device ADC=12   // ADC DE 10 BITS
#fuses XTPLL,NOMCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN
#use delay(clock=48000000)


/////////////////////////////////////////////////////////////////////////////
//
// CCS Library dynamic defines.  For dynamic configuration of the CCS Library
// for your application several defines need to be made.  See the comments
// at usb.h for more informaciónrmation
//
/////////////////////////////////////////////////////////////////////////////
#define USB_HID_DEVICE     FALSE             //deshabilitamos el uso de las directivas HID
#define USB_EP1_TX_ENABLE  USB_ENABLE_BULK   //turn on EP1(EndPoint1) for IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE  USB_ENABLE_BULK   //turn on EP1(EndPoint1) for OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE    3                 //size to allocate for the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE    3                 //size to allocate for the rx endpoint 1 buffer

#define USB_CON_SENSE_PIN PIN_E3  
#define DERECHA 0

#include <pic18_usb.h>     //Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include <USB_ADC_TESIS.h>         //Configuración del USB y los descriptores para este dispositivo
#include <usb.c>           //handles usb setup tokens and get descriptor reports

#byte ADCON0 = 0xFC2
#byte ADRESL = 0XFC3
#byte ADRESH = 0XFC4


#define LEDV    PIN_B6
#define LEDR    PIN_B7
#define LED_ON  output_high
#define LED_OFF output_low

#define modo      recibe[0]
#define param1    recibe[1]
#define param2    recibe[2]
#define MedidaAlta   envia[0]
#define MedidaBaja  envia[1]

void config_adcon2(short justificacion);
int H,L;

void main(void) {

   int8 recibe[3];                  //declaramos variables
   int8 envia[2];
   
   set_tris_a(0x1);    // configuramos RA como entrada
   
   LED_OFF(LEDV);                   //encendemos led rojo
   LED_ON(LEDR);

   usb_init_cs();                      //inicializamos el USB
   setup_adc_ports(AN0 || VSS_VDD);
   config_adcon2(DERECHA);
   while (TRUE)
   {
      usb_task();                      //habilita periferico usb e interrupciones
      if(usb_enumerated())          //si el PicUSB está configurado
      {
         LED_OFF(LEDR);
         LED_ON(LEDV);                    //encendemos led verde

         if (usb_kbhit(1))          //si el endpoint de salida contiene datos del host
         {
            usb_get_packet(1, recibe, 3); //cojemos el paquete de tamaño 3bytes del EP1 y almacenamos en recibe

            if (modo == 1) // Modo_Led
            {
               if (param1 == 0) {LED_OFF(LEDV); LED_OFF(LEDR);} //apagamos los leds
               if (param1 == 1) {LED_ON(LEDV); LED_OFF(LEDR);} //encendemos led verde
               if (param1 == 2) {LED_OFF(LEDV); LED_ON(LEDR);} //encendemos led rojo
            }
            if (modo == 2)  //Modo ADC
            {
              set_adc_channel(0);
              while(bit_set(ADCON0,1));
              H = ADRESH;
              L = ADRESL;
              MedidaAlta = H;
              MedidaBaja = L;
              usb_put_packet(1, envia, 1, USB_DTS_TOGGLE);
              LED_On(LEDR);
              LED_ON(LEDV);                    //encendemos led verde
            }
         }
      }
   }
}
void config_adcon2(short justificacion)
{
   setup_adc(ADC_CLOCK_DIV_64 );  // reloj de conversión = Fosc / 64
    if(justificacion){
    #asm
    bsf 0xFC0,7    // ADFM <- 1
    #endasm
    }
    else{
    #asm
      bcf 0xFC0,7   // ADFM <- 0
   #endasm
   }
   #asm          // configura Tacq = 2Tad
    bsf 0xFC0,3
    bcf 0xFC0,4
    bcf 0xFC0,5
   #endasm
}

en visual c# tenemos los siguiente:


Código:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

using PVOID = System.IntPtr;
using DWORD = System.UInt32;

namespace USB_ADC_TESIS
{
    public partial class Form1 : Form
    {
        PicUSBAPI usbapi = new PicUSBAPI();
        public Form1()
        {
            InitializeComponent();
        }
        unsafe public class PicUSBAPI
        {
            #region Definición de los Strings: EndPoint y VID_PID
            string vid_pid_norm = "vid_04d8&pid_0042";

            string out_pipe = "\\MCHP_EP1";
            string in_pipe = "\\MCHP_EP1";
            #endregion

            #region Funciones importadas de la DLL: mpusbapi.dll
            [DllImport("mpusbapi.dll")]
            private static extern DWORD _MPUSBGetDLLVersion();
            [DllImport("mpusbapi.dll")]
            private static extern DWORD _MPUSBGetDeviceCount(string pVID_PID);
            [DllImport("mpusbapi.dll")]
            private static extern void* _MPUSBOpen(DWORD instance, string pVID_PID, string pEP, DWORD dwDir, DWORD dwReserved);
            [DllImport("mpusbapi.dll")]
            private static extern DWORD _MPUSBRead(void* handle, void* pData, DWORD dwLen, DWORD* pLength, DWORD dwMilliseconds);
            [DllImport("mpusbapi.dll")]
            private static extern DWORD _MPUSBWrite(void* handle, void* pData, DWORD dwLen, DWORD* pLength, DWORD dwMilliseconds);
            [DllImport("mpusbapi.dll")]
            private static extern DWORD _MPUSBReadInt(void* handle, DWORD* pData, DWORD dwLen, DWORD* pLength, DWORD dwMilliseconds);
            [DllImport("mpusbapi.dll")]
            private static extern bool _MPUSBClose(void* handle);
            #endregion

            void* myOutPipe;
            void* myInPipe;

            //Constantes
            const int MaxRec = 2;
            const int MaxEnv = 2;
            //**** FUNCION ABRIR PIPE ****
            public void AbrirPipes()
            {
                DWORD seleccion = 0;
                myOutPipe = _MPUSBOpen(seleccion, vid_pid_norm, out_pipe, 0, 0);
                myInPipe = _MPUSBOpen(seleccion, vid_pid_norm, in_pipe, 1, 0);
            }
            //**** FUNCION CERRAR PIPE ****
            public void CerrarPipes()
            {
                _MPUSBClose(myOutPipe);
                _MPUSBClose(myInPipe);
            }

            /**** FUNCIONES ENVIO RECEPCION DE PAQUETES ******/
            private void EnvioPaquete(byte* SendPacket, DWORD SendLength)
            {
                uint Sendelay = 1000;
                DWORD SendDataLength;
                _MPUSBWrite(myOutPipe, (void*)SendPacket, SendLength, &SendDataLength, Sendelay);
            }
            private void ReciboPaquete(byte* ReceiveData, DWORD* ReceiveLength)
            {
                uint ReceiveDelay = 1000;
                DWORD ExpectReceiveLentgh = *ReceiveLength;
                _MPUSBRead(myInPipe, (void*)ReceiveData, ExpectReceiveLentgh, ReceiveLength, ReceiveDelay);
            }
            /****  PRENDER APAGAR LEDS ******/
            public void LedPIC(uint led)
            {
                byte* send_buf = stackalloc byte[2];
                send_buf[0] = 0x01;
                send_buf[1] = (byte)led;
                EnvioPaquete(send_buf, 2);
            }
            ///////////////////////////////////////////////
            /**** FUNCIONES PERSONALIZADAS ****/
            //public void RecibirPaquetePic(byte* BufferRec)
            public float RecibirPaquetePic()
            {
                float Conversion = 0;
                byte* BufferRec = stackalloc byte[3];               
               
                DWORD RecvLentgh = 2;

                ReciboPaquete(BufferRec, &RecvLentgh);
                
               // if (BufferRec[0]==0)
               // return Conversion = BufferRec[0];
                //else
               return Conversion = BufferRec[1];
            }
            // **** FUNCION QUE PIDA DATOS AL PIC ****
            public void PideDatosPic()
            {
                byte* send_buf = stackalloc byte[2];
                send_buf[0] = 0x02;  //pedimos al pic iniciar ADC
                send_buf[1] = 0;     // no iplementado
                EnvioPaquete(send_buf, 2);
            }
        }

        private void btnAbrir_Click(object sender, EventArgs e)
        {
            try
            {
                // CERRAMOS ENLACES ABIERTOS PARA INICIAR NUEVO ENLACE
                usbapi.CerrarPipes();
                // ABRIENDO NUEVO ENLACE
                usbapi.AbrirPipes();
                usbapi.LedPIC(0x00);
            }
            catch
            {
                MessageBox.Show("NO SE PUDO ABRIR ENLACE");
            }
            
        }

        private void btnCerrar_Click(object sender, EventArgs e)
        {
            usbapi.CerrarPipes();
        }

        private void btnRojo_Click(object sender, EventArgs e)
        {
            usbapi.LedPIC(0x01);
        }

        private void btnVerde_Click(object sender, EventArgs e)
        {
            usbapi.LedPIC(0x02);
        }

        private void btnADC_Click(object sender, EventArgs e)
        {
            usbapi.PideDatosPic();
            timer1.Start();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            usbapi.RecibirPaquetePic();
            textBox1.Text = usbapi.RecibirPaquetePic().ToString();
            this.listBox1.Items.Add(usbapi.RecibirPaquetePic().ToString());
        }

        private void btnPausa_Click(object sender, EventArgs e)
        {
            timer1.Stop();
        }
      
        
    }
}



Lo extraño de esto cuando hice el prog en c# que prendia y apagaba los led funcionao de maravillas, cuando le puse codigo para adquisicion de datos por el ADC mi prog ya no hace nada salvo enumerar y hacer conex con este pic, bueno sugerencias y sobre todo consejos seran bienvenidos

:LOL: [/b]
 
Que tal washi w z r, saliendome un poco del tema USB le comento sobre un detalle del ADC de 12 bits
hace unos días vengo trabajando con el pic 18f4523 el cual tambien maneja 12 bits de reslución en el ADC, mi aplicación consiste en leer el dato analogo que arroja un AD595 el cual acondiciona la señal de una termocupla tipo K, este por cada grado centigrado arroja 10 mV, bueno sin extenderme mucho, al visualizar los datos del ADC en una lcd, los visualizo con decimas de grados pero las decimas varian mucho es decir saltan por ejemplo de 1 a 7, de 3 a 9, etc y no se mantienen estables a una temperatura estable,

me gustaria saber si conoces algo sobre este pic y la forma correcta de m,anejar el adc para la resolución de 12 bits

gracias
 
Moyano Jonathan dijo:
Si alguien puede poner información sobre otg o algún código de ejemplo estaría buenisimo para que entre todos podamos realizar aplicaciones.
Hola

en la documentacion de microchip estan muchos ejemplos sobre el OTG, tienen ejemplos sobre CDC, HID, USB Mass Storage, USB printer.

si los abren esta el codigo y la documentacion.

salu2:)
 
Hola, yo tambien estoy desarrollando este tema del ADC , para que tu pic tenga una resol de 12bits colocas #DEVICE = 12 , aca te dejo un codigo

Código:
#include <18F4458.h>
#DEVICE ADC=12 // cad a 12 bits, justificación a a la derecha
#fuses XTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN,NOPBADEN
#use delay(clock=48000000)


#define DERECHA 0

#byte ADCON0 = 0xFC2
#byte ADRESL = 0xFC3 
#byte ADRESH = 0xFC4

#use standard_io(a)
void config_adcon2(short justificacion);
int h,l;
void Leer_ADC1(void)
{
     config_adcon2(DERECHA);
     set_adc_channel(0);
      bit_set(ADCON0,1);
      while(bit_test(ADCON0,1))
      h = ADRESH;
      l = ADRESL;
      output_b(h);  // bits bajos
      output_d(l);  //  bits altos
}

void main()
{
   setup_adc(ALL_ANALOG);
   set_tris_b(0x0);   //configura puertos como salidas
   set_tris_d(0x0);
   while(true)
   {
    Leer_ADC1();   
   
   }
}

//-----------------------------------------------------------------------------------------
// cumple la función de configurar el bit ADFM para hacer 
// la justificación, también se incluye el retardo por hardware de Tacq
// datos de entrada: bandera de justificación
// datos de salida: nada
//-----------------------------------------------------------------------------------------
void config_adcon2(short justificacion)
{
   setup_adc(ADC_CLOCK_DIV_64 );  // reloj de conversión = Fosc / 64
   if(justificacion){
    #asm
      bsf 0xFC0,7    // ADFM <- 1
    #endasm
   }
   else{
    #asm
     bcf 0xFC0,7   // ADFM <- 0
    #endasm
   }
   #asm          // configura Tacq = 2Tad
     bsf 0xFC0,3
     bcf 0xFC0,4
     bcf 0xFC0,5
   #endasm
}
El cod lineas arriba no me dio ningun problema, eso si te recomiendo que veas si el adc esta funcionando correctamente coloca led en el puerto B(B0 - B7) y al puerto D(D5-D7) (el codigo lineas arriba :LOL: realiza dicha operacion ) , a la entrada del pin RA1 coloca un potenciometro y mide la tension respectiva , una vez que estes seguro de tus tensiones ( en tu caso las variaciones ) sean las correctas, una vez asegurado esto los visualizaras en tu lcd .

Código:
#include <18F4458.h>
#DEVICE ADC=12 // cad a 12 bits, justificación a a la derecha
#fuses XTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN,NOPBADEN
#use delay(clock=48000000)


#define DERECHA 0

#byte ADCON0 = 0xFC2
#byte ADRESL = 0xFC3 
#byte ADRESH = 0xFC4

#use standard_io(a)
void config_adcon2(short justificacion);
int h,l;


float const resolucion=5.0/4096.0  // conversion 12bits


void main()
{
   float voltios;
   long valor;
   setup_adc(AN0);
   config_adcon2(DERECHA);
   set_adc_channel(0);   // canal 0 , por donde ingresan los datos
   while(true)
   {
    valor = read_adc();
    lcd_gotoxy(1,1);
    voltios = valor*resol;
    print(lcdputc,"%1.2f voltios",voltios);
    delay_ms(200);    //convierte cada 200ms
   }
}

//-----------------------------------------------------------------------------------------
// cumple la función de configurar el bit ADFM para hacer 
// la justificación, también se incluye el retardo por hardware de Tacq
// datos de entrada: bandera de justificación
// datos de salida: nada
//-----------------------------------------------------------------------------------------
void config_adcon2(short justificacion)
{
   setup_adc(ADC_CLOCK_DIV_64 );  // reloj de conversión = Fosc / 64
   if(justificacion){
    #asm
      bsf 0xFC0,7    // ADFM <- 1
    #endasm
   }
   else{
    #asm
     bcf 0xFC0,7   // ADFM <- 0
    #endasm
   }
   #asm          // configura Tacq = 2Tad
     bsf 0xFC0,3
     bcf 0xFC0,4
     bcf 0xFC0,5
   #endasm
}

Espero que los codigos te den una luz en tu camino jajajaaj , todo dependera ahora de ti , saludos
:LOL:
 
Hola Estoy implementando una aplicacion para el tema USB usando el 18F2550 en este caso de trata de un motor a pasos y una targeta de adquisicion de datos analogicos de 6 y 8 mas digitales, todo atraves del micro usando VB6 aunque es posible que lo transpase a .NET dado la modernidad. a la brevedad dare los resultados del codigo y algunas fotos y videos les agradesco por la informaciónrmacio he interes a todos, estare en contacto.
 

Adjuntos

me he descargado el ejemplo 1 para hacer algunas pruebas con el pero me topo con la sorpresa que al istalar el driver desde el panel de control me aprece una advertencia que dice que el puerto no se puede abrir (codigo 10), esto evita que lo detecte incluso el hiper terminal asi que al cargar el pic y conectarlo la computadora permanece inmutable tanto en vista como en XP he buscado algunas soluciones en la red pero too parece estar bien con el .INF amenos que se trate de un conflicto de version q no deveria, por favor si alguien ya hiso funcionar los ejemplos le pediria que me acesorara por que esto me tiene parado.

sigo en contacto.
 
Hola, yo tambien pase por lo mismo , pueden ser varias cosas , fijate bien si pusiste el capacitor electrolitico de 47uf adecuado en el pin Vbus ( que en pic 18f4550 es el pin 18) , si te compila bien el prog y no tienes problemas en grabar el prog en el pic , resvisa con detalle tu hardware.

El driver funciona de maravillas tanto en xp como en vista, mientras no le cambies o agreges mas definiciones de endpoint

AHH verifica si el VID yPID son los mismos

saludos.
 
Yo podría hacerlo, pero me complica mucho el tiempo. Además faltan por explicar algunos conceptos sobre USB, mas que nada el uso de unas funciones que no explique anteriormente.

PD: USB y Visual C# ya están dando sus primeros pasos pero me falta HID y Visual C#
 
Esos ejemplos ya los había visto, por ahora estoy viendo el VB 2008 para pasar todos los ejemplos de CDC USB y luego me voy a poner con HID en Visual C# o VC++. Por último ver el tema de Bulck transfer y hacer un manual recompilando todo lo visto.
 
hola jhonatan :
Asi es, pude enviar datos a la pc via USB con el pic18f4550 y con el pic18f4458, los recibo por cinco canales diferentes , ya que envio cinco señales analogicas , aqui una pequeña muestra , saludos
:cool:
 

Adjuntos