/********************************************************************
Programa: Control de dispositivos por USB.
Descripción: HID - DEMO, programa para mostrar el uso del puerto USB
en proyectos de control.
Programador: Moyano Jonathan.
Hardware necesario: USB - PIC trainer v0.1 + PicKit2 clon.
Año: 2011.
*********************************************************************/
//=========================================================================
#include <18F4550.h> // Definición de registros internos del PIC18F2550.
//#DEVICE ADC=8 // CAD a 8 bits, justificación a a la derecha.
#DEVICE ADC=10 // CAD a 10 bits, justificación a a la derecha.
//#DEVICE ADC=16 // CAD a 10 bits, justificación a a la izquierda.
#fuses MCLR,HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN
// NOMCLR: No vamos ha usar el PIN MCLR, el reset se hará por software.
// HSPLL: Utilizaremos un cristal de alta velocidad en conjunto con el PLL.
// NOWDT: No vamos a usar el perro guardian.
// NOPROTECT: Memoria no protejida contra lecturas.
// NOLVP: No utilizamos el modo de programación con bajo voltaje.
// NODEBUG: No utilizamos código para debugear.
// USBDIV: signfica que el clock del usb se tomará del PLL/2 = 96Mhz/2 = 48Mhz.
// PLL1: significa que el PLL prescaler dividirá la frecuencia del cristal. para HS = 20Mhz, PLL = 5.
// con esto se obtiene: 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.
// NOPBADEN: Todo el Puerto B como I/O digitales.
// Usamos una frecuencia de trabajo de 48Mhz.
#use delay(clock=48000000)
//===========================================================================
//========================================================================================================
// Incluimos librerías utilizadas por la aplicación.
#include <pic18_usb.h> // Drivers's USB del PIC18F2550.
#include <APLICACION_HID.h> // Definición de funciones y hardware utilizado en el programa.
#include <Descriptor_easyHID.h> // Descriptores HID del proyecto.
#include <USB.c> // Funciones del USB.
#define USB_EP1_RX_SIZE 32
#define USB_EP1_TX_SIZE 32
#build(reset=0x1000,interrupt=0x1008) //Remapeo
#org 0x0000,0x0FFF {}
// Usamos fast_io, en los puertos B y C.
#use fast_io(b)
#use fast_io(c)
void USB_debug(){
LED_ON(LED_RED); // Enciende el led error y apaga el led USB_OK.
LED_OFF(LED_GREEN);
usb_wait_for_enumeration(); // Espera a ser enumerado por el host.
LED_ON(LED_GREEN); // Enciende el led USB_OK y apaga el led USB_ERROR.
LED_OFF(LED_RED);
}
void config_adcon2(void) {
#asm
movlw 0b10111110
iorwf 0xFC0,1
#endasm
}
int8 recibe[USB_EP1_RX_SIZE]; // Declaramos la variable recibe de 32 bytes.
int8 envia[USB_EP1_TX_SIZE]; // Declaramos la variable envía de 32 bytes.
int8 valorPWM1_H=0; // Valor del semiperiodo alto del PWM1.
int8 valorPWM2_H=0; // Valor del semiperiodo alto del PWM2.
int8 valorPWM1_L=0; // Valor del semiperiodo bajo del PWM1.
int8 valorPWM2_L=0; // Valor del semiperiodo bajo del PWM2.
int8 valorPWM1=0; // Variable que contiene el valor del PWM1.
int8 valorPWM2=0; // Variable que contiene el valor del PWM2.
int8 valor_adc_alta=0; // Contiene el MSB del valor del ADC.
int8 valor_adc_baja=0; // Contiene el LSB del valor del ADC.
//===========================================================================================================
// Variables globales.
void main(void) // Función Principal.
{
// Configuraciones varias.
set_tris_b(0xF0); // Nibble bajo salidas, el alto entradas.
output_b(0x00); // Inicializamos las salidas a 0.
set_tris_c(0b00111000); // RC0,RC1,RC2,RC6,RC7,como salidas. Las demás Rc3
// RC4,RC5, como entradas.
setup_adc_ports(AN0_TO_AN2); // Configura canales usados por el ADC.
setup_adc(ADC_CLOCK_DIV_64); // Asigna la velocidad: relog\64.
config_ADCON2(); // Configuramos el ADCON2.
LED_OFF(PWM1); // Apagamos ambos canales PWM.
LED_OFF(PWM2);
usb_init(); // Inicializamos el stack USB.
usb_task(); // Habilita el periferico usb y las interrupciones.
USB_debug(); // Nos muestra el estado de conección del USB.
while (TRUE) // Bucle infinito.
{
if(usb_enumerated()) // Si el dispositivo está configurado...
{
// PWM por software correspondiente al canal 1.
valorPWM1_H=valorPWM1;
valorPWM1_L=255-valorPWM1_H;
for(valorPWM1_H;valorPWM1_H>0;valorPWM1_H--){
LED_ON(PWM1);}
for(valorPWM1_L;valorPWM1_L>0;valorPWM1_L--){
LED_OFF(PWM1);
}
// PWM por software correspondiente al canal 2.
valorPWM2_H=valorPWM2;
valorPWM2_L=255-valorPWM2_H;
for(valorPWM2_H;valorPWM2_H>0;valorPWM2_H--){
LED_ON(PWM2);}
for(valorPWM2_L;valorPWM2_L>0;valorPWM2_L--){
LED_OFF(PWM2);
}
// Leemos el estado de los pulsadores.
if(input_state(SW1)==0x01){delay_ms(20); envia[0]=0x01;}else{envia[0]=0x00;}
if(input_state(SW2)==0x01){delay_ms(20); envia[1]=0x01;}else{envia[1]=0x00;}
if(input_state(SW3)==0x01){delay_ms(20); envia[2]=0x01;}else{envia[2]=0x00;}
if(input_state(SW4)==0x01){delay_ms(20); envia[3]=0x01;}else{envia[3]=0x00;}
// Leemos 2 canales analógicos del PIC.
set_adc_channel(0); // Seleccionamos el canal 0 y comenzamos a leer.
delay_us(10); // Esperamos un tiempo para estabalizar el dato leido.
valor_adc_alta = (read_adc()>>8); // Enviamos la parte alta de la conversión de 10 bits.
valor_adc_baja = (int)(read_adc()); // Enviamos la parte baja de la conversión de 10 bits.
envia[4]=valor_adc_alta;
envia[5]=valor_adc_baja;
set_adc_channel(2); // Seleccionamos el canal 2 y comenzamos a leer.
delay_us(10); // Esperamos un tiempo para estabalizar el dato leido.
valor_adc_alta = (read_adc()>>8); // Enviamos la parte alta de la conversión de 10 bits.
valor_adc_baja = (int)(read_adc()); // Enviamos la parte baja de la conversión de 10 bits.
envia[6]=valor_adc_alta;
envia[7]=valor_adc_baja;
usb_put_packet(1, envia, USB_CONFIG_HID_TX_SIZE, USB_DTS_TOGGLE); // Enviamos el paquete de datos por USB.
if (usb_kbhit(1)) // Si hay un paquete de datos del host.. en el buffer lo tomamos y guardamos en la variable data.
{
usb_get_packet(1, recibe, USB_CONFIG_HID_RX_SIZE); // En el buffer lo tomamos del EP1 y lo guardamos en la variable recibe....
if(recibe[0]==ACTIVA_SALIDAS){ // Si recibe comando de control de salidas...
switch(recibe[1]){ // Según el dato que recibe, activa o desactiva los led's.
case LED_1:
output_toggle(PIN_B0); // Cambia de estado el LED1.
break;
case LED_2:
output_toggle(PIN_B1); // Cambia de estado el LED2.
break;
case LED_3:
output_toggle(PIN_B2); // Cambia de estado el LED3.
break;
case LED_4:
output_toggle(PIN_B3); // Cambia de estado el LED4.
break;
}
}
if(recibe[0]==PWM_CONTROL1) // Si recibimos el comando de control PWM1..
{valorPWM1=recibe[2];} // Tomamos el dato y lo procesamos.
if(recibe[0]==PWM_CONTROL2) // Si recibimos el comando de control PWM2..
{valorPWM2=recibe[3];} // Tomamos el dato y lo procesamos.
}
}
}
}
aca va el C#
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 = 1781;
public const UInt32 PRODUCT_ID = 07D0;
public const int BUFFER_IN_SIZE = 32;
public const int BUFFER_OUT_SIZE = 32;
// 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;
}
}
}
Cambio de vid,pid
namespace MecaniqueUK
{
class EasyHID
{
// HID specific...
public const UInt32 VENDOR_ID = 1781;
public const UInt32 PRODUCT_ID = 07D0;
public const int BUFFER_IN_SIZE = 32;
public const int BUFFER_OUT_SIZE = 32;
#ifndef __USB_DESCRIPTORS__
#define __USB_DESCRIPTORS__
#ifndef USB_CONFIG_PID
#define USB_CONFIG_PID 0x07D0 // PID easyHID, configurado por el usuario.
#endif
#ifndef USB_CONFIG_VID
#define USB_CONFIG_VID 0x1781 // VID easyHID, configurado por el usuario.
#endif