Hola a todos, tengo una duda que me ha estado comiendo la cabeza varios días.
Se trata de un visor del valor que toma una entrada analógica del PIC18F2550. El protocolo de comunicación que estoy utilizando es HID (human interface device).
Mi problema es que el valor que se muestra en el visor de texto no concuerda con lo que se muestra en el display LCD.
Mi código es el siguiente:
Firmware en C de CCS para el PIC18F2550.
// Programa: Hace una prueba de funcionamiento del LCD 2x16 y el ADC.
// Programador: Moyano Jonathan.
// Fecha: 13/02/09
#include <18F2550.h> // Definición de registros internos del PIC18F2550.
#DEVICE ADC=8 // CAD con 8 bits de resolución , justificación a la derecha.
#fuses NOMCLR,XTPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,VREGEN,NOPBADEN
// NOMCLR: No vamos ha usar el PIN MCLR, el reset se hará por soft.
// XTPLL: Vamos a usar un cristal de 4.00Mhz.
// NOWDT: No vamos a usar el perro guardian.
// NOPROTECT: Memoria no protejida contra lecturas.
// NODEBUG: No utilizamos código para debugear.
// NOLVP: No utilizamos el modo de programación con bajo voltaje.
// USBDIV: signfica que el clock del usb se tomará del PLL/2 = 96Mhz/2 = 48Mhz.
// PLL1: significa que el PLL prescaler no dividirá la frecuencia del cristal. para XT = 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á.
// NOVREGEN: habilita el regulador de 3.3 volts que usa el módulo USB.
// NOPBADEN: Deshabilitamos el módulo conversor ADC del puerto B.
#use delay(clock=48000000)
#DEFINE USB_HID_DEVICE TRUE // Vamos a utilizar el protocolo HID.
#define USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT // Definición del tamaño del buffer de salida.
#define USB_EP1_TX_SIZE 1
#define USB_EP1_RX_ENABLE USB_ENABLE_INTERRUPT // Definición del tamaño del buffer de entrada.
#define USB_EP1_RX_SIZE 1
/*********************************************************************************************************/
#define use_portb_lcd TRUE // Puerto B usado para el LCD.
// Librerías utilizadas.
#include <LCD.c>
#include <pic18_usb.h> // Drivers's USB del PIC18F2550.
#include <usb_desc_hid.h> // Descriptores USB.
#include <usb.c> // Funciones del USB.
/*********************************************************************************************************/
// Variables globales.
long valor; // Variable que guarda el valor del ADC.
void main() {
int8 dato[1]; // Variable que va a guardar el valor del ADC.
OUTPUT_A(0); // todos salidas
OUTPUT_B(0) ;
OUTPUT_C(0);
lcd_init(); // inicia la LCD
set_tris_a(0x3); // ra0=entradas, los demas=salida
set_tris_b(0x0);
set_tris_c(0x0);
setup_adc_ports( AN0 || VSS_VDD ); // canal AN0, Vref+ = Vdd, Vref- = Vss
setup_adc(ADC_CLOCK_DIV_64);
set_adc_channel(0);
lcd_putc("\f"); // para evitarme un retardo y que no parpadee la LCD
usb_init_cs(); // inicia el USB y sale. Va de la mano con usb_task().
while(1){ // bucle infinito
valor = read_adc();
dato[0] = valor;
usb_task(); // Configuramos el puerto USB.
if (usb_enumerated()) // Si el puerto es enumerado y configurado por el host..
{
usb_put_packet(1,dato,1,USB_DTS_TOGGLE); // Mando el valor del adc por USB.
}
lcd_gotoxy(1,1); // Posicionamos el cursor.
printf(lcd_putc,"Valor=%3lu",valor);
}
}
El código fuente del programa es el siguiente:
Private Sub datos_Timer()
Dim datos As Byte ' Variable que contiene el valor del ADC.
dato = ReadBuffer()
Valor.Text = dato
ReadReport
End Sub
Private Sub estado_conexión_Timer()
If FindTheHid Then ' Si el dispositivo está coenctado al host.
USB_ESTADO.BackColor = &HC000&
Else ' En cambio si no está conectado.
USB_ESTADO.BackColor = &HFF& ' Prende LED rojo.
End If
End Sub
Private Sub Form_Unload(Cancel As Integer)
Dim Result As Long
' Cierra los puertos de comunicaciones.
Result = CloseHandle(HIDHandle)
Result = CloseHandle(ReadHandle)
End Sub
Acá están las inmágenes que muestran la diferencia de los datos visualizados:
Lo que muestra la PC:
Lo que muestra el LCD:
En el link de descarga se encuentra el programa de control.