Error en comunicacion PIC18F4550 USB BULK

Llevo varios días con un problema de comunicación vía USB entre mi PC y un PIC18F4550.

El PC enumera el dispositivo y logro enviar (de la PC al PIC) exitosamente un dato y obtengo el resultado deseado, pero al momento de intentarlo de nuevo el PIC no responde.

He intentado cerrar la aplicación hecha para la PC y volverla a abrir, pero eso no arregla el problema. La única manera es desconectado el PIC de la PC. En verdad no entiendo cuál es el problema...

Las transmisiones que estoy haciendo son de 2 bytes nada mas, y según las pruebas que he realizado el problema se encuentra en que el comando USB_kbhit(1) solo "levanta" la primera vez...

Aqui les dejo el código con el que he estado batallando, estoy programando con CCS y mi cristal es de 20MHz:
Código:
#include <18F4550.h>
#fuses MCLR,HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN 
#use delay(clock=48000000)

#use fast_io(B) //para definir entadas y salidas del puerto B
#use fast_io(C) //para definir entadas y salidas del puerto C
#use fast_io(D) //para definir entadas y salidas del puerto D


#define abrir PIN_B7
#define alarma PIN_B6
#define dooropen PIN_B5
#define boton PIN_B4
#define TEST PIN_B3
#define conectado PIN_D0 //xxxxxxxxxxxxxxxxxxxxxxx///PARA PRUEBA


#define USB_HID_DEVICE     FALSE             //deshabilitamos el uso de las directivas HID
#define USB_EP1_TX_ENABLE  USB_ENABLE_INTERRUPT   
#define USB_EP1_RX_ENABLE  USB_ENABLE_INTERRUPT   
#define USB_EP1_TX_SIZE    2                 //size to allocate for the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE    2                 //size to allocate for the rx endpoint 1 buffer

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




int8 recibe[2];                  //declaramos variables
int8 envia[1];

int8 topen=1;  //programable
int8 talarma =5; //programable
int8 contal =0;

int8 divA=0;
int8 divB=0;
int8 divC=0;

int8 t1=0;
int8 t2=0;
int8 t3=0;
int8 t4=0;



void main(void)
{
   set_tris_b(0x33);
   set_tris_d(0x00);/////////////////////xxxxxxxxxxxxxxxxxxxxxxxxx/////////
   set_tris_c(0x00);//////////////////////xxxxxxxxxxxxxxxxxxxxxxxxxxxx////////
   OUTPUT_B(0);
   OUTPUT_D(0);////////////////////xxxxxxxxxxxxxxxxxxxxxx//////////
   OUTPUT_C(0);//////////////xxxxxxxxxxxxxxxxxxx///////////////////////
   
   
   enable_interrupts(INT_USB);  
   enable_interrupts(GLOBAL);
   

   

   output_low(conectado); //Apaga led para indicar que no ha sido detectado por pc

   usb_init_cs();  //inicializamos el USB
   
   
   while(TRUE){
      
     usb_task();                      //habilita periferico usb e interrupciones

       if(usb_enumerated())          //si el PicUSB está configurado
         {
          output_high(conectado);
          
          if (usb_kbhit(1))//si el endpoint de salida contiene datos del host
            {
             usb_get_packet(1, recibe, 2); 
             if(recibe[0] == 0xfe){
                topen = recibe[1];
               
             }
             if(recibe[0] == 0xff){
                talarma = recibe[1];
                
             }
             if(recibe[0] == 0xfd){
               output_high(abrir); 
               
               delay_ms(t1*1000);
               delay_ms(t2*1000);
               delay_ms(t3*1000);
               delay_ms(t4*1000);
               output_low(abrir);
             }
             recibe[0] = 0;    
             recibe[1] = 0;

             
 
         if(topen<65){
            t1=topen;
            t2=0;
            t3=0;
            t4=0;
         }
         else{
            divA = topen - 65;
            t1=65;
            
            if(divA>=65){
            divB= divA - 65;
            t2=65;
            }
            else{
            t2=divA;
            divB=0;
            divC=0;
            }
            
            if(divB>=65){
            divC= divB - 65;
            t3=65;
            }
            else{
            t3=divB;
            divC=0;
            }
            
            if(divC>=65){
            t4=65;
            }
            else
            t4=divC;
         }
         
         
         if(input(boton) == 1){
            output_high(abrir); 
            
            delay_ms(t1*1000);
            delay_ms(t2*1000);
            delay_ms(t3*1000);
            delay_ms(t4*1000);
            output_low(abrir);
            }
         if(input(dooropen) == 1){
            delay_ms(1000);
            if(contal<talarma-1)
               contal++;      
            else
               output_high(alarma);   
         }
         else {
            contal =0;
            output_low (alarma);
         }    
   }
}

Gracias de antemano :)
 
Hola, soy nuevo en este foro.
La cuestion es que tengo una duda sobre un proyecto que estoy realizando...
El proyecto consiste en enviar y recibir comandos via USB con transferencia tipo Bulk. La aplicacion usada en el PC Host esta hecha en JAVA y el codigo del PIC esta hecho en el compilador PIC CCS. El programa funciona correctamente cuando se emula con PROTEUS, sin embargo cuando lo intento hacer con el pic real solo envia y recibe una sola vez como si la instruccion USB_KBHIT(1) solo funcionara una vez.

Anexo el programa del pic:
Código:
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)


#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    32                // size to allocate for the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE    32                // size to allocate for the rx endpoint 1 buffer


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





const int8 Lenbuf = 64;

char Version[] = "fabian API PIC18F4550";
int  connected=0;

int8 recbuf[Lenbuf]; // VECTOR DE RECEPCION
//int8 sndbuf[Lenbuf]; // VECTOR DE SALIDA


void main(void) {

   delay_ms(500);
   connected=0;
   /*usb_init();
   usb_task();
  usb_wait_for_enumeration();*/
   enable_interrupts(global);
   

   while (TRUE)
   {
      usb_task();
      if(connected==0)
      {
            if(input(pin_d2)==1)
            {
               usb_init();
               usb_task();
               usb_wait_for_enumeration();
               connected=1;
               //output_high(pin_a0);
            }
      }
      if(connected==1)
      {
            if(input(pin_d2)==0)
            {
               //output_low(pin_a0);
               connected=0;
               usb_detach();
            }
      }
      if(connected==1)   
      {
            if(usb_enumerated())
            {
               
               if (usb_kbhit(1))
               {
                    output_toggle(pin_a0);   
                    //delay_ms(500);               
                    usb_get_packet(1, recbuf, 64);
                    if(recbuf[0]==1)
                    {
                       output_toggle(pin_a0);
                    }
                    if(recbuf[0]==2)
                    {
                        usb_put_packet(1,Version,21,USB_DTS_toggle);
                        
                        output_toggle(pin_a0);   
                        //delay_ms(500);
                        recbuf[0]=0;
                        
                    }
                    output_toggle(pin_a0);   
                    //delay_ms(500);
                    
                   
                    
                    
                    
               }
               
               
            }
      }
     
   }
}

Agradezco la respuesta, ya que he buscado mucho en la red y no he encontrado solucion.
Lo extraño es que en el simulador si funciona normalmente, sin importar las veces que se le pida el comando al PIC. Ademas, la unica forma de enviar mas de un paquete (en el circuito real) es reseteando el PIC.

Gracias espero respuestas...
 
Última edición por un moderador:
Buenos días... llevo bastante tiempo con este problema...

Trato de implementar un programa para Java con las librerías de JpicUSB

Hasta el momento todo OK, con el envío y recepción de data, el único problema es que... solamente puedo hacer una consulta al PIC, ya sea de entrada o salida (o de entrada+salida)

Estoy usando iface para Java.

Con métodos iface.Read / iface.Write / iface.WriteRead, sin embargo solo se logra la primera conexión

A nivel de PIC, estoy usando usb_put_packet / usb_get_packet (PIC18f4550)

Código:
#include <18F4550.h>
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,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 information
//
/////////////////////////////////////////////////////////////////////////////
#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 

//Debo entender que aquí la transmisión/recepción se habilita por el buffer 1 por medio de 
//interrupciones
#define USB_EP1_TX_SIZE 9 // size to allocate FOR the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE 32 // size to allocate FOR the rx endpoint 1 buffer

/////////////////////////////////////////////////////////////////////////////
//
// IF you are using a USB connection sense pin, define it here.  If you are
// not using connection sense, comment out this line.  Without connection
// sense you will not know IF the device gets disconnected.
//       (connection sense should look like this:
//                             100k
//            VBUS-----+----/\\/\\/\\/\\/\\----- (I/O PIN ON PIC)
//                     |
//                     +----/\\/\\/\\/\\/\\-----GND
//                             100k
//        (where VBUS is pin1 of the USB connector)
//
/////////////////////////////////////////////////////////////////////////////
///only the 18F4550 development kit has this pin
#define USB_CON_SENSE_PIN PIN_B2
#include <pic18_usb.h>
#include <header.h>      //USB Configuration and Device descriptors FOR this UBS device
#include <usb.c>        //handles usb setup tokens and get descriptor reports

const INT8 lenbuf = 1;
int8 recbuf[lenbuf]; 
int8 env[9];   
int8 env2[3];
int8 aux;
   
void main(VOID) 
{
   env[0] = 49; //1
   env[1] = 50; //2
   env[2] = 55; //7
   env[3] = 32; //___
   env[4] = 88;
   env[5] = 88;
   env[6] = 88;
   env[7] = 88;
   env2[0] = 48; //0
   env2[1] = 49; //1
   env2[2] = 47; // " / "
   
   delay_ms (500);
   output_high (PIN_C0);
   usb_init ();
   enable_interrupts (global);
   usb_wait_FOR_enumeration ();
   
   
   WHILE (TRUE)
   {
      aux = env[0];
      env[0] = env[1];
      env[1] = aux;
      WHILE(usb_enumerated ())
      {
         output_low (PIN_C0);
         output_low (PIN_D0);
         output_low (PIN_C2);
         output_high (PIN_C1);
         
         IF (usb_kbhit(1))         // Solo lee la primera vez
         {                        
            output_low (PIN_C1);
            output_high (PIN_C2);            
            usb_get_packet (1, recbuf, lenbuf) ;
            delay_ms(250);
            IF (recbuf[0] == 1)
            {
               usb_put_packet (1, env2, 3, USB_DTS_TOGGLE);
               output_high (PIN_D1);
               output_high (PIN_D2);
               delay_ms(250);
               //usb_put_packet (1, env2, 3, 0);
               //usb_put_packet (1, recbuf, 3, 0);
                              
            }

            ELSE IF (recbuf[0] == 127)
            {
               usb_put_packet (1, env, 8, USB_DTS_TOGGLE); //127_
               //usb_put_packet (1, env, 8, 0); //127_
               output_high (PIN_D3);
               output_high (PIN_D2);
               delay_ms(250);    
            }            
            //usb_put_packet (1, env, 3, USB_DTS_TOGGLE) ;
            output_low (PIN_C2);
            delay_ms(250);
         }
         usb_put_packet (1, env, 3, 0) ;
         delay_ms(500);
         output_high (PIN_C0);
         delay_ms (500);
         }
   }
}

Métodos usados para Envio,Recepción o Envio+Recepción desde JAVA

byte[] resp1 = iface.Read("vid_04d8&pid_000b",0,3,1000);
byte[] resp1 = iface.WriteRead("vid_04d8&pid_000b",0,dato,3,1000);
iface.Write("vid_04d8&pid_000b",0,out,1,0);

Espero puedan liberarme de este tormento...

Saludos y muchísimas gracias por anticipado. ...
 
Atrás
Arriba