Saludos a todos los foristas! Acá vengo a dejarles un pequeño proyecto en el que convierto una señal analógica a digital, y luego la mando a una PC vía USB BULK. El programa y el circuito son sumamente sencillos:
#include <18F4550.h>
#device adc=8
#fuses HSPLL, NOWDT, NOPROTECT, NOLVP, NODEBUG, USBDIV, PLL5, CPUDIV1, VREGEN
#use delay(clock=48000000)
#define usb_con_sense_pin pin_b2
#define USB_HID_DEVICE FALSE // deshabilitamos el uso de las directivas HID
#define USB_EP1_TX_ENABLE USB_ENABLE_BULK // turn on EP1(EndPoint1) for IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE USB_ENABLE_BULK // turn on EP1(EndPoint1) for OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE 32 // size to allocate for the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE 32 // size to allocate for the rx endpoint 1 buffer
#include <pic18_usb.h> // Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include "USB_BULK.h" // Configuración del USB y los descriptores para este dispositivo
#include <usb.c> // handles usb setup tokens and get descriptor reports
int16 adc;
int16 IniciarConteoEn=65459;
float envia;
#int_TIMER3 //Interrupción timer1
void temp1s(void) //función
{
output_toggle(PIN_B1);
adc=read_adc();
set_timer3(IniciarConteoEn);
}
void main(void) {
setup_timer_3 (T3_INTERNAL | T3_DIV_BY_1); ///configuro timer 1 con reloj interno y prescaler de 1
enable_interrupts(INT_TIMER3); //habilita interrupción timer1
enable_interrupts(global); //habilita interrupción general
set_timer3(IniciarConteoEn); //Precarga del timer1
setup_adc_ports(AN0|VSS_VDD);
setup_adc(ADC_CLOCK_DIV_64 );//|| ADC_ACQT_2TAD ); //Indica el tiempo de reloj
#asm //Inicio de sentencias en lenguaje Assembler
movlw 0b10001110 ;justificacion_derecha,2Tad,Fosc/64 //Modificando el tiempo de conversión
iorwf 0xFC0,1 ; direccion de ADCON2 //y el tiempo de adquisición
#endasm //Fin de la rutina Assembler
set_adc_channel(0);
usb_init();
usb_task();
usb_wait_for_enumeration();
enable_interrupts(global);
while (TRUE)
{
if(usb_enumerated()){
envia=(5.0*adc)/256.0;
usb_put_packet(1,envia,1,USB_DTS_TOGGLE);
}
}
}
El único problema que no he podido solucionar es que, si aumento la precarga de TIMER1, la PC no reconoce el dispositivo USB, y con el código actual la interrupción sólo ocurre cada 28us, dando una frecuencia de muestreo de 35,71KHz.
Originalmente, pensaba que la frecuencia fuera de al menos 40KHz, ya que las señales a muestrear están en el rango de audio, pero no lo he logrado. A todas estas, el cristal utilizado es de 20MHz.
Cualquier idea vendría bien...