Autor Tema: Mis primeros pasos con el 18F4550  (Leído 149690 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5449
    • Electrónica Didacta
Re: Mis primeros pasos con el 18F4550
« Respuesta #15 en: 11 de Enero de 2007, 16:38:00 »
jeje, viendo todo aquello de las especificaciones de ese puerto, existen 2 mundos. el mundo real: donde el usuario simplemente conecta y listo y el otro mundo: todo lo que implica hacer las transmisiones de datos. 

La tendencia parece ser: mientras mas fácil es de usar, mas complejo será el protocolo y toda la filosofia de las capas y lo que ello conlleva.


Salu2
Pedro
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5449
    • Electrónica Didacta
Re: Mis primeros pasos con el 18F4550
« Respuesta #16 en: 15 de Enero de 2007, 12:53:27 »
Aquí hay otro ejemplito para ir aprendiendo y practicando con el módulo USB que trae el 18F4550, esta vez se va a utilizar la clase CDC ó Communications Devices Class, entrando un poquito en teoría, se puede decir que una clase USB es un grupo de dispositivos (o interfaces dentro de un dispositivo) con ciertas caracteristicas en común. Típicamente, dos dispositivos pertenecen a la misma Clase si ambos utilizan formatos similares en los datos que reciben o transmiten, o si ambos utilizan una misma forma de comunicarse con el sistema.

tal es el caso de esta clase que permite a la función(ó dispositivo) comunicarse con el COM virtual a través del controlador HOST de USB en la computadora.

nota: este tema sobre la teoría y funcionamiento del bus USB no es para digerirlo a la primera leida, pués también hay que estudiarlo al nivel del módulo que trae el PIC

en este ejemplo (ejemplo6_parte2) le vamos a decir al pic que envie un mensaje (string) a la computadora, siempre y cuando el software se lo ordene. El software se va hacer en visual basic y para ello abrimos el VB y pegamos un control activex, en el formulario y es el MSCOMM.ocx



pegamos varios controles hasta que nos queda esta pantalla:



como veran hay 2 botones cada uno para enviar la orden al pic y después éste, nos envie la respectiva cadena, dicha orden será un byte ó un caracter, posteriormente esa cadena se guardará en la caja de texto.

el código en VB
Código: [Seleccionar]
' ejemplo6_parte2 comunicación al PIC mediante el puerto virtual COM4 cuya transmisión
' real será por el USB enviando un caracter para confirmarle al PIC, la transmisión
' de una cadena de acuerdo al caracter enviado
' 12-ene-07
' Pedro - PalitroqueZ
Option Explicit

Private Sub Command1_Click()
    If MSComm1.PortOpen = False Then
        MSComm1.PortOpen = True
    End If
    MSComm1.Output = "x"
End Sub

Private Sub Command2_Click()
    If MSComm1.PortOpen = False Then
        MSComm1.PortOpen = True
    End If
    MSComm1.Output = "a"
End Sub

Private Sub Form_Load()
    MSComm1.CommPort = 4
    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 "presionaste el número 1"
   
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
    Text1.Text = ""
    Text1.Text = Left$(InBuff, 23)  ' se recorta los caracteres basura
    MSComm1.PortOpen = False  'cierra el puerto y vacia el buffer
End Select
End Sub


de este código hay varias cosas que decir, lo primordial es tener bien configurado al MSCOMM, como por ejemplo RThreshold y para evitar caracteres extraños o los famosos chr(10) y chr(13) recortar la cadena a 23 caracteres como en este caso.

Otra cosa que coloqué fué cerrar el puerto después de ejecutar el evento comEvReceive, entre otras cosas para limpiar el buffer, en fin es cuestión de que hagan los respectivos ensayos de acuerdo a cada situación.

ahora viene escribir el código para el PIC:

Código: [Seleccionar]
/* ejemplo6_parte2.c
   este ejemplo hace uso del módulo USB en modo CDC transmitiendo datos
   hacia un puerto COMx emulado en Windows
   adaptación del código original de RRCdcUSB de RedPic
                                                Pedro-PalitroqueZ   12/01/07
*/
#include <18F4550.h>
#fuses XTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN,NOPBADEN
#use delay(clock=48000000)

#include "usb_cdc.h"

void main() {
   usb_cdc_init();
   usb_init();
   while(!usb_cdc_connected()) {}
   // espera a detectar una transmisión de la PC (Set_Line_Coding)
   do{
      usb_task();
      if (usb_enumerated()){ 
         if(usb_cdc_kbhit()){ //en espera de nuevo(s) caracter(es) en el buffer
            if(usb_cdc_getc()=='x'){ //¿lo que llegó fué el caracter x?
               printf(usb_cdc_putc, "el 11111111111111111111\n\r");
               //si, entonces envía una cadena hacia el PC
             }
            if(usb_cdc_getc()=='a'){ //¿lo que llegó fué el caracter a?
               printf(usb_cdc_putc, "el 22222222222222222222\n\r");
               //si, entonces envía una cadena hacia el PC               
             }
         }
        }
       }while (TRUE); // bucle eterno
}

allí se puede apreciar que si el byte que llega es una "x", entonces se prepara para transmitir ese montón de unos, y si llega una "a" manda ese montón de does

ahora se procede a compilar,grabar el pic, revisar conexiones, etc. y probar la transmisión, pero ANTES hay que instalar la aplicación para la clase CDC, solo hay que clicar en un archivito llamado mchpcdc.inf.

como en este ejemplo, no se utilizará componentes adicionales, no hará falta alimentación externa y se puede hacer directamente desde Vusb

un videito:

ejemplo6_parte2.wmv

observen que si no hay COM4 el VB tira el error porque no encuentra dicho puerto, pero cuando conectamos el cable todo funciona, bueno ahí habría que aplicar una validación para saltar ese error usando un On Error GoTo.

conclusiones:
-con este ejemplo se pretende hacer transmisiones de PIC<->PC usando el puerto USB real pero mediante el COM virtual

- usando la clase CDC es una manera fácil y rápida de hacer comunicación con la computadora, ya que podemos tomar programas de VB ya hechos para el MSCOMM y que mediante una pequeña adaptación podemos transmitir por el USB. La programación para el PIC varía ligeramente.

Fuentes consultadas: (altamente recomendadas para leer)
-El USB desencadenado  CDC USB

-858 USB Introduction to Full-Speed USB


-Un paseo por los Dispositivos de Almacenamiento Masivo USB

sobre transmisión RS-232<->VB

-comunicacion RS232 en Visual Basic

-No recibo todos los caracteres en Visual Basic

-Tutorial sobre comunicacion serie

-Por casualidad, alguien tuvo este problema con rs232 ?


el adjunto está todo lo necesario para correr este ejemplo

Salu2
Pedro
« Última modificación: 30 de Octubre de 2007, 18:42:48 por PalitroqueZ »
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado elmasvital

  • Administrador
  • PIC24H
  • *******
  • Mensajes: 1713
Re: Mis primeros pasos con el 18F4550
« Respuesta #17 en: 15 de Enero de 2007, 22:24:13 »
fantastico palitroquez realmente te esta quedando bordao :)

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5449
    • Electrónica Didacta
Re: Mis primeros pasos con el 18F4550
« Respuesta #18 en: 23 de Enero de 2007, 11:20:43 »
Gracias elmasvital, esto ya debería llamarse una bitacora, el diario de un pic o algo así jajaja

Seguimos con el módulo USB y con la clase CDC, porque a mi pensar es una manera fácil de usar el cable USB sin meterse tanto en las capas de este protocolo, y la verdad esas librerias que trae el compilador CCS son las que se encargan de todo.

mirando por un momento ¿qué se hizo en el ejemplo anterior?, ¡nos ahorramos el circuito del MAX232!

en este ejemplo6_parte3 vamos a profundizar la transmisión de datos, se tomará el código del ejemplo anterior y se estudiará el comportamiento de las funciones

Código: [Seleccionar]
  usb_enumerated()
 usb_cdc_kbhit()
 usb_cdc_getc()
 usb_cdc_connected()

recordemos que usb_cdc_connected() detecta si el controlador host está enviando datos y usb_enumerated() es para que el PC detecte nuestro dispositivo ( ó función), pero eso no quiere decir que el pic hará otras actividades si el cable está enchufado ó no.

modificando el código de ejemplo6_parte2

Código: [Seleccionar]
/* ejemplo6_parte3.c
 en este ejemplo se tratará de concocer la configuración del dispositivo, cuando
 hay/no hay conexión con el PC mediante los comandos
 usb_enumerated()
 usb_cdc_kbhit()
 usb_cdc_getc()
 usb_cdc_connected()

   adaptación del código original de RRCdcUSB de RedPic
                                 Pedro-PalitroqueZ   14/01/07
*/
#include <18F4550.h>
#fuses XTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN,NOPBADEN
#use delay(clock=48000000)

#define use_portb_lcd TRUE

#include <lcd.c>
#include "usb_cdc.h"

void main(){
   usb_cdc_init(); // llamadas necesarias para iniciar el módulo USB
   usb_init();    // llamadas necesarias  para iniciar el módulo USB
   lcd_init();    // llamadas necesarias para iniciar la LCD
   while(!usb_cdc_connected()) {lcd_putc("\fUSB NO detectadO"); delay_ms(100);}  // para evitarme un retardo y que no parpadee la LCD
   // espera a detectar una transmisión de la PC (Set_Line_Coding)
   lcd_putc("\fUSB DeTectAdo"); delay_ms(600);
   do{
      usb_task();
      if (usb_enumerated()){
         lcd_putc("\fya enumerado\n");  // para evitarme un retardo y que no parpadee la LCD
         lcd_putc("USB ConeCtaDo");  // para evitarme un retardo y que no parpadee la LCD         
         delay_ms(800);         
         if(usb_cdc_kbhit()){ //en espera de nuevo(s) caracter(es) en el buffer
            if(usb_cdc_getc()=='a'){ //¿lo que llegó fué el caracter a?
               lcd_putc("\fdAto rEciBido\n");  // para evitarme un retardo y que no parpadee la LCD
               lcd_putc("de la PC");  // para evitarme un retardo y que no parpadee la LCD
               delay_ms(800); //tiene que ser mayor a 500mS para que no existan parpadeos
            }
         }
      }
   lcd_putc("\fEn El bUClE UsB");  // para evitarme un retardo y que no parpadee la LCD
   delay_ms(700);   
   }while (TRUE); // bucle eterno
}


allí incluí una pantalla LCD, el cuál me mostrará que sucede en determinado momento dentro del código, la idea es conocer que hace el pic cuando:

Código: [Seleccionar]
- no hay conexión
- conectado el cable USB
- ejecutando la aplicación VB
- enviando el dato hacia el dispositivo

y todo eso me lo mostrará en pantalla con unos lcd_putc que coloqué en lugares estrategicos, el código en VB lo modifiqué ligeramente, para que envie un caracter y no reciba ninguno. vamos a grabar el pic y a probar:

video

estos son los mensajes del LCD y las acciones que llevé a cabo:

        MENSAJES         ->           CASOS POSIBLES
- "USB no detectado" -> el cable USB SI está ó NO está enchufado al PC

- "USB detectado", "ya enumerado USB conectado", "en el bucle USB" -> sucede cuando ejecuto la aplicación en VB

- "dato recibido de la PC" -> sucede cuando clico en el botón 'enviando a al pic'

recomendación: pegar un switche doble para desconectar a D- D+, para no estar a cada rato sacando la extensión y hacer una reconexión fácil.

esto está correcto solo en función del código, pues una vez que entra dentro del bucle no sale, y siempre mostrará que está conectado aunque no sea cierto.

si cierro la aplicación de VB y la vuelvo a abrir hará todo OK, porque seguirá en el mismo bucle.

hay una cosa curiosa que sucedió cuando apliqué un reset al PIC, en administrador de dispositivos reaparece el COM, pero en el programita de VB, se cuelga y no me detecta jamás el puerto a menos que reconecte el cable USB de nuevo, ¿¿?? nueva incognita que tenemos.

la solución a este inconveniente se encuentra en este post. Esto se llamaría: conexión "en caliente" del lado del software, (ya está arreglado en el video)

el código en VB
Código: [Seleccionar]
' ejemplo6_parte2 comunicación al PIC mediante el puerto virtual COM4 cuya transmisión
' real será por el USB enviando un caracter para confirmarle al PIC, la transmisión
' de una cadena de acuerdo al caracter enviado
' 12-ene-07
' Pedro - PalitroqueZ

' el uso de bandera permite averiguar varios datos para confirmar el estado real
' de la conexión
Option Explicit
Dim value As Long
Dim bandera As Boolean


Private Sub Command2_Click()
    Timer1.Enabled = False
    If MSComm1.PortOpen = True Then
      MSComm1.Output = "a"
    End If
    Timer1.Enabled = True
End Sub


Private Sub Form_Load()
    MSComm1.CommPort = 4
    MSComm1.OutBufferSize = 1 'tamaño del dato a transmitir
   
    Timer1.Interval = 50
    Timer1.Enabled = True
    bandera = False
End Sub

Private Sub Form_Unload(Cancel As Integer)
If MSComm1.PortOpen = True Then
    MSComm1.PortOpen = False
End If
End Sub

Private Sub Timer1_Timer()
On Error GoTo paca
DoEvents
If MSComm1.PortOpen = True Then
    DoEvents
    lblestado.Caption = "Conectado"
    Debug.Print "Conectado"
    MSComm1.PortOpen = False
    Exit Sub
Else
    DoEvents
    MSComm1.PortOpen = True
    Exit Sub
End If
paca: Debug.Print Err.Number & ": " & Err.Description
     Select Case Err.Number
        Case 8002   'Número de puerto no válido
            DoEvents
           lblestado.Caption = "Desconectado"
        Case 8005 'el puerto ya está abierto
            DoEvents
            lblestado.Caption = "puerto abierto"
        Case 8012 '8012 el dispositivo no está abierto
            DoEvents
            lblestado.Caption = "Desconectado"
        Case 8015
            DoEvents    ' para evitar retardos en bucles
            lblestado.Caption = "Desconectado"
    End Select
      Exit Sub
End Sub

en el adjunto está todo.

lecturas recomendadas:

- AN956 Migrating Applications to USB from RS-232 UART with Minimal Impact on PC Software

- Emulating RS-232 over USB with PIC18F4550

continuará...

Salu2
Pedro
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado Slalen

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1079
    • Página web personal de Guillermo Herrero González
Re: Mis primeros pasos con el 18F4550
« Respuesta #19 en: 29 de Enero de 2007, 16:55:19 »
Que gran trabajo PalitroqueZ!!!!
Me está sirviendo de mucha ayuda "tus primeros pasos".
Necesito aprender a manejar este monstruito para mi proyecto de fin de carrera :?
Os cuelgo las traducciones que he hecho
Mis dudas las pongo en este post

Gracias por tu tiempo!!!!
Un saludo!!!

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5449
    • Electrónica Didacta
Re: Mis primeros pasos con el 18F4550
« Respuesta #20 en: 07 de Febrero de 2007, 17:59:28 »
Me alegra que te sirviera en algo toda esta habladera jaja :D

por cierto, gracias por las traducciones. normalmente en este entorno hay que pelear 2 batallas: la del idioma y la del tema en sí.


ya tengo listo todo este tema en formato chm, mejor arreglado, las imagenes a su tamaño normal, todos los adjuntos y videos y quisiera pedir su autorización para publicarlo, ya que hago mucha referencia a este foro y algunos de sus integrantes. (Diego RedPic, Jaime J1M, Mauricio Maunix y perdonen si me olvidé de alguno).

es mejor tener esta documentación en un solo archivo, para no estar bajando link que a posteriori sean rotos, malos, etc

Salu2
Pedro

La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: Mis primeros pasos con el 18F4550
« Respuesta #21 en: 07 de Febrero de 2007, 18:35:50 »
PalitroqueZ, por mi parte no veo inconvenientes en que subas un compendio de lo que hayas elaborado basándote en algo que yo haya dicho y/o comentado. 

Después de todo, no se trata de que "patentemos" las palabras cada frase que uno diga :)  :mrgreen:
- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado J1M

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1960
Re: Mis primeros pasos con el 18F4550
« Respuesta #22 en: 07 de Febrero de 2007, 18:45:20 »
Enorabuena Pedro :) la cosa va viento en popa!! Por mi parte no hay ningún problema para que hagas lo q quieras con códigos, direcciones, etc. Para eso estan, sigo pensando como el primer día, el conocimiento debe ser libre! ;)

Desconectado micro_cadaver

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2102
    • blog microembebidos
Re: Mis primeros pasos con el 18F4550
« Respuesta #23 en: 07 de Febrero de 2007, 18:56:16 »
ahora me pongo a estudiar, gracias palitroqueZ
a cosechar!!!... :P
pic32... ahi voy....
aguante el micro 16f84  !!!!

visita mi pagina: http://www.microembebidos.wordpress.com

Desconectado Kedutpic

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 219
    • Microelectronica
Re: Mis primeros pasos con el 18F4550
« Respuesta #24 en: 07 de Febrero de 2007, 21:23:46 »
 :mrgreen: Muy bueno tu aporte palitroquez , me has dejado sorprendido  :) , ahora me dan mas ganas de seguir estudiando sobre los pic18F.
Actel  -  VHDL un nuevo mundo por descubrir :D
Grupo de Microelectronica - CIDI - UTP
Visitanos en : http://ue.accesus.com

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5449
    • Electrónica Didacta
Re: Mis primeros pasos con el 18F4550
« Respuesta #25 en: 08 de Febrero de 2007, 12:18:22 »
Bueno aquí está amigos, lo revisé muchas veces en busca de errores ortográficos y otras cosas raras (si ven algo que está mal, les ruego que me notifiquen para corregirlo), es lo mismo que coloqué en este tema pero empaquetado y con TODO, esa es una costumbre mia la de organizar los apuntes que hago.

y no crean que eso termina allí, me falta 2 ejemplitos mas sobre el CDC, uno lo llevo a mitad de camino (estoy atascado con este por los momentos  :?)

lo que me faltaría por hacer:

- estudio del USB usando la librería ó biblioteca mpusbapi.dll mediante apis en VB.
- usar el CAD pero con el Reloj interno R-C y comprobar si hay mayor precisión poniendo el pic a dormir durante la conversión.
- hacer varios ejemplos en ensamblador usando las nuevas magnificas instrucciones que trae esta familia.


Salu2
Pedro

nota: el archivito se lleva 41Mb  :shock:, la razón: por los videos.

link corregido: el anterior se había cortado.
« Última modificación: 16 de Mayo de 2007, 17:35:28 por PalitroqueZ »
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado Slalen

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1079
    • Página web personal de Guillermo Herrero González
Re: Mis primeros pasos con el 18F4550
« Respuesta #26 en: 09 de Febrero de 2007, 08:58:42 »
Buenas!!
He colgado más cosas aqui:
* Un programa en visual basic para comunicarse con el PicUSB de J1M, es igual que el suyo pero en VB6, funciona con su placa y su firmware (es el estudio que te falta PalitroqueZ)
* Las librerías de C18 de microchip corregidas, su traducción y las abreviaturas traducidas
* Los programas de Microchip de comunicación con el USB (en C18)
* Las palabras de configuración para los PIC18Fxx5x de C18 (en inglés, todo se andará...)
* Actualizaciones con correcciones de alguno de los anteriores
Lo dicho, si veis algún fallo/errata, por favor ¡¡¡Decidlo!!!

Un saludo!! :mrgreen:
« Última modificación: 09 de Febrero de 2007, 09:02:31 por Slalen »

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5449
    • Electrónica Didacta
Re: Mis primeros pasos con el 18F4550
« Respuesta #27 en: 09 de Febrero de 2007, 11:47:53 »
Estupendo Slalen  :-/, ya tengo material para iniciar, hay un código por allí que hicieron y está en VB explicado y todo. no se si está en la web de J1M (no recuerdo donde fué que lo bajé), pero es adicional para empezar a estudiar.  8)

Después de varios dias de descanso y para poner a trabajar al subconsciente en esto del USB seguimos con este módulo, y ¿porqué? es que este módulo es la joya de la corona de este PIC, así que seguiré echandole mano hasta abarcar todo lo necesario para realizar una comunicación PIC<->PC básica.

ya en el ejemplo anterior dimos cuenta de como detectar una conexión por software, desde el punto de vista de un programa en la PC, ahora le toca el turno al hardware del PIC, es decir, que el pic debe detectar al host USB.

hay algo que pasé por alto, desde que empecé con estos ejemplitos del CDC, hay una constante:

Código: [Seleccionar]
#include <18F4550.h>
#fuses XTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN,NOPBADEN
#use delay(clock=48000000)

#include "usb_cdc.h"

void main() {
...

la constante es el llamado al driver usb_cdc.h y no crean que es el único archivo usado, si miran dentro de éste veran después de varias lineas:

Código: [Seleccionar]
#if __USB_PIC_PERIF__
 #if defined(__PCM__)
  #error CDC requires bulk mode!  PIC16C7x5 does not have bulk mode
 #else
  #include <pic18_usb.h>   //Microchip 18Fxx5x hardware layer for usb.c
 #endif
#else
 #include <usbn960x.c>   //National 960x hardware layer for usb.c
#endif
#include "rr2_USB_Cdc_Monitor.h" //USB Configuration and Device descriptors for this UBS device
#include <usb.c>        //handles usb setup tokens and get descriptor reports

como estamos usando el 18F4550 entonces se utilizará el driver pic18_usb.h y además el rr2_USB_Cdc_Monitor.h y el usb.c

caramba se usan varias librerias y estas a su vez llaman a otras.

por ejemplo la rr2_USB_Cdc_Monitor.h es la usb_desc_cdc.h que está en la carpeta driver en PICC, solo que está modificada para identificar nuestro dispositivo como queramos (esto lo explica el amigo RedPic en su página) de la que me interesa hablar es la librería pic18_usb.h

si observamos el código del ejemplo anterior hay unas funciones de inicialización que hay que llamar para poder empezar a transmitir datos, una de ellas es

Código: [Seleccionar]
usb_init();


si buscamos que hace esa función en pic18_usb.h tenemos:

Código: [Seleccionar]
void usb_init(void) {
   usb_init_cs();

   do {
      usb_task();
   } while (usb_state != USB_STATE_POWERED);
}


si nos metemos dentro de usb_task():

Código: [Seleccionar]
/*****************************************************************************
/* usb_task()
/*
/* Summary: Keeps an eye on the connection sense pin to determine if we are
/*          attached to a USB cable or not.  If we are attached to a USB cable,
/*          initialize the USB peripheral if needed.  If we are disconnected
/*          from the USB cable, disable the USB peripheral.
/*
/*          NOTE: If you are not using a connection sense pin, will automatically
/*                enable the USB peripheral.
/*
/*          NOTE: this enables interrupts once the USB peripheral is ready
/*
/*****************************************************************************/
void usb_task(void) {
   if (usb_attached()) {
...

analicen lo que dice esta función, ahí se habla de un tal connection sense pin que interesante, veamos que hace la función usb_attached():

Código: [Seleccionar]
...
/******************************************************************************
/* usb_attached()
/*
/* Summary: Returns TRUE if the device is attached to a USB cable
/*
/*****************************************************************************/
#if USB_CON_SENSE_PIN
 #define usb_attached() input(USB_CON_SENSE_PIN)
#else
 #define usb_attached() TRUE
#endif
...

uuhmmm esa función está hecha mediante definición y llama a su vez a un tal USB_CON_SENSE_PIN

haciendo una pausa, esto que estoy haciendo es analizando el código inversamente, es decir, mediante una simulación en el MPLAB voy observando donde cae cada llamado para así determinar esa parte del código que me interesa.

¿quién es ese USB_CON_SENSE_PIN? y ¿porque en mi simulación del MPLAB salta sin preguntar por él?. En la nota de arriba dice que si no se está usando, automáticamente se habilitará el módulo USB.

video1

la línea BTFSC 0xf6d, 0x3 está preguntando si USBEN=0, mientras que para el primer condicional no aparece su respectiva línea en asm.

ahora que recuerdo en el código que escribió el amigo J1M, aparece una descripción de ese USB_CON_SENSE_PIN
(también aparece en el ejemplo ex_usb_serial2.c que trae el CCS)

Código: [Seleccionar]
/////////////////////////////////////////////////////////////////////////////
//
// 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)
//
/////////////////////////////////////////////////////////////////////////////
//#define USB_CON_SENSE_PIN PIN_B2  //CCS 18F4550 development kit has optional conection sense pin
...

y se hace llamar antes que los drivers, quiere decir entonces que hay una forma de detectar (mediante hardware) cuando el host está conectado al PIC y es al sensar un voltaje en un pin establecido, especificamente el voltaje del bus USB (VBUS)

¡vamos a probar pues! usemos el pin RE3 ¿se acuerdan? el del MCLR que solo puede funcionar como entrada digital.

Código: [Seleccionar]
#define USB_CON_SENSE_PIN PIN_E3  //pin de MCLR

hay una cosa que es digna de hacerle un estudio, me refiero a la función       usb_task() que está dentro de usb_init(), si hacen la prueba y se ponen hacer la simulación con el MPLAB descubriran 2 diferencias habilitando/deshabilitando el conection sense pin, otra cosa importante hablando del ejemplo anterior sabemos que el código se encierra dentro de un while

Código: [Seleccionar]
...
   while(!usb_cdc_connected()){
...
}

pero y ¿porque el HOST puede seguir reconociendo a la función aún dentro de ese bucle? si miran dentro de usb_task veran este código:

Código: [Seleccionar]
...
      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;

 allí se está seleccionado/habilitando la fuente de interrupción USB y cuando se conecta la función al host, se ejecuta uno de los 2 servicios de interrupción de rutina (SRI) :
 
 
Código: [Seleccionar]
usb_isr_rst() -> para el flag __USB_UIF_RESET
 usb_isr_uidle() -> para el flag __USB_UIF_IDLE
 

esto de alguna manera reconecta a la función para que sea reconocida por el HOST. está interesante esta parte, vamos a ver adonde llegamos. ;)
 
nota: me gustaría conocer como se aplica la sentencia debug_usb()
 
leyendo en la ayuda del CCS tenemos que:

Código: [Seleccionar]
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.

usando el pin RE3 (no olviden cambiar el fuse a NOMCLR) como sense pin, vamos hacer unas simulaciones a ver que pasa

video2

noten que ahora si aparecen las lineas en asm que corresponden a if(usb_attached()){. allí está preguntando por el estado de RE3

prosigamos con el el MPLAB-SIM, vamos a tener que averiguar que ocurre si hay una interrupción

nota:
 
Código: [Seleccionar]
void usb_cdc_init(void) {
   usb_cdc_line_coding.dwDTERrate=9600;
   usb_cdc_line_coding.bCharFormat=0;
   usb_cdc_line_coding.bParityType=0;
   usb_cdc_line_coding.bDataBits=8;
   (int8)usb_cdc_carrier=0;
   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;
}

me huele a que en esta llamada se hace una especie de configuración tipo USART.

después de  activar el estímulo de RE3 caigo en este segmento de código:

Código: [Seleccionar]
...
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");

este código ya lo había puesto antes, pues bien, después de un largo rato no pude simular esa interrupción. :(

queda una cosa por averiguar: que esa interrupción debe ocurrir cuando hay un detached, es decir, se desconecta el HOST de la función, ¿porque digo esto?, porque si sigo simulando me doy cuenta que llego al bucle main y allí caigo en el bucle eterno

Código: [Seleccionar]
   while(!usb_cdc_connected()) { //bucle eterno
delay_cycles(1);}  // para evitarme un retardo y que no parpadee la LCD

leyendo en el driver pic18_usb.h sobre esta línea:

Código: [Seleccionar]
UIE=__USB_UIF_IDLE | __USB_UIF_RESET;  //enable IDLE and RESET USB interrupt


tenemos unos defines:

Código: [Seleccionar]
#define __USB_UIF_IDLE     0x10 -> bit 4
#define __USB_UIF_RESET    0x01 ->  bit 0

si nos vamos a la datasheet del 18F4550, pág 180 nos encontarmos un SFR llamado UIR



este SFR contiene los flags de los estados de interrupción seleccionados por UIE



con este par de bits lo que hacemos es seleccionar el par USB Reset Interrupt y Idle Detect Interrupt Enable bit

otro dato importante, si nos vamos a la descripción de ambos servicio de interrupción, veremos

para el RESET:

Código: [Seleccionar]
/*******************************************************************************
/* usb_isr_rst()
/*
/* Summary: The host (computer) sent us a RESET command.  Reset USB device
/*          and token handler code to initial state.
/*
/********************************************************************************/

para el estado IDLE:
/*******************************************************************************
/* usb_isr_uidle()
/*
/* Summary: USB peripheral detected IDLE.  Put the USB peripheral to sleep.
/*
/********************************************************************************/

nuevamente deduzco lo siguiente:
- que ambos casos sirven para detectar el estado HOST<->PIC.
como lamentablemente no puedo hacer la simulación, no me queda de otra que probar el código en el protoboard, pero haciendo unas modificaciones, el código quedará así:

Código: [Seleccionar]
/* ejemplo6_parte4_temp.c
 en este ejemplo se tratará se ordenará al PIC reconocer la detección del HOST USB de la PC

   adaptación del código original de RRCdcUSB de RedPic
                                 Pedro-PalitroqueZ   4/feb/07
*/
#include <18F4550.h>
#fuses XTPLL,NOMCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN,NOPBADEN
#use delay(clock=48000000)

#define use_portb_lcd TRUE

#define USB_CON_SENSE_PIN PIN_E3
#include <lcd.c>
#include "usb_cdc.h"

void main(){
   lcd_init();    // llamadas necesarias para iniciar la LCD
usb_cdc_init(); // llamadas necesarias para iniciar el módulo USB
   usb_init();    // llamadas necesarias  para iniciar el módulo USB
   while(!usb_cdc_connected()) { //bucle eterno
delay_us(500);
   }
   do{
    usb_task();
delay_us(500);
   }while (TRUE); // bucle eterno
}

y en el driver pic18_usb.h coloqué un par de lineas nuevas:

Código: [Seleccionar]
void usb_attach(void) {
   usb_token_reset();
lcd_putc("\fUSB CONECTADO");
delay_ms(100);
...
}

void usb_detach(void) {  //done
lcd_putc("\fUSB DESCONECTADO");
delay_ms(100);
...
}

nota: me molesta este warning que me sale en output:

Código: [Seleccionar]
>>> Warning 216 "C:\18F\ejemplo6_parte4\ejemplo6_parte4_temp.c" Line 31(0,1): Interrupts disabled during call to prevent re-entrancy:  (usb_token_reset)

después de revisar bien las conexiones, el .lst para ver si estan OK los fuses, se procede a grabar el PIC y a ensayar:

con el HOST:



sin el HOST:



¡arrg! que mala pata, se queda activado el USB CONECTADO aún después de desconectar al HOST :(

obviamente hay que revisar nuevamente a pic18_usb.h

vamos a repasar, según mi hipótesis para que el módulo USB arranque la función usb_task() debe esperar por el nivel alto en RE3 (proveniente de Vusb) y si ocurre selecciona/habilita la interrupción para los casos USB Reset e Idle Detect hasta aquí vamos bien, ahora ¿que debe ocurrir para que ocurra una de esas 2 interrupciones?

primero que nada si ocurre una interrupción el contador de programa se vá para:

Código: [Seleccionar]
#int_usb
void usb_isr() {
   if (usb_state==USB_STATE_DETACHED) return;   //should never happen, though
   if (UIR) {
      debug_usb(debug_putc,"\r\n\n[%X] ",UIR);
      if (UIR_ACTV && UIE_ACTV) {usb_isr_activity();}  //activity detected.  (only enable after sleep)

      if (UCON_SUSPND) return;

      if (UIR_UERR && UIE_UERR) {usb_isr_uerr();}          //error has been detected

      if (UIR_URST && UIE_URST) {usb_isr_rst();}        //usb reset has been detected

      if (UIR_IDLE && UIE_IDLE) {usb_isr_uidle();}        //idle time, we can go to sleep
      if (UIR_SOF && UIE_SOF) {usb_isr_sof();}
      if (UIR_STALL && UIE_STALL) {usb_isr_stall();}        //a stall handshake was sent

      if (UIR_TRN && UIE_TRN) {
         usb_isr_tok_dne();
         UIR_TRN=0;    // clear the token done interrupt., 0x190.3
      }    //a token has been detected (majority of isrs)
   }
}

ahí está otra vez el debug_usb(), me intriga saber como se usa??. esa línea es crucial porque se puede averiguar quien demonios fué el flag que se activó. voy a ser práctico, sustituiré a debug_usb por printf así:

Código: [Seleccionar]
printf(lcd_putc,"\f UIR= %X",UIR);
 delay_ms(500);

nota: en la ventana output me aparecen mas warnings misteriosos:

Código: [Seleccionar]
>>> Warning 216 "C:\18F\ejemplo6_parte4\ejemplo6_parte4_temp.c" Line 32(0,1): Interrupts disabled during call to prevent re-entrancy:  (@delay_ms1)
>>> Warning 216 "C:\18F\ejemplo6_parte4\ejemplo6_parte4_temp.c" Line 32(0,1): Interrupts disabled during call to prevent re-entrancy:  (lcd_send_nibble)
>>> Warning 216 "C:\18F\ejemplo6_parte4\ejemplo6_parte4_temp.c" Line 32(0,1): Interrupts disabled during call to prevent re-entrancy:  (lcd_send_byte)
>>> Warning 216 "C:\18F\ejemplo6_parte4\ejemplo6_parte4_temp.c" Line 32(0,1): Interrupts disabled during call to prevent re-entrancy:  (lcd_putc)

pero yo pa´lante como el burro testarudo cuando no quiere caminar, grabar el pic, probar y..

sin conetctar el HOST: USB CONECTADO
[1]conectando al HOST:  UIR= 10 y luego cambia a 01
[2]desconectando el HOST: UIR=54 y luego cambia a 44

y para rematar al poco tiempo me sale un mensaje del windows diciendo que no reconoce al dispositivo.

54-> 01010100
44-> 01000100

[1]: el flag correcto es USB reset
[2]: los flags involucrados son: start of frame, idle detect y  bus activity

señores, ¡esto se complicó! lo mejor es entrarle por otro lado, la experiencia que he tenido me dice que cuando algo se complica, es que por ahí no es la solución.

mirando por enésima vez el código principal veo que aparte de que hacen la llamada usb_task() dentro de usb_init() la hacen afuera , es decir, se puede usar estas funciones dentro de nuestro código como queramos.

esta usb_init es importante porque habilita o no el módulo USB, ¿y que tal si usamos esa función en vez de meternos con el driver?

para ello tendremos que quitar la linea:

Código: [Seleccionar]
while(!usb_cdc_connected()) { //bucle eterno

eso no nos importa por ahora, yo no voy a enviar datos al pic, ¡lo único que quiero es que el pic me diga si o no! :)

vamos a intentar ooootra vez:

Código: [Seleccionar]
/* ejemplo6_parte4_temp.c
 en este ejemplo se tratará se ordenará al PIC reconocer la detección del HOST USB de la PC

   adaptación del código original de RRCdcUSB de RedPic
                                 Pedro-PalitroqueZ   4/feb/07
*/
#include <18F4550.h>
#fuses XTPLL,NOMCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN,NOPBADEN
#use delay(clock=48000000)

#define use_portb_lcd TRUE

#define USB_CON_SENSE_PIN PIN_E3
#include <lcd.c>
#include "usb_cdc.h"

void main(){
lcd_init();    // llamadas necesarias para iniciar la LCD
usb_cdc_init(); // llamadas necesarias para iniciar el módulo USB
    usb_init();    // llamadas necesarias  para iniciar el módulo USB
   do{
    usb_task();
delay_us(500);
   }while (TRUE); // bucle eterno
}



simulación en MPLAB.wmv

en el video anterior quité lo relacionado a la pantalla LCD para resaltar la parte importante, pero al grabar el PIC se las puse de nuevo:

video en protoboard_e6p4v4.wmv

ahora si funcionó, aunque fuera por poleo (no veo ninguna interrupción aquí) pero algo es algo, ya sabemos que: con la función usb_task() podemos determinar el estado de conexión.
 
observación: el error que me apareció en el windows al no detectar el dispositivo en cierto tiempo se debió al retardo de 500mS que metí en #int USB
 
seguro alguien preguntará: ¿bueno pero si no habilito el sense pin hará lo mismo?. y yo le responderé que no, puesto que con esa deshabilitación, el módulo USB siempre estará encendido. (comprobado)

el problema no termina aquí, la idea principal es escribir un código donde se muestre el estado y que aparte realice otras actividades.


 
el adjunto con el fuente, circuito eléctrico, etc.

Salu2
Pedro

moraleja de este ejemplo: ¿a que vuelta se echa el perro?. R: a la última :)
« Última modificación: 09 de Febrero de 2007, 15:53:31 por PalitroqueZ »
La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: Mis primeros pasos con el 18F4550
« Respuesta #28 en: 09 de Febrero de 2007, 16:43:49 »
muy buen trabajo PalitroqueZ, mis felicitaciones.

Slalen nose si pudieras colocar todos los archivos del vb, para que los que se inician en ello tb aprendan sobre el software que va en la PC, estaria mas completo creo, si es que podes, weno gracias, adios!!
.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5467
    • Picmania by Redraven
Re: Mis primeros pasos con el 18F4550
« Respuesta #29 en: 09 de Febrero de 2007, 16:50:19 »
Pedro, déjame que te felicite por tu magnifico trabajo. Te está quedando de dulce.  :mrgreen:
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania