HOla amigos de TodoPIC, soy nuevo en este foro,
actualmente estoy desarrollando una aplicacion para comunicar informacion del PIC al PC y viceverza via USB, pues me he orientado gracias a un articulo que encontre por alli (internet) en donde se basaban en el trabajo que ustedes vienen realizando en este foro.
en mi proyecto inicialmente partimos con lo basico que en él estaba implementado (encender y apagar led´s con un PIC18f4550 desde una programa elaborado en java, ademas hacer la peticion de una respuesta de la version del firmware implementada en el PIC ).
ahora nosotros ademas hemos implementado en el proyecto la recepcion de datos por medio del Conversor Analogo Digital del PIC, estos datos son enviados al programa (en java) en el PC, ademas estamos manejando tres tipos de interrupciones (dos utilizando RTCC y timer1, y otra que es interrupcion externa en el pin B0).
nuestra inquietud sobre este proyecto esta en que la velocidad con la que se ejecutan los eventos (apagar y encender led) aveeces funciona y aveces no funciona, ademas cuando funciona tarda un tiempo no deseado en responder (aveces 3, 5 y hastya 10seg), cosa que no sucedia inicialmente.
estamos curiosos de saber lo que sucede, nos hemos preguntado si tal vez sera alguna opcion relacionada con la transferencia de datos via USB.
hemos incluso deshabilitado el codigo que nosotros hemos implementado adicional y funciona igual.
acontinuacion les dejamos nuestro codigo y el del archivo de cabecera que estamos utilizando:
CODIGO DEL ARCHIVO CABECERA: HEADER.H#IFNDEF __USB_DESCRIPTORS__
#DEFINE __USB_DESCRIPTORS__
#include <usb.h>
////////////////////////////////////////////////////////////////////////////////
///
/// start config descriptor
/// right now we only support one configuration descriptor.
/// the config, interface, class, and endpoint goes into this array.
///
////////////////////////////////////////////////////////////////////////////////
#DEFINE USB_TOTAL_CONFIG_LEN 32 // config+interface+class+endpoint
// configuration descriptor
char const USB_CONFIG_DESC[] = {
// config_descriptor for config index 1
USB_DESC_CONFIG_LEN, // length of descriptor size
USB_DESC_CONFIG_TYPE, // constant CONFIGURATION (0x02)
USB_TOTAL_CONFIG_LEN,0, // size of all data returned for this config
1, // number of interfaces this device supports
0x01, // identifier for this configuration. (IF we had more than one configurations)
0x00, // index of string descriptor for this configuration
0xC0, // bit 6=1 if self powered, bit 5=1 if supports remote wakeup (we don't), bits 0-4 reserved and bit7=1
0x32, // maximum bus power required (maximum milliamperes/2) (0x32 = 100mA)
// interface descriptor 0 alt 0
USB_DESC_INTERFACE_LEN, // length of descriptor
USB_DESC_INTERFACE_TYPE, // constant INTERFACE (0x04)
0x00, // number defining this interface (IF we had more than one interface)
0x00, // alternate setting
2, // number of endpoints, not counting endpoint 0.
0xFF, // class code, FF = vendor defined
0xFF, // subclass code, FF = vendor
0xFF, // protocol code, FF = vendor
0x00, // index of string descriptor for interface
// endpoint descriptor
USB_DESC_ENDPOINT_LEN, // length of descriptor
USB_DESC_ENDPOINT_TYPE, // constant ENDPOINT (0x05)
0x81, // endpoint number and direction (0x81 = EP1 IN)
0x02, // transfer type supported (0 is control, 1 is iso, 2 is bulk, 3 is interrupt)
USB_EP1_TX_SIZE,0x00, // maximum packet size supported
0x01, // polling interval in ms. (for interrupt transfers ONLY)
// endpoint descriptor
USB_DESC_ENDPOINT_LEN, // length of descriptor
USB_DESC_ENDPOINT_TYPE, // constant ENDPOINT (0x05)
0x01, // endpoint number and direction (0x01 = EP1 OUT)
0x02, // transfer type supported (0 is control, 1 is iso, 2 is bulk, 3 is interrupt)
USB_EP1_RX_SIZE,0x00, // maximum packet size supported
0x01, // polling interval in ms. (for interrupt transfers ONLY)
};
////////////////////////////////////////////////////////////////////////////////
//******************* BEGIN CONFIG DESCRIPTOR LOOKUP TABLES ********************
// since we can't make pointers to constants in certain pic16s, this is an offset table to find
// a specific descriptor in the above table.
////////////////////////////////////////////////////////////////////////////////
// NOTE: DO TO A LIMITATION OF THE CCS CODE, ALL HID INTERFACES MUST START AT 0 AND BE SEQUENTIAL
// FOR EXAMPLE, IF YOU HAVE 2 HID INTERFACES THEY MUST BE INTERFACE 0 AND INTERFACE 1
#define USB_NUM_HID_INTERFACES 0
//
////////////////////////////////////////////////////////////////////////////////
// the maximum number of interfaces seen on any config for example, if config 1
// has 1 interface and config 2 has 2 interfaces you must define this as 2
#define USB_MAX_NUM_INTERFACES 1
//
////////////////////////////////////////////////////////////////////////////////
//define how many interfaces there are per config.
- is the first config, etc.
const char USB_NUM_INTERFACES[USB_NUM_CONFIGURATIONS]={1};
#if (sizeof(USB_CONFIG_DESC) != USB_TOTAL_CONFIG_LEN)
#error USB_TOTAL_CONFIG_LEN not defined correctly
#endif
////////////////////////////////////////////////////////////////////////////////
///
/// start device descriptors
///
////////////////////////////////////////////////////////////////////////////////
//
//device descriptor
char const USB_DEVICE_DESC[] ={
USB_DESC_DEVICE_LEN, //the length of this report
0x01, //constant DEVICE (0x01)
0x10,0x01, //usb version in bcd
0x00, //class code (if 0, interface defines class. FF is vendor defined)
0x00, //subclass code
0x00, //protocol code
USB_MAX_EP0_PACKET_LENGTH, //max packet size for endpoint 0. (SLOW SPEED SPECIFIES

0xD8,0x04, //vendor id (0x04D8 is Microchip)
0x0B,0x00, //product id
0x01,0x00, //device release number
0x01, //index of string description of manufacturer. therefore we point to string_1 array (see below)
0x02, //index of string descriptor of the product
0x00, //index of string descriptor of serial number
USB_NUM_CONFIGURATIONS //number of possible configurations
};
//
////////////////////////////////////////////////////////////////////////////////
///
/// start string descriptors
/// String 0 is a special language string, and must be defined. People in U.S.A.
/// can leave this alone.
/// You must define the length else get_next_string_character() will not see the string
/// Current code only supports 10 strings (0 thru 9)
///
////////////////////////////////////////////////////////////////////////////////
//the offset of the starting location of each string.
//offset[0] is the start of string 0, offset[1] is the start of string 1, etc.
//
const char USB_STRING_DESC_OFFSET[]={0,4,20};
#define USB_STRING_DESC_COUNT sizeof(USB_STRING_DESC_OFFSET)
char const USB_STRING_DESC[]={
//string 0 Codificacion de la tabla ???
4, //length of string index
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
0x09,0x04, //Microsoft Defined for US-English
//string 1 --> la compañia del producto ???
16, //length of string index
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
'j',0,
'P',0,
'i',0,
'c',0,
'U',0,
's',0,
'b',0,
//string 2 --> nombre del dispositivo
18, //length of string index
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING)
'J',0,
'E',0,
'C',0,
'R',0,
' ',0,
'U',0,
'S',0,
'B',0,
};
#ENDIF
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
AHORA EL CODIGO CORRESPONDIENTE AL PROGRAMA PRINCIPALFIRMWARE 18F4550.C
#include <18F4550.h> // Declaracion del microcontrolador a utilizar
//#device *=8
#device ADC=16
#fuses HSPLL,NOMCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN // Configuracion del microcontrolador
// 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) // Configuracion del relog a utilizar
//#define use_portb_lcd TRUE // definir portb lcd
//#include <lcd.c> // Se declara periferico a utilizar -> LCD.
//#use rs232(baud=19200, xmit=PIN_C6,rcv=PIN_C7,stream=HOSTPC) // Se declara periferico a utilizar -> rs232.
///////////////////////////////////////////////////////////////////////////////////////////////////
// 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 INTS_PER_SECOND 30 // (4000000/(2*256*256))
#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 (activacion de traferencia masiva en USB configurando el EndPoint 1 de transmision)
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK // turn on EP1(EndPoint1) for OUT bulk/interrupt transfers (activacion de traferencia masiva en USB configurando el EndPoint 1 de recepcion)
#define USB_EP1_TX_SIZE 32 // size to allocate for the tx endpoint 1 buffer (tamaño del buffer de transferencia en la transmision entre 1 y 32 bytes para USB 2.0)
#define USB_EP1_RX_SIZE 32 // size to allocate for the rx endpoint 1 buffer (tamaño del buffer de transferencia en la recepcion entre 1 y 32 bytes para USB 2.0)
///////////////////////////////////////////////////////////////////////////////////////////////////
// Include the CCS USB Libraries. See the comments at the top of these
// files for more information
////////////////////////////////////////////////////////////////////////////////
#include <pic18_usb.h> // Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include <header.h> // Configuración del USB y los descriptores para este dispositivo
#include <usb.c> // Handles usb setup tokens and get descriptor reports
#include <stdlib.h>
#include <stdio.h> //
////////////////////////////////////////////////////////////////////////////////
//#define Enciende Output_High
//#define Apaga Output_Low
//#define Conmuta Output_Toggle
#define RecCommand recbuf[0] //
#define LedParam recbuf[1]
#define COMMAND_TEMPERATURA 1
#define COMMAND_LEDS 2
#byte PORT_E = 5
#define LedState PORT_E,2
////////////////////////////////////////////////////////////////////////////////
// RAM, RAM, RAM
////////////////////////////////////////////////////////////////////////////////
const int8 Lenbuf = 32; //32 //Longitud del Buffer de lectura en el puerto USB.
int16 conversion;//,min=0,max=1023; //Se declaran Variable enteras a 16Bits.
float temp; //Decalracion de una variable flotante.
char ctemp[5];
int8 recbuf[Lenbuf];
//char cLedParam;
int8 i=0;
int8 LedParam_copy=0;
//int8 sndbuf[Lenbuf];
BYTE int_count; // Número de interrupciones que faltan antes que haya transcurrido un segundo
////////////////////////////////////////////////////////////////////////////////
// M A I N
////////////////////////////////////////////////////////////////////////////////
#INT_RTCC
void Led_State() //Interrupción utilizada para el manejo del bit de estado.
{
if(--int_count==0)
{ output_bit(Pin_E2,!bit_test(LedState)); //Llega aquí cada segundo.
int_count=INTS_PER_SECOND;
}
}
#INT_TIMER1
void interrupcion_timer1(){
i++;
if (i==40){
output_d(0x00);
i=0;
}
set_timer1(0);
set_timer1(3036);
}
#INT_EXT //Interrupcion a aplicar cuando se active el sensor de movimiento
void sensor_movimiento_isr(){
if (LedParam_copy == 0x02){
output_d(0x00);
i=0;
}
else{
set_timer1(0);
setup_timer_1( T1_INTERNAL | T1_DIV_BY_8 );
output_d(0x01);
i = 0;
set_timer1(3036); // 256-(15/(4/48000000))
}
}
/**
#int_ext1 //Interrupcion a aplicar cuando se active el sensor de humo
void sensor_humo_isr(){
output_d(LedParam);
delay_ms(1000);
output_d(LedParam);
}
*/
//******************************************************************************
ConvenVoltio()
{
temp=((0.0078125*conversion)-0.5); //Calculo de la temperatura
sprintf(ctemp, "%f", temp); //Convierte un numero de tipo coma flotante a tipo cadena
//sprintf(cRecCommand, "%u", RecCommand);
//itoa(LedParam, 10, cLedParam);
return ctemp;
}
//******************************************************************************
void main(void){
delay_ms(500); //Retardo de 0.5 seg
usb_init(); //Inicializa el Modulo de Comunicacion USB
usb_task(); //
usb_wait_for_enumeration(); //Se situa en un bucle infinito mientras la comunicacion USB es enumerada
set_tris_a(0000001); //Configuracion del Pin A0 como entrada
set_tris_b(00001111); //Configuracion del Pin b0 como entrada
setup_adc(ADC_CLOCK_DIV_4); //
setup_adc_ports(AN0); //Configuracion del puerto como entrada Analoga
set_adc_channel(0); //Seleccion del canal de conversion en este caso el cero
int_count=INTS_PER_SECOND;
set_timer0(0);
setup_counters( RTCC_INTERNAL, RTCC_DIV_256 | RTCC_8_BIT );
// 48 mhz clock, no prescaler, set timer 0
// to overflow in 15seg
enable_interrupts(INT_RTCC); //
enable_interrupts(INT_TIMER1); //
enable_interrupts(INT_EXT); //
//ext_int_edge (L_TO_H);
//port_b_pullups(true);
//enable_interrupts(int_ext1); //
enable_interrupts(GLOBAL); //Inabilita las demas interrupciones
//do
while(true)
{
if(usb_enumerated()){ //¿El sistema operativo de la PC nos ha reconocidos como conectados y ha enumerado la Comunicacion USB?
if (usb_kbhit(1)){ //Verifica si se han recibido datos provenientes del PC
usb_get_packet(1, recbuf, Lenbuf); //Toma los dos bytes que llegan y los guarda en recbuf,
//y luego son guardos en RecCommand y LedParam respectivamente
if(RecCommand==COMMAND_TEMPERATURA){ //Verifica si el byte 0 (RecCommad) que llega es igual a COMMAND_FIRMWARE
usb_put_packet(1,ctemp,4,USB_DTS_TOGGLE); //Escribe en el Puerto USB el valor de la temperatura
//usb_put_packet(1,cLedParam,4,USB_DTS_TOGGLE); //Escribe en el Puerto USB el valor de recbuf
//printf("Data leida de USB: %u",LedParam); //Supuestamente envia el dato leido por el puerto RS232
//printf("Data leida de USB: %s",cLedParam); //Supuestamente envia el dato leido por el puerto RS232
//delay_ms(1000);
//printf("Data leida de USB: %s",Lenbuf);
}
if(RecCommand==COMMAND_LEDS){ //Verifica si el dato que llega es igual a COMMAND_LEDS
LedParam_copy = LedParam;
//output_d(LedParam); //Escribe por el puerto D los leds que va a encender
//printf("Data leida de USB: %u",recbuf);
//printf("Data leida de USB: %s",Lenbuf);
}
}
}
delay_us(10);
conversion = read_adc(); //Lectura del conversor del ADC
//printf("%Lu",conversion); //Formato de envio del valor de la temperatura por RS232
//setup_adc( ADC_OFF );
ConvenVoltio();
//usb_put_packet(1,temp,5,USB_DTS_TOGGLE); //Escribe en el Puerto USB la version del firmware
//printf(" %1.1f ",temp); //Formato de envio del valor de la temperatura por RS232
//printf(lcd_putc,"\f Temperatura: \n %1.1f oC ",temp); //Impresion del dato en la LCD
//delay_ms(100); //Retardo de 1 usegundo
//usb_token_reset();
}//while(true);
}