desktop

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

Hola, soy nuevo por acá.
Estoy probando los ejemplos pero nada parece andar.
Hace un por de días que probé el primer ejemplo y me funciono perfecto después probé el ejemplo que moyano: "Joistick USB con PIC18F2550 1 analógico + 8 botones" y me funciono perfecto pero cuando trate de volver a los ejemplos de este hilo la pc me empezó a poner que no se reconoce el dispositivo. Lo raro es que si grabo el pic con el ejemplo del joystick (HID) anda perfecto.
La verdad ya se me están acabando las ideas, así que cualquier ayuda se las voy a agradecer mucho.

Saludos, Damián

PD1: Ya probé montones de valores para el capacitor de VUSB ahora estoy con uno de 10uF de tantalio.

PD2. Gracias por el tema, esta todo muy bien explicado.
 
Si te ha funcionado antes , es problema de la PC no de los ejemplos. Algo que hay que tener en cuenta es cuando uno conecta un dispositivo USB la PC toma los descriptores del dispositivo y crea un archivo que guarda en el registro para que cada vez que el usuario conecte el dispositivo este no pida los drivers continuamente y se enumere de forma automatica.

El problema recae en cuando uno ha conectado y desconectado muchos dispositivos con el mismo descriptor y diferente driver o funcionamiento pueden aparecer conflictos de software. Que te soy sincero la única opción que hay es formatear la máquina o buscarte un programa para limpiar los driver's USB ...si buscas en la red seguro los encontras.

El capacitor de Vusb ha sido comentado ampliamente y te digo que no es critico siempre y cuando tenga un valor de 470nf para arriba.
 
Hola Moyano:

Por lo que cuentas, sigues en el tema del ID y no se que más historias para no tener problemas en el futuro. Al menos que reconozca el nombre del dispositivo.

Si sigues en el mundo de la EEPROM puedes dejarlo para más adelante, ya que me encanta la parte del 8 entradas y salidas digitales, analógicas, etc.

Saludo.
 
Hola a todos. Estoy probando un programa con el PIC18F4550, para la comunicación por USB clase CDC. El programa que uso como entorno es el HYPERTERMINAL. El programa anda muy bien en el envio de datos (PIC-PC), pero cuando intento realizar el envio de datos al reves (PC-PIC) nunca recibo los caracteres. Este es el programa. Cuando preciono la 'x' para recibir el dato, nunca funciona. Muchas gracias.



#include <18F4550.h>

#fuses HSPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL3,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.
#include "usb_desc_cdc.h" // Descriptores del dispositivo USB.



void main() {

float medicion;
usb_cdc_init(); // Configuramos al puerto virtual.
usb_init(); // Inicializamos el stack USB.

setup_adc_ports (all_analog);
setup_adc (adc_clock_internal); //enciende adc
set_adc_channel(0); //elige canal a medir RA0
delay_us(10);


while(!usb_cdc_connected()) { // Mientras el USB no esté conectado.
output_high(PIN_B6); // Función USB no detectada. (Enciende LED rojo)
output_low(PIN_B7); // (Apaga LED verde)
}

// espera a detectar una transmisión de la PC (Set_Line_Coding).

output_high(PIN_B7); // Función USB detectada. (Enciende LED verde)
output_low(PIN_B6); // (Apaga LED rojo)

printf(usb_cdc_putc, "Dispositivo USB_CDC\n\r");
do{

usb_task();
if (usb_enumerated()){ // Espera a que el dispositivo sea enumerado por el host
// medicion=read_adc();
// printf(usb_cdc_putc, "Dispositivo USB_CDC\n\r");
// delay_ms(2000);
// printf(usb_cdc_putc, "Emilio D'Olivo\n\r");
// delay_ms(2000);
// printf(usb_cdc_putc, "Grupo GIDE\n\r");
// delay_ms(2000);
// printf(usb_cdc_putc,"\r");
// printf(usb_cdc_putc,"-%2.1g",medicion);
// delay_ms(500);


if(usb_cdc_kbhit()){ // En espera de nuevos caracteres en el buffer de recepción.
if(usb_cdc_getc()=='x'){ //¿lo que llegó fué el caracter x?
printf(usb_cdc_putc, "Se recibe el caracter x.\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, "Se recibe el caracter a.\n\r");
//si, entonces envía una cadena hacia el PC
}
}
}
}while (TRUE); // bucle infinito.
}
 
Me interesó lo de Linux, aunque estaría bueno que lo hiciera con gambas...entonces con mis ejemplos no hace falta modificar casi nada solo la comunicación serie.

Pichuquy: Tenés mal configurado los fuses por eso no te anda la aplicación.
 
Última edición:
Si es verdad...ahora posteo para ayudar a algunos con los dramas que se le presenten ..por que el tiempo esta escaseando. En cuanto termine con mis estudios termino con la aplicación final y la subo para que todos la puedan probar.
 
Hola Moyano Jonathan. He revisado los fuses y no encuentro el error que me decís. El programa me anda bien, solo que en el envío de (PC - PIC) falla y no recibo lo que corresponde. No puedo encontrar porque me hace eso… Muchas Gracias.
 
Si te ha funcionado antes , es problema de la PC no de los ejemplos. Algo que hay que tener en cuenta es cuando uno conecta un dispositivo USB la PC toma los descriptores del dispositivo y crea un archivo que guarda en el registro para que cada vez que el usuario conecte el dispositivo este no pida los drivers continuamente y se enumere de forma automatica.

El problema recae en cuando uno ha conectado y desconectado muchos dispositivos con el mismo descriptor y diferente driver o funcionamiento pueden aparecer conflictos de software. Que te soy sincero la única opción que hay es formatear la máquina o buscarte un programa para limpiar los driver's USB ...si buscas en la red seguro los encontras.

El capacitor de Vusb ha sido comentado ampliamente y te digo que no es critico siempre y cuando tenga un valor de 470nf para arriba.

Holas, tenias razón con los driver, de tanto cambiar el firmware windows no aguanto.
Por si a otro le pasa lo mismo tiene que ejecutar.

@echo off
set devmgr_show_nonpresent_devices=1
cd %SystemRoot%\system32
start devmgmt.msc

después se abre el administrador de dispositivos pero en ver esta la opción de mostrar dispositivos ocultos (los iconos de los drivers viejo aparecen mas claro). Yo tenia mas de 50 drivers en el USB.

Pichuquy:
Hola a todos. Estoy probando un programa con el PIC18F4550, para la comunicación por USB clase CDC. El programa que uso como entorno es el HYPERTERMINAL. El programa anda muy bien en el envio de datos (PIC-PC), pero cuando intento realizar el envio de datos al reves (PC-PIC) nunca recibo los caracteres. Este es el programa. Cuando preciono la 'x' para recibir el dato, nunca funciona. Muchas gracias.



#include <18F4550.h>

#fuses HSPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PL L3,CPUDIV1,VREGEN,NOPBADEN

Si copiaste y pegaste tu código es raro que te ande bien: PLL3 es para cristales de 12MHz y además lo tenés con un espacio

Saludos y gracias por la ayuda
 
Hola damian234, gracias por contestar. Es verdad que tengo el fuse PLL3 con espacio... pero en mi programa esta bien echo. Y lo estoy usando con un cristal de 12 Mhz. Ese codigo lo copie y lo peque desde este mismo tutorial. Yo estoy usando como programa interfaz el HYPERTERMINAL y no logro hacer que me envie datos desde la pc al pic. Tambien lo probé con el LABVIEW pero recibo cualquier caracter y no el que corresponde. No se si me explico bien. Ya no se mas que probar, estoy pensando que la libreria #include "usb_cdc.h" quizas tenga algun error. Yo estoy usando win VISTA. Muchas gracias.
 
:unsure:que tal felisito a todos son unos maestros de esto.
quisiera preguntarles lo siguiente:
-¿que nesesito para introducirme bien en el tema? soy estudiante de ingenieria en electromecanica pero ami me apasiona mucho la electronica. tengo conceptos en electronica analogica y en electronica digital.
-me podrian ayudar para entender la comunicacion usb. busco en internet pero no en cuentro mucha informacion.
-he leido sobre el picbasicpro se puede hacer esta aplicacion en este compilador.
les agradecere su ayuda.
 
Código:
#include <18F4550.h>
#include "usb_cdc.h"				// Descripción de funciones del USB.
#include "usb_desc_cdc.h"			// Descriptores del dispositivo USB.

#fuses HSPLL, MCLR, NOWDT, NOPROTECT, NOLVP, NODEBUG, USBDIV, PLL3, CPUDIV1, VREGEN, NOPBADEN

#use delay(clock=48000000)			// Frecuencia máxima de trabajo.

char letra;

void main() {

   float medicion;
   usb_cdc_init();					// Configuramos al puerto virtual.
   usb_init();						// Inicializamos el stack USB.
   
   setup_adc_ports (all_analog);
   setup_adc (adc_clock_internal);	//enciende adc
   set_adc_channel(0);				//elige canal a medir RA0
   delay_us(10);
   
   while(!usb_cdc_connected()) {	// Mientras el USB no esté conectado.
      output_high(PIN_B6);			// Función USB no detectada. (Enciende LED rojo)
      output_low(PIN_B7);			// (Apaga LED verde)
   }
   // espera a detectar una transmisión de la PC (Set_Line_Coding).
   
   output_high(PIN_B7); 			// Función USB detectada. (Enciende LED verde)
   output_low(PIN_B6); 				// (Apaga LED rojo)
   
   printf(usb_cdc_putc, "Dispositivo USB_CDC\n\r");
   do{
   
      usb_task();
      if (usb_enumerated()){ 		// Espera a que el dispositivo sea enumerado por el host
      // medicion=read_adc();
      // printf(usb_cdc_putc, "Dispositivo USB_CDC\n\r");
      // delay_ms(2000);
      // printf(usb_cdc_putc, "Emilio D'Olivo\n\r");
      // delay_ms(2000);
      // printf(usb_cdc_putc, "Grupo GIDE\n\r");
      // delay_ms(2000);
      // printf(usb_cdc_putc,"\r");
      // printf(usb_cdc_putc,"-%2.1g",medicion);
      // delay_ms(500);
      
      
         if(usb_cdc_kbhit()){ 		// En espera de nuevos caracteres en el buffer de recepción.
            letra=usb_cdc_getc();
			output_high(PIN_B7);
            delay_ms(2000);
            output_low(PIN_B7);
            if(letra=='x' || letra == 'a'){ //¿lo que llegó fué el caracter x o el a?
               printf(usb_cdc_putc, "Se recibe el caracter %c.\n\r",letra);  //si, entonces envía una cadena hacia el PC
               // usb_cdc_putc(letra);										 //si no anda proba poniendo directamente 
            }
            else{
               usb_cdc_putc('?');	//para lee mal el buffer
            }
         }
      }
   }while (TRUE); // bucle infinito.
}

Haber, yo uso MPLAB así que no te puedo ayudar mucho pero por lo que vi en los archivos de los encabezados deberia andar. Lo unico que le cambie es la forma de usar el printf(), igual no me gusta mucho eso que hace el ccs para pasar caracter por caracter. Tambien le agrege unas lineas para ver si por lo menos le llega info al pic.
Con lo poco que se de ccs y con el sueño no se me ocurre nada mas. Igual yo estoy por hacer lo mismo para controlar un ampli HI-END por la PC, así que si solucionas el problema decime.
 
Última edición:
Hola damian2340. Gracias por la ayuda. Me sigue asiendo lo mismo... En la foto adjunto un programa de LABVIEW que lo unico que hace es hacer de "eco" entre el pic y el pc. Pero por mas que le ingrese cualquier letra siempre me debuelve el mismo caracter que es ":" y no se como arreglarlo.. No se si alguien tubo este problema algunas ves.. gracias. :cry:
 

Adjuntos

  • Captura.JPG
    Captura.JPG
    67.9 KB · Visitas: 51
pichuquy: Hasta donde llega la ejecucion del programa por lo menos llega a encender tu pin7? bueno aunque despues de que le haces el getc lo vuelves a encender y ya estaba previamente encendido y luego lo apagas mejor deberias de encender otro pin por lo menos para debugearlo mejor yo por lo menos este pedacito lo programaria asi

if(usb_cdc_kbhit()){
letra=usb_cdc_getc();
output_low(PIN_B7);
delay_ms(2000);
output_high(PIN_B7);
usb_cdc_putc(letra); //enviando de vuelta el caracter un eco para probar que recibio
if((letra=='x')||(letra=='X')||
(letra=='a')||(letra=='A')){ //¿lo que llegó fué el caracter x o el a?
printf(usb_cdc_putc, "Se recibe el caracter %c.\n\r",letra); //si, entonces envía una cadena hacia el PC
// usb_cdc_putc(letra); //si no anda proba poniendo directamente
}else{
usb_cdc_putc('?'); //para lee mal el buffer
}
}
 
Atrás
Arriba