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

Lo que vamos a experimentar ahora es la detección del host por parte del PIC18F2550. En el ejemplo anterior vimos como detectar la conexión por software. Lo que se va a hacer en este ejemplo es que el PIC detecte la conexión del host.

Esta es la primera parte de la información sobre las librerías.

Como dije antes también vamos a ver que pasa con las librerías de control.

Viendo el código que utilizamos en los diferentes ejemplos hasta ahora propuestos, vemos que hay una librería:
Código:
// 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. (Librería que tenemos que ver)


La constante es el llamado al driver usb_cdc.h , pero esta a su vez llama a otras librerías.


Código:
/////////////////////////////////////////////////////////////////////////////
//
// Lo que hace esta parte es seleccionar la librería de control según el dispositivo que se haya seleccionado.
// por ejemplo si se pone: #include <18F2550.h> va a enlazar la librería: <pic18_usb.h> 
/////////////////////////////////////////////////////////////////////////////
#ifndef __USB_PIC_PERIF__
#define __USB_PIC_PERIF__	1
#endif

#if __USB_PIC_PERIF__
 #if defined(__PCM__)
  #error CDC Modo bulck requerido!  PIC16C7x5 solo puede comunicarse mediante HID (baja velocidad).
 #else
  #include <pic18_usb.h>   // Configuración de hardware para los PIC18Fxx5x
 #endif
#else
 #include <usbn960x.c>   // Configuración de hardware para los dispositivos National 960x
#endif
#include <usb_desc_cdc.h>	// Configuración y descriptores USB.
#include <usb.c>        // Tokens y handles usb.

Si observamos el código del ejemplo n°1, hay unas funciones de inicialización que hay que llamar para poder empezar a transmitir datos, una de ellas es:
Código:
usb_init(); // Inicializamos hardware USB del PIC18F2550.
Código:
si buscamos que hace esa función en pic18_usb.h tenemos:

void usb_init(void) {
   usb_init_cs(); 

   do {
      usb_task();
   } while (usb_state != USB_STATE_POWERED); // Llama a las funciones anteriormente descriptas siempre y
}                                                                           // cuando el USB , este conectado.

Si nos metemos dentro de usb_task()
Código:
/*****************************************************************************
/* usb_task()
/*
/* Función: Mantiene un ojo puesto sobre el SENSE pin para saber si el cable usb está o no conectado.
/*               Si está conectado inicializa el periferico si es requerido. Si no está conectado el cable desactiva el
/*               puerto usb del PIC.
/* Nota:     Si el SENSE pin no es definido en la programación del pic, el hardware usb se inicializa de forma
/*               automática.
/*           
/* Nota:     Esta función también habilita las interrupciones si el hardware usb está conectado.
/*  
/*
/*****************************************************************************/
void usb_task(void) {
   if (usb_attached()) { // Si el pic está conectado al host........

Como podemos ver esta función es muy importante para el desarrollo de la comunicación pic - host.

En esta función vemos hablar de un tal SENSE PIN que tiene que ser definido para que a través de este pin se detecte la conexión del host.

En la función usb_attached() se detallará la función del SENSE PIN. pero esto será en la 2° parte de la información.

Espero que les sirva. :cool:
 
Ahora estoy en un curso, cuando llegue a mi casa examino tus códigos.

Que sepas que unos usuarios me están examinando el código del manual para optimizarlo y reutilización de códigos entre otras cosas. Cosa que incluiré en el manual.

Mucha gente me pide que lo pase a Visual Basic 6 y 2008, cosa que haré cuando acabe todo. Mestoy peleando con Linux de C# que no se que pasa que no me abre el puerto serie... :cry:
 
estoy empezando a ver la programación en visual c# y estoy viendo la forma de migrar los ejemplos antes propuestos a este lenguje. meta sabés como se puede hacer para realizar estas funciones en visual c#:

El código es de visual basic 6.0:

Código:
Private Sub conectar_Click()
'comprueva que el puerto este cerrado para poder abrirlo
    If MSComm1.PortOpen = False Then
        'determina el puerto que hemos seleccionado.
        If COM_sel.ListIndex = 0 Then
            MSComm1.CommPort = 1
            End If
        If COM_sel.ListIndex = 1 Then
            MSComm1.CommPort = 2
            End If
        If COM_sel.ListIndex = 2 Then
            MSComm1.CommPort = 3
            End If
        If COM_sel.ListIndex = 3 Then
            MSComm1.CommPort = 4
            End If
        If COM_sel.ListIndex = 4 Then
            MSComm1.CommPort = 5
            End If
        If COM_sel.ListIndex = 5 Then
            MSComm1.CommPort = 6
            End If
        If COM_sel.ListIndex = 6 Then
            MSComm1.CommPort = 7
            End If
        If COM_sel.ListIndex = 7 Then
            MSComm1.CommPort = 8
            End If
        If COM_sel.ListIndex = 8 Then
            MSComm1.CommPort = 9
            End If
        If COM_sel.ListIndex = 9 Then
            MSComm1.CommPort = 10
            End If
        If COM_sel.ListIndex = 10 Then
            MSComm1.CommPort = 11
            End If
            End If
            
MSComm1.OutBufferSize = 1 'tamaño del dato a transmitir.
    MSComm1.InBufferSize = 23
    MSComm1.InputMode = comInputModeText 'los datos se recuperan en modo texto.
    MSComm1.InputLen = 23  ' BUFFER DE ENTRADA SE PUEDE DEJAR AL MAXIMO.
    MSComm1.PortOpen = True
    MSComm1.RThreshold = 23 'son 23 caracteres.
End Sub

Private Sub Form_Load()
COM_sel.AddItem "COM1"
COM_sel.AddItem "COM2"
COM_sel.AddItem "COM3"
COM_sel.AddItem "COM4"
COM_sel.AddItem "COM5"
COM_sel.AddItem "COM6"
COM_sel.AddItem "COM7"
COM_sel.AddItem "COM8"
COM_sel.AddItem "COM9"
COM_sel.AddItem "COM10"
COM_sel.AddItem "COM11"
COM_Sel.ListIndex = 0
End Sub

Private Sub MSComm1_OnComm()
Dim InBuff As String
Select Case MSComm1.CommEvent
    Case comEvReceive
    InBuff = MSComm1.Input
    Debug.Print InBuff
    Texto.Text = ""
    Texto.Text = Left$(InBuff, 23)  ' se recorta los caracteres basura
    MSComm1.PortOpen = False  'cierra el puerto y vacia el buffer
End Select
End Sub
 
Sigo estando en clase, le hecharé un ojo, pero en el VB6 no lo entiendo, solo algunas cosa, mientras tanto aquí lo puse por si hay ayuda de ellos.

http://foros.elguille.información/Mensajes.aspx?ID=46028

http://forums.microsoft.com/MSDN-ES/ShowPost.aspx?PostID=4227073&SiteID=11&mode=1

Con el tiempo te responderán, aún así le hecho un vistaso. Te hablo porque en estos momentos el profesor no está.

Suerte.

EDITO:
http://foro.elhacker.net/programacion_vb/pasar_de_vb6_a_c_yo_vb_net-t237914.0.html

http://foros.solocodigo.com/viewtopic.php?f=53&t=37799

http://www.forosdelweb.com/f79/pasar-vb6-c-vb-net-652474/#post2698550
 
ok me fijo en lo que pusiste y te digo. En Vb lo entiendo en visual c# estoy en la pag 135 de tu tuto y estoy viendo como es la programación . Luego te pregunto así no te molesto.
 
Jamás me molestas. Sólo que no conozco el VB6 y me quedo pescando... :eek:

Veo que vas demasiado rápdio en el manual, ya en 135.

Visual Basic .net
Código:
Dim mBuffer As Byte() = New Byte(0) {} 
mBuffer(0) = &H74 'ASCII letra "t". 
serialPort1.Write(mBuffer, 0, mBuffer.Length);

Saludo.

PD: He puesto más enlace aquí.
 
Por cierto. ¿Qué versión del manual tienes?

La actual es la Versión 1.1, comprueba en la página 472. Ya que la v1.1 se han corregidos faltas de ortorgrafías, errores tontos y sobre todo, se incluye enlace de cada ejemplo del Visual C#.


Ver manuales.
 
Dale meta ya me fijo en las correcciones que hiciste. Termine el proyecto del control de 8 relé por puerto USB. Lo que si voy a tener que hacer es ver la forma de optimizar el código ya que funciona pero de una manera muy lenta, es decir por ejemplo , cuando al pic le ordeno que prenda un relé apretando un botón en la aplicación no lo hace de forma inmediata, sino que tengo que realizar la acción de apretar el botón repetidas veces hasta que responde. (no se bien a que se debe el problema).

Acá esta el fuente del PIC y el código fuente de VB 6.0

Código:
// Programa de control de 8 relés por puerto USB, utilizando el PIC18F2550 y la clase CDC.
// Versión: 1.0 Fecha: 9/12/08.
// Programador: Moyano Jonathan.
//****************************************************************************************

// Definiciones varias.

#include <18F2550.h> // Definición de registros internos.
#fuses HSPLL,MCLR,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.
MCLR: Utilizamos reset por hardware.
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.
NOPBADEN: No utilizaremos el módulo de entradas análógicas del puerto B.
*/
#use delay(clock=48000000) // Frecuencia máxima de trabajo 48 Mhz.
#include "usb_cdc.h" // Descripción de funciones del USB.
#include "usb_desc_cdc.h" // Descriptores del dispositivo USB.

// Funciones que indican el estado de la  conexión usb.
void usb_conectado(void) {
output_high(PIN_A0);
output_low(PIN_A1);
}
void usb_desconectado(void) {
output_high(PIN_A1);
output_low(PIN_A0);
}
void usb_enumerado(void) {
output_high(PIN_A2);
}

// Programa principal:

void main() {
set_tris_a(0x00); // Configura al puerto A y al puerto B como salida.
set_tris_b(0x00);

// Configuraciones varias.
setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

// Iniciamos el USB.
usb_cdc_init(); // Funciones necesarias para iniciar el módulo USB.
usb_init(); // Funciones necesarias para iniciar el módulo USB.
while(!usb_cdc_connected()) { // Mientras el USB no esté conectado.
usb_desconectado();
}
usb_conectado();
do{
usb_task();
      if (usb_enumerated()){ // Si el puerto ya fue enumerado por el host :
      usb_enumerado(); // Enciende led de enumeración_OK.
      if(usb_cdc_kbhit()){ // en espera de nuevo(s) caracter(es) en el buffer.
        if(usb_cdc_getc()=='1'){ // ¿lo que llegó fué el caracter 1?
              output_toggle(PIN_B0); // Conmuta el estado del relé 1.
                   }
        if(usb_cdc_getc()=='2'){ // ¿lo que llegó fué el caracter 2?
              output_toggle(PIN_B1); // Conmuta el estado del relé 2.
                   }
        if(usb_cdc_getc()=='3'){ // ¿lo que llegó fué el caracter 3?
              output_toggle(PIN_B2); // Conmuta el estado del relé 3.
                   }
        if(usb_cdc_getc()=='4'){ // ¿lo que llegó fué el caracter 4?
              output_toggle(PIN_B3); // Conmuta el estado del relé 4.
                   }
        if(usb_cdc_getc()=='5'){ // ¿lo que llegó fué el caracter 5?
              output_toggle(PIN_B4); // Conmuta el estado del relé 5.
                   }
        if(usb_cdc_getc()=='6'){ // ¿lo que llegó fué el caracter 6?
              output_toggle(PIN_B5); // Conmuta el estado del relé 6.
                   }
        if(usb_cdc_getc()=='7'){ // ¿lo que llegó fué el caracter 7?
              output_toggle(PIN_B6); // Conmuta el estado del relé 7.
                   }
        if(usb_cdc_getc()=='8'){ // ¿lo que llegó fué el caracter 8?
              output_toggle(PIN_B7); // Conmuta el estado del relé 8.
                   }
           }
      }
   }while (TRUE); // bucle eterno
}

Las librerías usadas son las que ya usabamos anteriormente, al igual que el driver para windows.

El código fuente del programa para la pc es el siguiente.

Código:
Private Sub Form_Load()
MsgBox "PROGRAMA CREADO POR: Moyano Jonathan para Foros de electrónica"
Puerto.AddItem "COM1" ' Añadimos diferentes numeraciones para el puerto serie.
Puerto.AddItem "COM2"
Puerto.AddItem "COM3"
Puerto.AddItem "COM4"
Puerto.AddItem "COM5"
Puerto.AddItem "COM6"
Puerto.AddItem "COM7"
Puerto.AddItem "COM8"
Puerto.AddItem "COM9"
Puerto.AddItem "COM10"
Puerto.AddItem "COM11"
Puerto.ListIndex = 0   ' Configuramos COM1, como predeterminado.
Timer1.Interval = 50
Timer1.Enabled = True 'activamos el ciclo de escaneno del puerto.
evento.Text = "Seleccione un puerto y haga click en conectar."
End Sub
Private Sub conectar_Click()
'comprueva que el puerto este cerrado para poder abrirlo.
    If MSComm1.PortOpen = False Then
        'determina el puerto que hemos seleccionado.
        If Puerto.ListIndex = 0 Then
            MSComm1.CommPort = 1
            End If
        If Puerto.ListIndex = 1 Then
            MSComm1.CommPort = 2
            End If
        If Puerto.ListIndex = 2 Then
            MSComm1.CommPort = 3
            End If
        If Puerto.ListIndex = 3 Then
            MSComm1.CommPort = 4
            End If
        If Puerto.ListIndex = 4 Then
            MSComm1.CommPort = 5
            End If
        If Puerto.ListIndex = 5 Then
            MSComm1.CommPort = 6
            End If
        If Puerto.ListIndex = 6 Then
            MSComm1.CommPort = 7
            End If
        If Puerto.ListIndex = 7 Then
            MSComm1.CommPort = 8
            End If
        If Puerto.ListIndex = 8 Then
            MSComm1.CommPort = 9
            End If
        If Puerto.ListIndex = 9 Then
            MSComm1.CommPort = 10
            End If
        If Puerto.ListIndex = 10 Then
            MSComm1.CommPort = 11
            End If
            End If
            
    MSComm1.OutBufferSize = 1 'tamaño del dato a transmitir.
    MSComm1.InBufferSize = 23
    MSComm1.InputMode = comInputModeText 'Los datos se recuperan en modo texto.
    MSComm1.InputLen = 23  ' Buffer de entrada de 23 bytes (caracteres).
    MSComm1.PortOpen = True
    evento.Text = "Se ha conectado al puerto: COM" & MSComm1.CommPort
    MSComm1.RThreshold = 23 'Son 23 caracteres.
End Sub
Private Sub rele1_Click()
Timer1.Enabled = False
If MSComm1.PortOpen = True Then
If rele1.BackColor = &H8000000F Then
rele1.BackColor = &HFF00&
MSComm1.Output = "1"
evento.Text = "Se ha activado el relé N°1."
Else
rele1.BackColor = &H8000000F
MSComm1.Output = "1"
evento.Text = "Se ha desactivado el relé N°1."
End If
End If
Timer1.Enabled = True
End Sub
Private Sub rele2_Click()
Timer1.Enabled = False
If MSComm1.PortOpen = True Then
If rele2.BackColor = &H8000000F Then
rele2.BackColor = &HFF00&
MSComm1.Output = "2"
evento.Text = "Se ha activado el relé N°2."
Else
rele2.BackColor = &H8000000F
MSComm1.Output = "2"
evento.Text = "Se ha desactivado el relé N°2."
End If
End If
Timer1.Enabled = True
End Sub
Private Sub rele3_Click()
Timer1.Enabled = False
If MSComm1.PortOpen = True Then
If rele3.BackColor = &H8000000F Then
rele3.BackColor = &HFF00&
MSComm1.Output = "3"
evento.Text = "Se ha activado el relé N°3."
Else
rele3.BackColor = &H8000000F
MSComm1.Output = "3"
evento.Text = "Se ha desactivado el relé N°3."
End If
End If
Timer1.Enabled = True
End Sub
Private Sub rele4_Click()
Timer1.Enabled = False
If MSComm1.PortOpen = True Then
If rele4.BackColor = &H8000000F Then
rele4.BackColor = &HFF00&
MSComm1.Output = "4"
evento.Text = "Se ha activado el relé N°4."
Else
rele4.BackColor = &H8000000F
MSComm1.Output = "4"
evento.Text = "Se ha desactivado el relé N°4."
End If
End If
Timer1.Enabled = True
End Sub
Private Sub rele5_Click()
Timer1.Enabled = False
If MSComm1.PortOpen = True Then
If rele5.BackColor = &H8000000F Then
rele5.BackColor = &HFF00&
MSComm1.Output = "5"
evento.Text = "Se ha activado el relé N°5."
Else
rele5.BackColor = &H8000000F
MSComm1.Output = "5"
evento.Text = "Se ha desactivado el relé N°5."
End If
End If
Timer1.Enabled = True
End Sub
Private Sub rele6_Click()
Timer1.Enabled = False
If MSComm1.PortOpen = True Then
If rele6.BackColor = &H8000000F Then
rele6.BackColor = &HFF00&
MSComm1.Output = "6"
evento.Text = "Se ha activado el relé N°6."
Else
rele6.BackColor = &H8000000F
MSComm1.Output = "6"
evento.Text = "Se ha desactivado el relé N°6."
End If
End If
Timer1.Enabled = True
End Sub
Private Sub rele7_Click()
Timer1.Enabled = False
If MSComm1.PortOpen = True Then
If rele7.BackColor = &H8000000F Then
rele7.BackColor = &HFF00&
MSComm1.Output = "7"
evento.Text = "Se ha activado el relé N°7."
Else
rele7.BackColor = &H8000000F
MSComm1.Output = "7"
evento.Text = "Se ha desactivado el relé N°7."
End If
End If
Timer1.Enabled = True
End Sub
Private Sub rele8_Click()
Timer1.Enabled = False
If MSComm1.PortOpen = True Then
If rele8.BackColor = &H8000000F Then
rele8.BackColor = &HFF00&
MSComm1.Output = "8"
evento.Text = "Se ha activado el relé N°8."
Else
rele8.BackColor = &H8000000F
MSComm1.Output = "8"
evento.Text = "Se ha desactivado el relé N°8."
End If
End If
Timer1.Enabled = True
End Sub

Private Sub Timer1_Timer()
Dim a As String
On Error GoTo tratamiento_de_errores
DoEvents
If MSComm1.PortOpen = True Then
    DoEvents
    estado_grafico.BackColor = &HFF00&
    estado.Caption = "CONECTADO"
    Debug.Print "Conectado"
    MSComm1.PortOpen = False
    Exit Sub
Else
    DoEvents
    MSComm1.PortOpen = True
    Exit Sub
End If
tratamiento_de_errores: Debug.Print Err.Number & ": " & Err.Description
     Select Case Err.Number
        Case 8002   'Número de puerto no válido
            DoEvents
           estado_grafico.BackColor = &HFF&
           estado.Caption = "DESCONECTADO"
           evento.Text = "Número de puerto no válido"
        Case 8005 'el puerto ya está abierto
            DoEvents
           estado.BackColor = &HFF0000
           estado.Caption = ""
           evento.Text = "El puerto ya está abierto."
        Case 8012 '8012 el dispositivo no está abierto
            DoEvents
           estado.BackColor = &HFF&
           estado.Caption = "DESCONECTADO"
           evento.Text = "El puerto no está abierto."
        Case 8015
            DoEvents
            estado.BackColor = &HFF&
            estado.Caption = "DESCONECTADO"
    End Select
      Exit Sub
End Sub
Private Sub Form_Unload(Cancel As Integer)
    If MSComm1.PortOpen = True Then
        MSComm1.PortOpen = False
    End If
End Sub
Private Sub MSComm1_OnComm()
Dim InBuff As String
Select Case MSComm1.CommEvent
    Case comEvReceive
    InBuff = MSComm1.Input
    Debug.Print InBuff
   evento.Text = ""
   evento.Text = Left$(InBuff, 23)  ' Se recortan los caracteres basura.
    MSComm1.PortOpen = False  'Cierra el puerto y vacia el buffer.
End Select
End Sub

Meta lo de no molestarte era no molestarte en clase :cool:
 

Adjuntos

  • control_de_8_rels_por_usb_439.rar
    150.8 KB · Visitas: 1,877
¿Cuántas veces tienes que pulsar el botón para que te haga caso el USB?

Veo que vas progresando, ahora estoy con openSUSE 11.0 Luego pruebo tu aplicación.

Prueba con esto para que envía varias veces el mismo byte con un solo pulso del botón.
Código:
Dim mBuffer As Byte() = New Byte(10) {}
mBuffer(0) = &H74 'ASCII letra "t".
mBuffer(1) = &H74 'ASCII letra "t".
mBuffer(2) = &H74 'ASCII letra "t".
mBuffer(3) = &H74 'ASCII letra "t".
mBuffer(4) = &H74 'ASCII letra "t".
mBuffer(5) = &H74 'ASCII letra "t".
mBuffer(6) = &H74 'ASCII letra "t".
mBuffer(7) = &H74 'ASCII letra "t".
mBuffer(8) = &H74 'ASCII letra "t".
mBuffer(9) = &H74 'ASCII letra "t".
serialPort1.Write(mBuffer, 0, mBuffer.Length);

Si te funciona a la primera así me avisas, y si no también.
 
dale meta , esto del usb me tiene trabajando a full, veo que el código es para visual basic.net así que me voy a tener que migrar a ese lenguaje nomás a ver como me arreglo jejej . gracias por todo.

por los menos unas 6 veces, a veces me hace caso ahi nomas , pero es muy lento en la ejecución voy a ver como lo arreglo.

dependo casi exclusivamente de que te respondan en los foros donde has posteado los ejemplos en vb 6.0 así la migración del código va a ser directa
 
Prueba con Visual Basic .net 2008, quizás ya no tengas que actualizar desde cero con el .net si ya tienes el Visual C# ya instalado. Al menos tienes los dos.

El VB 6 cada vez notarás que está más obsoleto porque viene tecnologías nuevas y puertos nuevos, aparecerá el USB 3 dentro de no se cuando y no se si será compatible, al menos en Visual Basic .net 201x cuando salga si.

PD: Veo que tendré que acostumbrarme al Visual Basic también y no tengo ni idea de manejarlo.
 
lo del usb 3.0 va a ser algo fuera de orbita estuve viendo las velocidades q va alcanzar y son enormes........ = no compatible con pic por lo menos hasta dentro de 15 años min...

fuera de eso me baje un programa que se llama easyHID y lo que hace es generarme toda la programación del pic y visual basic 6.0 para comunicarme con el protocolo hid programando en proton basic compiler para el pic y visual basic 6.0 para pc.......... eso será otro rollo.
 
A parte del USB 3, van a sacar el USB 4 a medio corto plazo. No tardarán mucho por no se que historia.

He leído por ahí que www.microchip.com y demás µC se va a incluir el USB 3.0 como ocurre con USB 2.0 en 18Fx550 y otros PIC.

PD: Todavía no doy palo en abrir un puerto serie con monoDevelop en openSUSE 11.0. Estoy armando una que no veas. Dejo el código fuente aquí por si algún visitante sabe y nos ayuda.

Me estoy llenvado por este enlace pero que va:
http://www.mono-project.com/HowToSystemIOPorts

Código:
// MainWindow.cs created with MonoDevelop
// User: metaconta at 23:01 08/12/2008
//
// To change standard headers go to Edit->Preferences->Coding->Standard Headers
//
using System;
using Gtk;
using System.IO.Ports; // Añadir este using.

public partial class MainWindow: Gtk.Window
{	
	private SerialPort miSerie; // miSerie.

	public MainWindow (): base (Gtk.WindowType.Toplevel)
	{
		Build ();
		
		//serialPort1 = new SerialPort("/dev/ttyS0",9600, Parity.None, 8, StopBits.Two);
		  miSerie = new SerialPort("/dev/ttyS0",9600, Parity.None, 8, StopBits.Two);
		
		// Abrir puerto mientra se ejecute la aplicación
            if (!miSerie.IsOpen)
            {
                try
                {
                    miSerie.Open();
                }
                catch (System.Exception ex)
                {
                   // MessageBox.Show(ex.ToString());
				   // label1.Text = ex.ToString();
				    entry1.Text = ex.ToString();
                }
            } 
	}
	
	protected void OnDeleteEvent (object sender, DeleteEventArgs a)
	{
		Application.Quit ();
		a.RetVal = true;
	}

	protected virtual void OnButtonTClicked (object sender, System.EventArgs e)
	{ 
		    byte[] mBuffer = new byte[1];
            mBuffer[0] = 0x74; //ASCII letra "t".
            miSerie.Write(mBuffer, 0, mBuffer.Length);
	}

	protected virtual void OnButtonBClicked (object sender, System.EventArgs e)
	{
		    byte[] miBuffer = new byte[1];
            miBuffer[0] = 0x62; //ASCII letra "b".
            miSerie.Write(miBuffer, 0, miBuffer.Length);
	}

	protected virtual void OnButtonAClicked (object sender, System.EventArgs e)
	{
		    byte[] mBuffer = new byte[1];
            mBuffer[0] = 0x61; //ASCII letra "a".
            miSerie.Write(mBuffer, 0, mBuffer.Length);
	}

	protected virtual void OnButtonLClicked (object sender, System.EventArgs e)
	{
		    byte[] mBuffer = new byte[1];
            mBuffer[0] = 0x6C; //ASCII letra "l".
            miSerie.Write(mBuffer, 0, mBuffer.Length);
	}

	protected virtual void OnButtonEspacioClicked (object sender, System.EventArgs e)
	{
		    byte[] mBuffer = new byte[1];
            mBuffer[0] = 0x20; //ASCII letra "Espacio".
            miSerie.Write(mBuffer, 0, mBuffer.Length);
	}
}

Al pulsar el botón cualquiera, em dice este error.
Exception in Gtk# callback delegate
Note: Applications can use GLib.ExceptionManager.UnhandledException to handle the exception.
System.IO.IOException: I/O Error
at System.IO.Ports.SerialPortStream..ctor (System.String portName, Int32 baudRate, Int32 dataBits, Parity parity, StopBits stopBits, Boolean dtrEnable, Boolean rtsEnable, Handshake handshake, Int32 readTimeout, Int32 writeTimeout, Int32 readBufferSize, Int32 writeBufferSize) [0x00075] in /usr/src/packages/BUILD/mono-1.9.1/mcs/class/System/System.IO.Ports/SerialPortStream.cs:49
at (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPortStream:.ctor (string,int,int,System.IO.Ports.Parity,System.IO.Ports.StopBits,bool,bool,System.IO.Ports.Handshake,int,int,int,int)
at System.IO.Ports.SerialPort.Open () [0x00078] in /usr/src/packages/BUILD/mono-1.9.1/mcs/class/System/System.IO.Ports/SerialPort.cs:563
at (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPort:Open ()
at MainWindow.OnButtonTClicked (System.Object sender, System.EventArgs e) [0x00000] in /home/metaconta/Prueba3/Prueba3/MainWindow.cs:45
at GLib.Signal.voidObjectCallback (IntPtr handle, IntPtr data) [0x0005c] in /usr/src/packages/BUILD/gtk-sharp-2.12.1/glib/Signal.cs:179
at GLib.ExceptionManager.RaiseUnhandledException(System.Exception e, Boolean is_terminal) in /usr/src/packages/BUILD/gtk-sharp-2.12.1/glib/ExceptionManager.cs:line 58
at GLib.Signal.voidObjectCallback(IntPtr handle, IntPtr data) in /usr/src/packages/BUILD/gtk-sharp-2.12.1/glib/Signal.cs:line 181
at GLib.Signal.voidObjectCallback(IntPtr , IntPtr )
at Gtk.Application.gtk_main()
at Gtk.Application.gtk_main()
at Gtk.Application.Run() in /usr/src/packages/BUILD/gtk-sharp-2.12.1/gtk/Application.cs:line 106
at Prueba3.MainClass.Main(System.String[] args) in /home/metaconta/Prueba3/Prueba3/Main.cs:line 18
 

Adjuntos

  • prueba3_931.zip
    6.1 KB · Visitas: 558
Di una mirada rápida al código que pusiste y no logro entender por que no te podés comunicar

ya el sueño me está haciendo ver puertos usb y códigos en el aire así que mañana sigo con todo el rollo del usb y veo si sigo viendo el manual que escribiste meta. La verdad me he dado cuenta que nosotros dos nada más estamos participando, me gustaría que alguien más de su opinión. Mañana espero poder postear los esquemas con los diferentes circuitos para hacer las pruebas.

PD: espero poder postear todo lo referente al pickit2
 
Bueno sigamos con la parte 2 del tema de la detección por parte del pic de la conexión del host.

Bueno veamos que hace la función usb_attached()

Código:
/******************************************************************************
/* usb_attached()
/*
/* Función: Regresa un 1 lógico si el puerto usb está conectado.
/*
/*****************************************************************************/
#if USB_CON_SENSE_PIN // Si el pin_Sense está definido..
 #define usb_attached() input(USB_CON_SENSE_PIN) // Define a la función usb_attached() = pin_sense = 1
#else // sino se definio el pin_sense.
 #define usb_attached() TRUE  // Define que el puerto usb igual está conectado, aunque (en realidad no sabe).
#endif


Entonces el SENSE_PIN lo que hace es detectar la conexión del host por hardware, puntualmente detecta el voltaje del puerto usb (VUSB), como lo muestra en la siguiente figura:

Código:
/////////////////////////////////////////////////////////////////////////////
//
// Si vas a usar el sense_pin definilo acá.  si no lo vas a usar salta el comentario.
// " Sin el pin (sense_pin) , no vas a saber si el dispositivo se ha desconectado del usb.
// 
//       La conexión a realizar es la siguiente:
//
//                             100k
//            VBUS-----+----/\/\/\/\/\----- (I/O PIN ON PIC)
//                     |
//                     +----/\/\/\/\/\-----GND
//                             100k
//
//        (Donde VBUS, es el pin 1 del puerto USB)
//
/////////////////////////////////////////////////////////////////////////////
#define USB_CON_SENSE_PIN PIN_B2  // RB2 definido como sense_pin.

En la función usb_attached() , me decía que si yo definía este pin. El dispositivo "sabría" cuando yo me conecto
o no al puerto usb.


en los ejemplos también verán esto:
Código:
while(!usb_cdc_connected()){
}

Esta función entra en bucle infinito hasta que el usb es conectado, pero como hace el host para reconocer esa
función aún dentro de ese bucle. ?

Bien la respuesta está en las Servicios de interrupciones del usb (SRI) , que son 2 y cuando se detecta la función se ejecuta uno de ellos.
Veamos el código de más abajo.

Código:
   enable_interrupts(INT_USB);
    enable_interrupts(GLOBAL);
    UIE=__USB_UIF_IDLE | __USB_UIF_RESET;  // Habilita las interrupciones IDLE and RESET.
    usb_state=USB_STATE_POWERED;

/***************************************************************************/

 usb_isr_rst() -> para el flag __USB_UIF_RESET
 usb_isr_uidle() -> para el flag __USB_UIF_IDLE

estas interrupciones de alguna manera me detectan la función y por lo tanto la conexión.

Viendo la definición para la función usb_task():

If you use connection sense, and the usb_init_cs() for initialization, then you must periodically call this function to keep an eye on the connection sense pin.
When the PIC is connected to the BUS, this function will then perpare the USB peripheral. When the PIC is disconnected from the BUS, it will reset the USB stack and peripheral. Will enable and use the USB interrupt.
Note: In your application you must define USB_CON_SENSE_PIN to the connection sense pin.

que traducido a criollo :LOL: sería:

Si usted usa el pin_sense, y la función usb_init_cs() para la inicialización, luego tendra que mantener puesto un ojo en el pin de sensado de conexión.
Cuando el pic es conectado al puerto usb, la función prepara el periférico usb. Cuando el pic es desconectado
del puerto usb, la función resetea el stack usb y resetea el periférico. Luego habilita las interrupciones del usb hasta que se detecte una nueva conexión.

bueno a la traducción le añadí un par de cosas para que se entendiera :cool:

Viendo en los ejemplos de comunicación con el puerto usb:
Código:
usb_cdc_init(); // Configuramos al puerto virtual.

esta función literalmente , es la que me configura el puerto serie virtual:

Código:
void usb_cdc_init(void) {
   usb_cdc_line_coding.dwDTERrate=9600; // Velocidad de comunicación: 9.6kbps
   usb_cdc_line_coding.bCharFormat=0;     //  formato de los bits ----?
   usb_cdc_line_coding.bParityType=0;      //  Paridad = none.
   usb_cdc_line_coding.bDataBits=8;        //  8 bits de datos.
   (int8)usb_cdc_carrier=0;                       // Activa la comprobación de carro.
   usb_cdc_got_set_line_coding=FALSE;
   usb_cdc_break=0;
   usb_cdc_put_buffer_nextin=0;
   usb_cdc_get_buffer_status.got=0;
   usb_cdc_put_buffer_free=TRUE;
}


Luego de que el pic haya detectado por hardware la conexión con el host, limpia el flag de interrupciones del puerto usb y activa nuevamente las interrupciones, como lo muestra el siguiente código:

Código:
if ((usb_state == USB_STATE_ATTACHED)&&(!UCON_SE0)) {
 UIR=0;
 UIE=0;
 enable_interrupts(INT_USB);
 enable_interrupts(GLOBAL);
 UIE=__USB_UIF_IDLE | __USB_UIF_RESET;  //enable IDLE and RESET USB interrupt
 usb_state=USB_STATE_POWERED;
 debug_usb(debug_putc, "\r\n\nUSB TASK: POWERED");

bueno hasta acá llega la parte 2 , me faltan algunas cosas más para definir con respecto a las interrupciones pero eso será en la parte 3. :cool:

espero les sirva.
 
He visto algunas empresas que trabajan con microcontroladores pic que ofrecen drivers customizados para trabajar con usb bajo software.......... es decir simulan un puerto usb para los pic's que no lo tienen.

deber ocupar algo de ram del micro......................y funcionar con la más bajas de las velocidades (HID)
 
voy a ver si consigo más información sobre ese libro a ver si lo puedo llegar a comprar aunque estoy con el tema de que me tengo que comprar un lcd 4 x 20 caracteres y no llego con la plata....

bueno el tema es que cada vez más se avanza en el desarrollo del puerto usb y hasta ahora los únicos que hemos participado somos nosotros ¿?¿? .

pd: Aporten sus ideas ........

meta : gracias por ayudarme con en el tema de la programación de la pc.

voy a ver si hoy reviso todos los post de usb que he hecho corrijo los errores y añado alguna cosita más
 
YO hace mucho que no toco nada por los estudios de la facultad, que encima hasta dentro de 2 años minino no veré nada de electrónica, pero en la próxima semana que ya entro en las vacaciones me toca empezar a jugar con la electrónica a ver si me puedo meter con esto del uso del USB con los pic que es algo que me entusiasmo bastante. En especial yo lo estaré haciendo para linux, aunque con lo que tengo pensado usar sera fácilmente portable a windows.
 
Atrás
Arriba