...
/*
//configure a 20MHz crystal to operate at 48MHz
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=48000000)
*/
...
#fuses XTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,NOVREGENPBADEN: PORTB A/D Enable bit// código ejemplo para hacer funcionar por primera vez al PIC18F4550 mediante encendido
// y apagado de 8 led´s conectado al PORTB en intervalos de 1 Seg
// 16-Dic-2006
#include <18f4550.h> //archivo de cabecera
#fuses XTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,NOVREGEN
// el fuse que configuramos anteriormente
#use delay(clock=48000000)
// el clock que tendremos a la entrada del CPU
void main() {
set_tris_a(0x0); // configura los puertos como salidas
set_tris_b(0x0);
set_tris_c(0x0);
set_tris_d(0x0);
set_tris_e(0x0);
//----------------------------------
disable_interrupts(global);
disable_interrupts(int_timer1);
disable_interrupts(int_rda);
disable_interrupts(int_ext);
disable_interrupts(int_ext1);
disable_interrupts(int_ext2);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_psp(PSP_DISABLED);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
port_b_pullups(FALSE);
//---------------------------
output_a (0); // saca un nivel bajo de salida en los puertos
output_c (0);
output_d (0);
output_e (0);
while(1){
output_b (0); // saca un nivel bajo en el portb
delay_ms(1000); // retardo de 1 Seg
output_b (0xff); // saca un nivel alto en el portb
delay_ms(1000); // retardo de 1 Seg
}
}
Configuration Fuses:
Word 1: 0220 XTPLL NOIESO NOFCMEN PLL1 CPUDIV1 USBDIV
Word 2: 1E1E BROWNOUT NOWDT BORV20 PUT WDT32768 NOVREGEN RESERVED
Word 3: 8300 PBADEN CCP2C1 MCLR NOLPT1OSC RESERVED
Word 4: 0081 STVREN NODEBUG NOLVP NOXINST NOICPRT RESERVED
Word 5: C00F NOPROTECT NOCPD NOCPB
Word 6: E00F NOWRT NOWRTD NOWRTC NOWRTB
Word 7: 400F NOEBTR NOEBTRB#fuses XTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,NOVREGEN,NOPBADEN// código ejemplo para hacer funcionar por segunda vez al PIC18F4550 mediante encendido
// y apagado de 8 led´s conectado al PORTB y RE3 en intervalos de 1 Seg (sin usar el MCLR)
// 20-Dic-2006
#include <18f4550.h> //archivo de cabecera
#fuses XTPLL,NOMCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,NOVREGEN,NOPBADEN
#use delay(clock=48000000) // el clock que tendremos a la entrada del CPU
void main() {
set_tris_a(0x0); // configura los puertos como salidas
set_tris_b(0x0);
set_tris_c(0x0);
set_tris_d(0x0);
set_tris_e(0x0); // RE3 <- entrada no hace falta configurarlo (ver note1 pag126)
//-----------------------------------
disable_interrupts(global);
disable_interrupts(int_timer1);
disable_interrupts(int_rda);
disable_interrupts(int_ext);
disable_interrupts(int_ext1);
disable_interrupts(int_ext2);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_psp(PSP_DISABLED);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
//-------------------------------------------
port_b_pullups(FALSE);
output_a (0); // saca un nivel bajo de salida en los puertos
output_b (0); // saca un nivel bajo en el portb
output_c (0);
output_d (0);
output_e (0);
while(1){
if(input_state(PIN_E3)){
output_b (0); // saca un nivel bajo en el portb
output_c (0);
delay_ms(1000); // retardo de 1 Seg
output_b (0xff); // saca un nivel alto en el portb
delay_ms(1000);
}
else{
output_b (0); // saca un nivel bajo en el portb
output_c (0);
delay_ms(1000);
output_c (0xff);
delay_ms(1000);
}
}
}
bsf porta,0
nop
bsf porta,1
#asm
bsf PORTB,0,1
bsf PORTB,1,1
#endasm
pero sospecho que el pcwh, mete sus narices aún en asm, porque en la ayuda del ccs, dice:BSF f,b
cuando en realidad la instrucción es:BSF f,b,a
CONFIG FOSC = XTPLL_XT, PLLDIV = 1,CPUDIV = OSC1_PLL2,USBDIV = 2,PWRT = ON,BOR = SOFT, VREGEN = OFF , WDT = OFF ,WDTPS = 1,MCLRE = ON,PBADEN = OFF
CONFIG LVP = OFF,XINST = OFF,DEBUG = OFF
; código ejemplo para hacer funcionar por tercera vez al PIC18F4550 mediante encendido
; y apagado de 8 led´s conectado al PORTB dependiendo del estado del pulsador en RB0
; que encenderá led´s pares e impares
; 21-Dic-2006
LIST P=18F4550 ;directive to define processor
#include <P18F4550.INC> ;processor specific variable definitions
;#fuses XTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,NOVREGEN,NOPBADEN // el fuse que configuramos anteriormente (CORREGIDO)
;#use delay(clock=48000000) // el clock que tendremos a la entrada del CPU
CONFIG FOSC = XTPLL_XT, PLLDIV = 1,CPUDIV = OSC1_PLL2,USBDIV = 2,PWRT = ON,BOR = SOFT, VREGEN = OFF
CONFIG WDT = OFF ,WDTPS = 1,MCLRE = ON,PBADEN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF
CBLOCK 0x0
ENDC
org 0
goto inicio
;org 0x8 interrup alta priori
;org 0x18 baja prioridad
inicio:
;clrf LATA ; limpia los latch
;clrf LATB
;clrf LATC
;clrf LATD
;clrf LATE
clrf TRISA ; configuar el port como salida ¡que bueno!, no hay que estar cambiando de bancos ;-)
movlw 0x1
movwf TRISB ; configura RB0<- entrada, el resto -> salida
clrf TRISC
clrf TRISD
clrf TRISE
;//------------------------------------------------------
; ahora viene la deshabilitación de modulos (pheriperals)
;*******************************************************
clrf,ADCON0 ; desactiva el CAD
movlw 0xf
movwf ADCON1 ; todas digitales
bcf INTCON,GIE ; desactiva interrupciones
movlw 0x7
movwf CMCON ;desactiva el modulo comparador
;clrf CVRCON ; desactiva el Vref del comparador no hace falta
clrf SPPCON ; desactiva el modulo Streaming Parallel Port (SPP)
clrf SSPCON1 ; desactiva el modulo MSSP,SSPEN
bcf UCON,USBEN ; desactiva el modulo USB
bsf INTCON2,RBPU ; desactiva las resistencias de amarre en PORTB
;disable_interrupts(global);
;setup_adc_ports(NO_ANALOGS);
;setup_adc(ADC_OFF);
;setup_spi(FALSE);
;setup_psp(PSP_DISABLED);
;setup_comparator(NC_NC_NC_NC);
;setup_vref(FALSE);
;//-------------------------------------------
;port_b_pullups(FALSE);
ciclo:
btfss PORTB,0
bra LED_RB2
bcf PORTB,2,1
bcf PORTB,4,1
bcf PORTB,6,1
bsf PORTB,1,1
bsf PORTB,3,1
bsf PORTB,5,1
bsf PORTB,7,1
bra ciclo
LED_RB2:
bcf PORTB,1,1
bcf PORTB,3,1
bcf PORTB,5,1
bcf PORTB,7,1
bsf PORTB,2,1
bsf PORTB,4,1
bsf PORTB,6,1
bra ciclo
end
movff 0x1,TRISB
pero no sirve, porque para esa instrucción los argumentos deben ser registros en ambos (ver pagina 334), nos vamos por el tradicional registro de trabajo, (que ahora se llama WREG)...
0004 6A92 CLRF 0xf92, ACCESS 29: clrf TRISA ; configuar el port como salida ¡que bueno!, no hay que estar cambiando de bancos ;-)
0006 0E01 MOVLW 0x1 30: movlw 0x1
0008 6E93 MOVWF 0xf93, ACCESS 31: movwf TRISB ; configura RB0<- entrada, el resto -> salida
000A 6A94 CLRF 0xf94, ACCESS 32: clrf TRISC
000C 6A95 CLRF 0xf95, ACCESS 33: clrf TRISD
000E 6A96 CLRF 0xf96, ACCESS 34: clrf TRISE
35: ;//------------------------------------------------------
36: ; ahora viene la deshabilitación de modulos (pheriperals)
37: ;*******************************************************
0010 6A00 CLRF 0, ACCESS 38: clrf,ADCON0 ; desactiva el CAD
0012 0E0F MOVLW 0xf 39: movlw 0xf
0014 6EC1 MOVWF 0xfc1, ACCESS 40: movwf ADCON1 ; todas digitales
0016 9EF2 BCF 0xff2, 0x7, ACCESS 41: bcf INTCON,GIE ; desactiva interrupciones
0018 0E07 MOVLW 0x7 42: movlw 0x7
001A 6EB4 MOVWF 0xfb4, ACCESS 43: movwf CMCON ;desactiva el modulo comparador
44: ;clrf CVRCON ; desactiva el Vref del comparador no hace falta
001C 6A65 CLRF 0xf65, ACCESS 45: clrf SPPCON ; desactiva el modulo Streaming Parallel Port (SPP)
001E 6AC6 CLRF 0xfc6, ACCESS 46: clrf SSPCON1 ; desactiva el modulo MSSP,SSPEN
0020 966D BCF 0xf6d, 0x3, ACCESS 47: bcf UCON,USBEN ; desactiva el modulo USB
0022 8EF1 BSF 0xff1, 0x7, ACCESS 48: bsf INTCON2,RBPU ; desactiva las resistencias de amarre en PORTB
49: ;disable_interrupts(global);
50: ;setup_adc_ports(NO_ANALOGS);
51: ;setup_adc(ADC_OFF);
52: ;setup_spi(FALSE);
53: ;setup_psp(PSP_DISABLED);
54: ;setup_comparator(NC_NC_NC_NC);
55: ;setup_vref(FALSE);
56: ;//-------------------------------------------
57: ;port_b_pullups(FALSE);
58:
59: ciclo:
0024 A081 BTFSS 0xf81, 0, ACCESS 60: btfss PORTB,0
0026 D008 BRA 0x38 61: bra LED_RB2
0028 9581 BCF 0x81, 0x2, BANKED 62: bcf PORTB,2,1
002A 9981 BCF 0x81, 0x4, BANKED 63: bcf PORTB,4,1
002C 9D81 BCF 0x81, 0x6, BANKED 64: bcf PORTB,6,1
65:
002E 8381 BSF 0x81, 0x1, BANKED 66: bsf PORTB,1,1
0030 8781 BSF 0x81, 0x3, BANKED 67: bsf PORTB,3,1
0032 8B81 BSF 0x81, 0x5, BANKED 68: bsf PORTB,5,1
0034 8F81 BSF 0x81, 0x7, BANKED 69: bsf PORTB,7,1
0036 D7F6 BRA 0x24 70: bra ciclo
71: LED_RB2:
0038 9381 BCF 0x81, 0x1, BANKED 72: bcf PORTB,1,1
003A 9781 BCF 0x81, 0x3, BANKED 73: bcf PORTB,3,1
003C 9B81 BCF 0x81, 0x5, BANKED 74: bcf PORTB,5,1
003E 9F81 BCF 0x81, 0x7, BANKED 75: bcf PORTB,7,1
76:
0040 8581 BSF 0x81, 0x2, BANKED 77: bsf PORTB,2,1
0042 8981 BSF 0x81, 0x4, BANKED 78: bsf PORTB,4,1
0044 8D81 BSF 0x81, 0x6, BANKED 79: bsf PORTB,6,1
0046 D7EE BRA 0x24 80: bra ciclo
; código ejemplo para hacer funcionar por tercera vez al PIC18F4550 mediante encendido
; y apagado de 8 led´s conectado al PORTB dependiendo del estado del pulsador en RB0
; que encenderá led´s pares e impares
; 21-Dic-2006
LIST P=18F4550 ;directive to define processor
#include <P18F4550.INC> ;processor specific variable definitions
;#fuses XTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,NOVREGEN,NOPBADEN // el fuse que configuramos anteriormente (CORREGIDO)
;#use delay(clock=48000000) // el clock que tendremos a la entrada del CPU
CONFIG FOSC = XTPLL_XT, PLLDIV = 1,CPUDIV = OSC1_PLL2,USBDIV = 2,PWRT = ON,BOR = ON, VREGEN = OFF
CONFIG WDT = OFF ,WDTPS = 1,MCLRE = ON,PBADEN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF
CBLOCK 0x0
ENDC
org 0
goto inicio
; org 0x8 interrup alta priori
; org 0x18 baja prioridad
inicio:
; clrf LATA ; limpia los latch
; clrf LATB
; clrf LATC
; clrf LATD
; clrf LATE
clrf TRISA ; configuar el port como salida ¡que bueno!, no hay que estar cambiando de bancos ;-)
movlw 0x1
movwf TRISB ; configura RB0<- entrada, el resto -> salida
clrf TRISC
clrf TRISD
clrf TRISE
;//------------------------------------------------------
; ahora viene la deshabilitación de modulos (pheriperals)
;*******************************************************
clrf,ADCON0 ; desactiva el CAD
movlw 0xf
movw ADCON1 ; todas digitales
bcf INTCON,GIE ; desactiva interrupciones
movlw 0x7
movwf CMCON ;desactiva el modulo comparador
;clrf CVRCON ; desactiva el Vref del comparador no hace falta
clrf SPPCON ; desactiva el modulo Streaming Parallel Port (SPP)
clrf SSPCON1 ; desactiva el modulo MSSP,SSPEN
bcf UCON,USBEN ; desactiva el modulo USB
bsf INTCON2,RBPU ; desactiva las resistencias de amarre en PORTB
;disable_interrupts(global);
;setup_adc_ports(NO_ANALOGS);
;setup_adc(ADC_OFF);
;setup_spi(FALSE);
;setup_psp(PSP_DISABLED);
;setup_comparator(NC_NC_NC_NC);
;setup_vref(FALSE);
;//-------------------------------------------
;port_b_pullups(FALSE);
ciclo:
btfss PORTB,0
bra LED_RB2
bcf PORTB,2,0
bcf PORTB,4,0
bcf PORTB,6,0
bsf PORTB,1,0
bsf PORTB,3,0
bsf PORTB,5,0
bsf PORTB,7,0
bra ciclo
LED_RB2:
bcf PORTB,1,0
bcf PORTB,3,0
bcf PORTB,5,0
bcf PORTB,7,0
bsf PORTB,2,0
bsf PORTB,4,0
bsf PORTB,6,0
bra ciclo
end
; código ejemplo para hacer funcionar por tercera vez al PIC18F4550 mediante encendido
; y apagado de 8 led´s conectado al PORTB dependiendo del estado del pulsador en RB0
; que encenderá led´s pares e impares
; 21-Dic-2006
LIST P=18F4550 ;directive to define processor
#include <P18F4550.INC> ;processor specific variable definitions
;#fuses XTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,NOVREGEN,NOPBADEN // el fuse que configuramos anteriormente (CORREGIDO)
;#use delay(clock=48000000) // el clock que tendremos a la entrada del CPU
CONFIG FOSC = XTPLL_XT, PLLDIV = 1,CPUDIV = OSC1_PLL2,USBDIV = 2,PWRT = ON,BOR = ON, VREGEN = OFF
CONFIG WDT = OFF ,WDTPS = 1,MCLRE = ON,PBADEN = OFF,LVP = OFF,XINST = OFF,DEBUG = OFF
CBLOCK 0x0
ENDC
org 0
goto inicio
; org 0x8 interrup alta priori
; org 0x18 baja prioridad
inicio:
; clrf LATA ; limpia los latch
; clrf LATB
; clrf LATC
; clrf LATD
; clrf LATE
clrf TRISA ; configuar el port como salida ¡que bueno!, no hay que estar cambiando de bancos ;-)
movlw 0x1
movwf TRISB ; configura RB0<- entrada, el resto -> salida
clrf TRISC
clrf TRISD
clrf TRISE
;//------------------------------------------------------
; ahora viene la deshabilitación de modulos (pheriperals)
;*******************************************************
clrf,ADCON0 ; desactiva el CAD
movlw 0xf
movwf ADCON1 ; todas digitales
bcf INTCON,GIE ; desactiva interrupciones
movlw 0x7
movwf CMCON ;desactiva el modulo comparador
;clrf CVRCON ; desactiva el Vref del comparador no hace falta
clrf SPPCON ; desactiva el modulo Streaming Parallel Port (SPP)
clrf SSPCON1 ; desactiva el modulo MSSP,SSPEN
bcf UCON,USBEN ; desactiva el modulo USB
bsf INTCON2,RBPU ; desactiva las resistencias de amarre en PORTB
;disable_interrupts(global);
;setup_adc_ports(NO_ANALOGS);
;setup_adc(ADC_OFF);
;setup_spi(FALSE);
;setup_psp(PSP_DISABLED);
;setup_comparator(NC_NC_NC_NC);
;setup_vref(FALSE);
;//-------------------------------------------
;port_b_pullups(FALSE);
ciclo:
btfss PORTB,0
bra LED_RB2
bcf LATB,2,0
bcf LATB,4,0
bcf LATB,6,0
bsf LATB,1,0
bsf LATB,3,0
bsf LATB,5,0
bsf LATB,7,0
bra ciclo
LED_RB2:
bcf LATB,1,0
bcf LATB,3,0
bcf LATB,5,0
bcf LATB,7,0
bsf LATB,2,0
bsf LATB,4,0
bsf LATB,6,0
bra ciclo
end
// usando el CAD en el 18F4550
// 30-Dic-2006
#include <18f4550.h> //archivo de cabecera
//#DEVICE ADC=8 // cad a 8 bits, justificación a a la derecha
#DEVICE ADC=10 // cad a 10 bits, justificación a a la derecha
//#DEVICE ADC=16 // cad a 10 bits, justificación a a la izquierda
#fuses XTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,NOVREGEN,NOPBADEN // el fuse que configuramos anteriormente (CORREGIDO)
#use delay(clock=48000000) // el clock que tendremos a la entrada del CPU
#byte LATB=0xF8A
#byte PORTB=0XF81
void main() {
long value;
int parte_alta;
int ADC_ACQT_2TAD=0x1;
output_a(0); // saca un nivel bajo de salida en los puertos
output_b(0);
output_c(0);
output_d(0);
output_e(0);
set_tris_a(0x1); // configura los puertos como salidas
set_tris_b(0x0);
set_tris_c(0x0);
set_tris_d(0x0);
set_tris_e(0x0);
//-----------------------------------
disable_interrupts(global);
disable_interrupts(int_timer1);
disable_interrupts(int_rda);
disable_interrupts(int_ext);
disable_interrupts(int_ext1);
disable_interrupts(int_ext2);
setup_spi(FALSE);
setup_psp(PSP_DISABLED);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
port_b_pullups(FALSE);
setup_adc_ports( AN0 || VSS_VDD );
setup_adc(ADC_CLOCK_DIV_64 || ADC_ACQT_2TAD );
set_adc_channel(0);
while(1){ // bucle infinito
value = read_adc(); // toma el resultado del CAD
output_b((int)value); // envía el byte LSB a portb
parte_alta=(int)((value & 0x300)>>8); // separa los 2 bits MSB de value
output_c(parte_alta); // y los envia al portc
}
} int ADC_ACQT_2TAD=0x1;
#asm
movlw 0b10001110 ;justificacion_derecha,2Tad,Fosc/64
movwf 0xFC0 ; direccion de ADCON2
#endasm
setup_adc(ADC_CLOCK_DIV_64 ); //|| ADC_ACQT_2TAD );
#asm
movlw 0b10001110 ;justificacion_derecha,2Tad,Fosc/64
iorwf 0xFC0,1 ; direccion de ADCON2
#endasm
1A0
2AA
3FF
esas lineas corresponden al supuesto valor de ADRESH:ADRESL y seran cargadas por el estímulo en un bucle #asm
movlw 0b10111110 ;justificacion_derecha,20Tad,Fosc/64
iorwf 0xFC0,1 ; direccion de ADCON2
#endasm
ADC-W0001: Tad time is less than 1.60us
ADC-W0010: A Minimum of 2 TADs are required before another conversion should be started.
...
#asm
movlw 0b10001110 //justificacion_derecha,2Tad,Fosc/64
...
...
delay_us(3); // para pasar >= 2Tad a la sig CAD
...
1=Vbus
2=D-
3=D+
4=gnd
picusb.cat
picusb.inf
picusbci.dll
wdmstub.sys
ahora viene la parte difícil, entender que es lo que hace aquello y como lo hace. :?
' 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
/* 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
}
usb_enumerated()
usb_cdc_kbhit()
usb_cdc_getc()
usb_cdc_connected()
/* 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
}
- no hay conexión
- conectado el cable USB
- ejecutando la aplicación VB
- enviando el dato hacia el dispositivo
| 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' |
' 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
#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() {
...
#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
usb_init();
void usb_init(void) {
usb_init_cs();
do {
usb_task();
} while (usb_state != USB_STATE_POWERED);
}
/*****************************************************************************
/* 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()) {
...
...
/******************************************************************************
/* 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
...
/////////////////////////////////////////////////////////////////////////////
//
// 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
...
#define USB_CON_SENSE_PIN PIN_E3 //pin de MCLR
...
while(!usb_cdc_connected()){
...
}
...
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;
usb_isr_rst() -> para el flag __USB_UIF_RESET
usb_isr_uidle() -> para el flag __USB_UIF_IDLE
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.
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;
}
...
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");
while(!usb_cdc_connected()) { //bucle eterno
delay_cycles(1);} // para evitarme un retardo y que no parpadee la LCD
UIE=__USB_UIF_IDLE | __USB_UIF_RESET; //enable IDLE and RESET USB interrupt
#define __USB_UIF_IDLE 0x10 -> bit 4
#define __USB_UIF_RESET 0x01 -> bit 0
/*******************************************************************************
/* 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.
/*
/********************************************************************************/
/* 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
}
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);
...
}
>>> 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)
#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)
}
}
printf(lcd_putc,"\f UIR= %X",UIR);
delay_ms(500);
>>> 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)
while(!usb_cdc_connected()) { //bucle eterno
/* 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
}
usb_init():
Initializes the USB hardware. Will then wait in an infinite loop for the USB peripheral to be connected to bus (but that doesn't mean it has been enumerated by the PC). Will enable and use the USB interrupt.
usb_init_cs():
The same as usb_init(), but does not wait for the device to be connected to the bus. This is useful if your device is not bus powered and can operate without a USB connection.
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.
usb_detach():
Removes the PIC from the bus. Will be called automatically by usb_task() if connection is lost, but can be called manually by the user.
usb_attach():
Attaches the PIC to the bus. Will be called automatically by usb_task() if connection is made, but can be called manually by the user.
usb_attached():
If using connection sense pin (USB_CON_SENSE_PIN), returns TRUE if that pin is high. Else will always return TRUE.
usb_enumerated():
Returns TRUE if the device has been enumerated by the PC. If the device has been enumerated by the PC, that means it is in normal operation mode and you can send/receive packets.
usb_enumerated(): // proviene de USB.C
returns TRUE if device has been enumerated (configured) by host, FALSE if it has not. Do not try to use the USB peripheral until you are enumerated.
/* probando_USB.c
es una modificación del ejemplo6_parte4, aquí se usa una bandera global
que determinará el estado de conexión del USB, mediante las llamadas
usb_attach y usb_detach en pic18_usb.h
Modificación del código original de RRCdcUSB de RedPic
Pedro-PalitroqueZ 11-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
short estado_usb; // boolean global, se debe declarar antes de llamar a usb_cdc.h
#define USB_CON_SENSE_PIN PIN_E3
#include <lcd.c>
#include "usb_cdc.h"
void mostrar_estado_usb(short bandera);
void main(){
estado_usb=false;
usb_cdc_init(); // llamadas necesarias para iniciar el módulo USB
usb_init_cs(); // inicia el USB y sale. va a la par con usb_task()
lcd_init(); // llamadas necesarias para iniciar la LCD
while(true){
usb_task(); // configura el USB
mostrar_estado_usb(estado_usb);
if(usb_cdc_connected()){
// espera a detectar una transmisión de la PC (Set_Line_Coding)
if (usb_enumerated()){ // aquí se hace el acceso HOST<->PC y después sale
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?
printf(usb_cdc_putc, "Llegó la letra a\n\r"); // envia una respuesta al HOST --FALTABA ESTA LÍNEA--
lcd_gotoxy(1,1);
lcd_putc("llego una a ");
delay_ms(500);
}
}
}
}
//*************** aquí se ejecutan otros procesos*********************//
lcd_gotoxy(1,1);
lcd_putc("otros procesos");
delay_ms(500);
}
}
/************************************************
// esta llamada imprime en la LCD los estados de conectado
// y desconectado del USB dependiendo de la bandera
// estado_usb
//***********************************************/
void mostrar_estado_usb(short bandera){
lcd_gotoxy(10,2);
if(bandera){
lcd_putc(" USB:On");
}else{
lcd_putc("USB:Off");
}
delay_ms(500);
}
' ejemplo6_parte5 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-feb-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 Command1_Click()
If MSComm1.PortOpen = True Then
MSComm1.PortOpen = False
End If
End
End Sub
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
MSComm1.InBufferSize = 16 '16 caracteres
'MSComm1.PortOpen = True
MSComm1.InputLen = 16 ' BUFFER DE ENTRADA SE PUEDE DEJAR AL MAXIMO
MSComm1.RThreshold = 16 '
Timer1.Interval = 10
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 MSComm1_OnComm()
Dim InBuff As String
Select Case MSComm1.CommEvent
Case comEvReceive
InBuff = MSComm1.Input
Debug.Print InBuff
Text1.Text = ""
Text1.Text = Left$(InBuff, 16) ' se recorta los caracteres basura
MSComm1.PortOpen = False 'cierra el puerto y vacia el buffer
Espera 2 ' retardo de 2 segundos
Text1.Text = ""
End Select
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
' procedimiento de retardo
'este código NO es de mi autoría, lo bajé del internet.
Sub Espera(Segundos As Single)
Dim ComienzoSeg As Single
Dim FinSeg As Single
ComienzoSeg = Timer
FinSeg = ComienzoSeg + Segundos
Do While FinSeg > Timer
DoEvents
If ComienzoSeg > Timer Then
FinSeg = FinSeg - 24 * 60 * 60
End If
Loop
End Sub
printf(usb_cdc_putc, "Llegó la letra a\n\r"); // envia una respuesta al HOST
SnoopyPro is a tool for advanced USB programmers. It allows you to record
each URB sent to and received from a USB device. This traces can be saved,
loaded, edited, printed and combined into new traces.
WARNING: You might damage your system with this tool. Don't use it if
you don't know what you're doing!!!! We're not responsible for anything
that happens to you, your system, your devices, your marriage, etc. etc.
...
==========================================================================
INSTALLATION/USE:
==========================================================================
1. Run SnoopyPro.exe from whereever you have saved it.
2. Open up the USB devices window with F2.
3. Choose 'Unpack Drivers' from the 'File' menu.
4. Choose 'Install Service' from the 'File' menu.
5. Locate the device you want to sniff.
6. Right-click on it and choose 'Install and Restart'.
7. Wait for the magic to happen...
...
#include <18f4525.h> //archivo de cabecera
#DEVICE ADC=10 // cad a 10 bits, justificación a a la derecha
#fuses XT,NOWDT,NOPROTECT,NOLVP,NODEBUG // el fuse que configuramos anteriormente
#use delay(clock=4000000) // el clock que tendremos a la entrada del CPU
#define use_portb_lcd TRUE
#include <LCD.c>
#define DERECHA 0
#define IZQUIERDA 1
long value;
void config_adcon2(short justificacion);
void main(){
int i;
OUTPUT_A(0); // todos salidas
OUTPUT_B(0);
OUTPUT_C(0);
OUTPUT_D(0);
OUTPUT_E(0);
lcd_init(); // inicia la LCD
set_tris_a(0x3); // ra0=entradas, los demas=salida
set_tris_b(0x0);
set_tris_c(0x0);
set_tris_d(0x0);
set_tris_e(0x0);
setup_adc_ports( AN0 || VSS_VDD ); // canal AN0, Vref+ = Vdd, Vref- = Vss
config_adcon2(DERECHA);
lcd_putc("\f"); // para evitarme un retardo y que no parpadee la LCD
while(1){ // bucle infinito
value = read_adc();
if(input_state(PIN_A1)){ //pregunta por el switche
config_adcon2(DERECHA);
}else{
config_adcon2(IZQUIERDA);
}
for(i=0;i<16;i++){
lcd_gotoxy(16-i,1);
lcd_putc((char)(bit_test(value,i)+0x30));
}
printf(lcd_putc,"\n0x%Lx",value);
}
}
//-----------------------------------------------------------------------------------------
// cumple la función de configurar el bit ADFM para hacer
// la justificación, también se incluye el retardo por hardware de Tacq
// datos de entrada: bandera de justificación
// datos de salida: nada
//-----------------------------------------------------------------------------------------
void config_adcon2(short justificacion){
setup_adc(ADC_CLOCK_DIV_64 ); // reloj de conversión = Fosc / 64
if(justificacion){
#asm
bsf 0xFC0,7 // ADFM <- 1
#endasm
}
else{
#asm
bcf 0xFC0,7 // ADFM <- 0
#endasm
}
#asm // configura Tacq = 2Tad
bsf 0xFC0,3
bcf 0xFC0,4
bcf 0xFC0,5
#endasm
set_adc_channel(0);
}#include <18f4550.h> //archivo de cabecera
#DEVICE ADC=10 // cad a 10 bits, justificación a a la derecha
#fuses XTPLL,NOMCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,NOVREGEN,NOPBADEN
#use delay(clock=48000000)
// el resto queda igual
...
...
/* aplicación al ejemplo6_parte5, el resultado del CAD se enviará a una LCD
y al mismo tiempo (si hay conexión) al PC, mostrando el estado del USB.
se ha incluido una bandera en la librería pic18_usb.h de manera de saber
cuando ocurre la llamada attach y detach
parte de este código corresponde al original de RRCdcUSB de RedPic
Pedro-PalitroqueZ 13-feb-07
*/
#include <18F4550.h>
#DEVICE ADC=10 // cad a 10 bits, justificación a a la derecha
#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
#define DERECHA 0
#define IZQUIERDA 1
short estado_usb; // boolean global, se debe declarar antes de llamar a usb_cdc.h
#include <lcd.c>
#include "usb_cdc.h"
long value;
void config_adcon2(short justificacion);
void mostrar_estado_usb(short bandera);
void main(){
int i;
set_tris_a(0x3); // ra[1,0]=entradas, los demas=salida
estado_usb=false;
usb_cdc_init(); // llamadas necesarias para iniciar el módulo USB
usb_init_cs(); // inicia el USB y sale. va a la par con usb_task()
lcd_init(); // llamadas necesarias para iniciar la LCD
setup_adc_ports( AN0 || VSS_VDD ); // canal AN0, Vref+ = Vdd, Vref- = Vss
config_adcon2(DERECHA);
while(true){
usb_task(); // configura el USB
mostrar_estado_usb(estado_usb);
value = read_adc();
if(input_state(PIN_A1)){ //pregunta por el switche
config_adcon2(DERECHA);
}else{
config_adcon2(IZQUIERDA);
}
for(i=0;i<16;i++){
lcd_gotoxy(16-i,1);
lcd_putc((char)(bit_test(value,i)+0x30));
}
printf(lcd_putc,"\n0x%Lx",value);
if(usb_cdc_connected()){
// espera a detectar una transmisión de la PC (Set_Line_Coding)
if (usb_enumerated()){ // aquí se hace el acceso HOST<->PC y después sale
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?
printf(usb_cdc_putc,"%Lx", value); // envia el ADRESH:ADRESL al HOST
}
}
}
}
}
}
/************************************************
// esta llamada imprime en la LCD los estados de conectado
// y desconectado del USB dependiendo de la bandera
// estado_usb
//***********************************************/
void mostrar_estado_usb(short bandera){
lcd_gotoxy(10,2);
if(bandera){
lcd_putc(" USB:On");
}else{
lcd_putc("USB:Off");
}
//delay_ms(500);
}
//-----------------------------------------------------------------------------------------
// cumple la función de configurar el bit ADFM para hacer
// la justificación, también se incluye el retardo por hardware de Tacq
// datos de entrada: bandera de justificación
// datos de salida: nada
//-----------------------------------------------------------------------------------------
void config_adcon2(short justificacion){
setup_adc(ADC_CLOCK_DIV_64 ); // reloj de conversión = Fosc / 64
if(justificacion){
#asm
bsf 0xFC0,7 // ADFM <- 1
#endasm
}
else{
#asm
bcf 0xFC0,7 // ADFM <- 0
#endasm
}
#asm // configura Tacq = 2Tad
bsf 0xFC0,3
bcf 0xFC0,4
bcf 0xFC0,5
#endasm
set_adc_channel(0);
}
usb_cdc_line_coding.dwDTERrate=9600;
usb_cdc_line_coding.bCharFormat=0;
usb_cdc_line_coding.bParityType=0;
usb_cdc_line_coding.bDataBits=8;
...
' 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
' del resultado del CAD
' 13-feb-07 Pedro - PalitroqueZ
Option Explicit
Dim value As Long
Const color_verde = &HFF00&
Const color_rojo = &HFF&
Dim bandera As Boolean
Function cambiar(valor As Long)
Dim t As Integer: Dim asa As String: Dim pepe As String
pepe = HEXA_BIN(CStr(Hex(valor)))
'Debug.Print "pepe= " & Len(pepe)
'MsgBox pepe
For t = 1 To 16
' Debug.Print pepe
asa = Mid$(pepe, t, 1)
' Debug.Print asa
Label1(t - 1).Caption = asa ' es t-1 porque la matriz cuenta desde 0
Next t
End Function
Private Sub Check1_Click()
On Error GoTo palla
DoEvents
If Check1.value = 1 Then
DoEvents
Timer1.Enabled = False
Check1.ForeColor = &H8000&
Check1.Caption = "Recibiendo datos..."
If MSComm1.PortOpen = True Then
Timer2.Enabled = True
End If
Timer1.Enabled = True
Else
DoEvents
Timer2.Enabled = False
Check1.value = 0
cambiar (0) '
separar (0) ' limpia los caracteres del display
Check1.ForeColor = color_rojo
Check1.Caption = "Nada que recibir"
Timer1.Enabled = True
End If
Exit Sub
palla:
DoEvents
' Check1.value = 0
'Check1.ForeColor = color_rojo
'Check1.Caption = "Nada que recibir"
Timer2.Enabled = False
Timer1.Enabled = True
Exit Sub
End Sub
Function separar(valor1 As Long)
Dim i As Integer: Dim cadena As String
cadena = CStr(Hex(valor1))
Select Case Len(cadena) ' casos para que se mantenga el numero en LSB
Case 3: cadena = "0" & cadena
Case 2: cadena = "00" & cadena
Case 1: cadena = "000" & cadena
End Select
For i = 1 To 4
lblhex(i - 1).Caption = Mid$(cadena, i, 1)
Next i
End Function
Private Sub Command1_Click()
Unload Me
End Sub
Private Sub Form_Load()
Dim i As Integer: Dim adres As String
For i = 0 To 15
Label1(i).Alignment = 2
Label1(i).Font.Size = 14
Label1(i).Font.Bold = True
Label1(i).ForeColor = 0
Next i
For i = 0 To 3
lblhex(i).Alignment = 2
lblhex(i).Font.Size = 14
lblhex(i).Font.Bold = True
lblhex(i).ForeColor = 0
Next i
Check1.value = 0
Check1.ForeColor = color_rojo
Check1.Caption = "Nada que recibir"
shpestadousb.FillColor = color_rojo
'adres = "&H" & "3ff" & "&"
'value = Val(adres)
cambiar (0) '
separar (0) '
MSComm1.CommPort = 4
MSComm1.OutBufferSize = 1 'tamaño del dato a transmitir
MSComm1.InBufferSize = 4
'MSComm1.InputMode = comInputModeText 'los datos se recuperan en modo texto
MSComm1.InputLen = 4 ' BUFFER DE ENTRADA SE PUEDE DEJAR AL MAXIMO
' MSComm1.PortOpen = True
MSComm1.RThreshold = 4 'son 4 caracteres el par ADRESH:ADRESL
Timer1.Interval = 10
Timer1.Enabled = True
Timer2.Interval = 100
Timer2.Enabled = False
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 "dato llegada: " & InBuff
cambiar (Val("&H" & Left$(InBuff, 4) & "&")) '
separar (Val("&H" & Left$(InBuff, 4) & "&")) '
'MSComm1.PortOpen = False 'cierra el puerto y vacia el buffer
End Select
End Sub
Private Function HEXA_BIN(hexadecimal As String) As String
Dim numero_hexa As String, resultado As String, i As Long, cadena As String
resultado = ""
'Debug.Print "hexadecimal= " & Len(hexadecimal)
Select Case Len(hexadecimal) ' casos para que se mantenga el numero en LSB
Case 3: hexadecimal = "0" & hexadecimal
Case 2: hexadecimal = "00" & hexadecimal
Case 1: hexadecimal = "000" & hexadecimal
End Select
For i = 1 To Len(hexadecimal)
numero_hexa = Mid(hexadecimal, i, 1)
Select Case numero_hexa
Case "0"
cadena = "0000"
Case "1"
cadena = "0001"
Case "2"
cadena = "0010"
Case "3"
cadena = "0011"
Case "4"
cadena = "0100"
Case "5"
cadena = "0101"
Case "6"
cadena = "0110"
Case "7"
cadena = "0111"
Case "8"
cadena = "1000"
Case "9"
cadena = "1001"
Case "A"
cadena = "1010"
Case "B"
cadena = "1011"
Case "C"
cadena = "1100"
Case "D"
cadena = "1101"
Case "E"
cadena = "1110"
Case "F"
cadena = "1111"
End Select
resultado = resultado & cadena
'Debug.Print resultado
numero_hexa = ""
Next i
HEXA_BIN = resultado
End Function
Private Sub Timer1_Timer()
On Error GoTo paca
DoEvents
If MSComm1.PortOpen = True Then
DoEvents
shpestadousb.FillColor = color_verde
'lblestado.Caption = "Conectado"
Debug.Print "Conectado"
'MSComm1.Output = "a"
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
shpestadousb.FillColor = color_rojo
'lblestado.Caption = "Desconectado"
Case 8005 'el puerto ya está abierto
DoEvents
shpestadousb.FillColor = color_rojo
' lblestado.Caption = "puerto abierto"
Case 8012 '8012 el dispositivo no está abierto
DoEvents
shpestadousb.FillColor = color_rojo
'lblestado.Caption = "Desconectado"
Case 8015
DoEvents ' para evitar retardos en bucles
shpestadousb.FillColor = color_rojo
'lblestado.Caption = "Desconectado"
Case 8018
DoEvents
shpestadousb.FillColor = color_rojo
End Select
cambiar (0) '
separar (0) '
Check1.value = 0
Exit Sub
End Sub
Private Sub Timer2_Timer()
On Error GoTo palla1
MSComm1.Output = "a"
Exit Sub
palla1:
'Timer2.Enabled = False
'Check1.value = 0
Timer1.Enabled = True
Exit Sub
End Sub
short estado_usb; // boolean global, se debe declarar antes de llamar a usb_cdc.h
void main() {
output_d(0x01);
delay_ms(300);
usb_cdc_init();
usb_init();
while(!usb_cdc_connected()) {}//No continua hasta que el puerto USB se conecte.
do{
usb_task();
output_bit( PIN_d1,estado_usb);
if (usb_enumerated()) {//Si El puerto Com virtual es activado: if(estado_usb=1){
if(z==0)output_toggle(pin_d0);
z++;
}
else output_high(pin_d0);
}
}WHILE(1);
}Hola amigos, pues queria comentar que la com CDC esta de maravila :-/ :-/ :-/ .
El unico detalle que tengo es el siguiente:
Mi programa, debe saber en que momento el puerto Com que le corresponde, es abierto, ya sea por el hyperterminal.
No se si entendi mal respecto a la variable estado_usb.
Su funcion es la de saber si el PIC esta conectado al USB y detectado y recibido por el windows. ó detecta en que momento se habre el puerto Com.
Saludos a todos y muchas gracias Pedro por este gran aporte para todos.
Saludos!
Hola amigosCódigo: [Seleccionar]void main() {
output_d(0x01);
delay_ms(300);
usb_cdc_init();
usb_init();
while(!usb_cdc_connected()) {}//No continua hasta que el puerto USB se conecte.
do{
usb_task();
output_bit( PIN_d1,estado_usb);
if (usb_enumerated()) {//Si El puerto Com virtual es activado: if(estado_usb=1){
if(z==0)output_toggle(pin_d0);
z++;
}
else output_high(pin_d0);
}
}WHILE(1);
}
Bueno con el codig anterior, pretendo lo siguiente. Cuando conectas el PIC al USb. se debe encender el pin D0. y el pin D1, muestra lo que tiene l variable estado_usb. Al comienzo, todo bien. arranca encendido D0 y apagado D1. hasta ahora va perfecto.
ejecuto Hyperterminal. abro el puerto COM, y perfecto D1 se enciende y D0, empieza a parpadear. PERFECTO!
Cuando en el hyperterminal cierro el puerto, deja de parpadear D0, Perfecto. PERO!
D1, se me queda encendio, y necesito que se quede apagado, indicando que el COm esta cerrado.
Como puedo detectar eso??
Bueno amigos, es que despues de leer ahora si detenidamente todos tus avances amigo pedro, ya entiendo por que no se apaga, ya que usb_task() lo que hace es detectar si estas conectado fisicamente al puerto USB. y como yo no uso USB_CON_SENSE_PIN. es por ello que no se apaga.
si esta bien mi reflexion?? jeje :-) Esto del USB es para quedar LoCo. :z). Sin la ayuda de ustedes, seria bien pesada la cuesta.
...
Bueno ahora si planteo la pregunta de una forma mas concreta:
Como se puede hacer para que el PIC detecte que el COM virtual fue abierto por hyperterminal????
Bueno, haciendo pruebas, veo lo siguiente. Me perdonan si es que esto ya se habla antes, si es asi por favor me avisan para borrarlo.
habilite el pin A1 como USB_CON_SENSE_PIN, efectivamente. A pesar de haber colocado el canle USB, si no conecto A1 a VCC_USB, no conecta.
Antes de colocar A1, D0 y D1, apagados. PIC=Desconectado.
Coloco A1. Pito en windows de detectado y aceptado por el. D0 y D1. Apagado.
(Aca es donde me doy cuenta que mi reflexion anterior no es tan cierta. Ya que a pesar de que A1 esta detectado VCC_USb, D1 no enciende???? no se :?)
Abro Hyperterminal. selecciono Com7(virtual) y le doy abrir puerto y !!! se enciende D1 y empieza a parpadear D0. Perfecto por D0. pero D1 hummm :( . Seguiere en las pruebas a ver como resulta esto.
cita:
...
"Los dispositivos (o mejor dicho, las funcionas) tienen asociados unos canales
lógicos unidireccionales (llamados pipes) que conectan al host controlador con
una entidad lógica en el dispositivo llamada endpoint. Los datos son enviados
en paquetes de largo variable (potencia de 2). Típicamente estos paquetes son
de 64, 128 o más bytes.
Estos endpoints (y sus respectivos pipes) son numerados del 0 al 15 en cada
dirección, por lo cual un dispositivo puede tener hasta 32 endpoints (16 de
entrada y 16 de salida). La dirección se considera siempre desde el punto de
vista del host controlador. Así un endpoint de salida será un canal que
transmite datos desde el host controlador al dispositivo. Un endpoint solo
puede tener una única dirección. El endpoint 0 (en ambas direcciones) está
reservado para el control del bus."
...
...
/* usb_put_packet(endpoint,*ptr,len,toggle)
/*
/* Input: endpoint - endpoint to send packet to
/* ptr - points to data to send
/* len - amount of data to send
/* toggle - whether to send data with a DATA0 pid, a DATA1 pid, or toggle from the last DATAx pid.
/*
/* Output: TRUE if data was sent correctly, FALSE if it was not. The only reason it will
/* return FALSE is if because the TX buffer is still full from the last time you
/* tried to send a packet.
/*
/* Summary: Sends one packet out the EP to the host. Notice that there is a difference
/* between a packet and a message. If you wanted to send a 512 byte message you
/* would accomplish this by sending 8 64-byte packets, followed by a 0 length packet.
/* If the last (or only packet) being sent is less than the max packet size defined
/* in your descriptor then you do not need to send a 0 length packet to identify
/* an end of message.
...
/*******************************************************************************
/* usb_get_packet(endpoint, *ptr, max)
/*
/* Input: endpoint - endpoint to get data from
/* ptr - where to save data to local PIC RAM
/* max - max amount of data to receive from buffer
/*
/* Output: the amount of data taken from the buffer.
/*
/* NOTE - IF THERE IS NO PACKET TO GET YOU WILL GET INVALID RESULTS!
/* VERIFY WITH USB_KBHIT() BEFORE YOU CALL USB_GET_PACKET()!
/*
/* Summary: Gets a packet of data from the USB buffer and puts into local PIC RAM.
/* Until you call usb_get_packet() the data will sit in the endpoint
/* buffer and the PC will get NAKs when it tries to write more data
/* to the endpoint.
...
Hola Slalen. me estoy ayudando con tus traducciones y veo que trabajas con el C18, mejor que mejor así hay material para ambos compiladores. voy a bajarlo a ver que tal es..
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!!
PalitroqueZ muchas gracias por el aporte, en un inicio como no tengo puertos seriales usaba un adaptador rs232-usb y un max232 para comunicarme con mi PIC, ahora acabo de pasar mi codigo para que use USB para que emule el puerto COM y va de maravilla ya no necesito ninguno de los dispositivos que anteriormente mencione solo el pic y directo a la PC :-/ :-/ :-/ :-/.
Sigue adelante que la información que posteas es muy valiosa.
Saludos
FJPPitta
nos arroja 10000, y pienso que como hay 8 dígitos, ya que la versión es en hexa (8 nibbles = 32bits) -> versión dll = 1.0.0.0.0
empezaremos hacer modificaciones al ejemplo de Slalen (esperemos que Slalen no se moleste :D)
hola compañeros se me hace interesante este tema, les tengo una pregunta se podria comunicar este pic con un celular via usb??
en especifico mandar codigos at al telefono??
saludos
Palitroquez usa los adjuntos del foro para las fotos que tienes pegadas... que los servicios gratuitos los borran con el tiempo. Entiendo que los pusiste así para evitar cargar el foro pero las imágenes y el post son lo suficientemente interesantes para conservarlas aquí.
1 saludo
...
De la misma forma esta libreria posee get_int_usb() y para float y double, todavia no he comprobado su funcionamiento pero seguramente funcionen igual de bien que la de strings.
Palitroquez, a ver si me puedes echar una mano con esto. me he dado una vuelta por el foro buscando informacion sobre generar o empaquetar ficheros ejecutables o instalables de mis aplicaciones creadas con visual studio .net 2005. La informacion encontrada no me acaba de resolver de todo el problema. El objetivo es hacer unos ficheros instalables para correr mis aplicaciones en otros equipos que no posean el entorno visual studio instalado. La verdad es que se me echa el tiempo encima. Gracias de antemano.
Txiku
Enhorabuena Slalen, ¡te habrás quedado agusto después de escribir 653 páginas, macho!
Enhorabuna Slalen por tu proyecto de fín de carrera y gracias por compartirlo con todos. Es un excelente trabajo que aclara muchas dudas en cuanto al USB y a los micros (practicamente tenemos un datasheet en toda regla). Solo me queda animarte para que continues con la superior.
Un saludo.
...
Ya resolvi el problema de los ficheros ejecutables e instalables de Visual studio. Este es mi caso particular ya que estaba usando el control Mscomm importado desde VB6 con el Mscomm32.ocx. La forma de crear ficheros ejecutables y llevarlos a otro equipo es mediante el menu "BUILD" y se crearan en el directorio del proyecto en una carpeta llamada Debug o Release. Para crear un archivo instalable y exportarlo a otro equipo sirve con el menu "PUBLISH". En mi caso he tenido que registrar en el Pc donde queria correr mi aplicacion, el fichero Mscomm32.ocx, que se encarga de controlar el puerto serie. Haciendo este registro y ejecutando el fichero ejecutable ya tengo mi aplicacion funcionando en cualquier Pc.
No olvidar instalar la version correspondiente del Microsoft .NET framework
...
(Slalen) ¿Guillermo ese es tu nombre?
acabo de darle una ojeada a tu tesis, y dejame FELICITARTE por el empeño y el esmero que le pusiste. como decimos aquí "le echaste un camión a ese proyecto" :-/ :-/
bueno amig@s con esta tesis tienen una BUENA referencia para los que quieran empezar con el 18F4550 y sus hermanos 'menores', está TODO TODO explicado y en ESPAÑOL sobre la arquitectura de este uC PIC y como no podía faltar el módulo USB.
seguiré leyendo en otro rato, son demasiadas paginas. :)
PD:
le echaste un camión: dedicarle mucho empeño a una meta propuesta.
Since Timer0 is shut down in Sleep mode, the TMR0
interrupt cannot awaken the processor from Sleep.
...es que estoy trabajando sola y no tengo quien me pueda guiar ni un poco, asi que te agradeceria cualquier ayuda y disculpa las molestias, gracias
... y si lo puedo trabajar a 9600 baudios??
...
hola, se me paso por alto pregunta, lo que he leido es que el mssp para trabajar la comunicacion serial pero sincronica hay mucha diferencia que trabajar en forma asincronica ? gracias
Hola a todos... haber, tengo una duda para variar jeje he estado intentando probar los distintos programas con el usb que an hecho J1M y PalitroqueZ y bueno cual ha sido mi sorpresa que para cada programa necesito unos controladores distintos... me explico... si cargo en el pic un programa de J1M me pide los driver suyos y si cargo uno de PalitroqueZ quiere los controladores de PalitroqueZ(que por cierto no los encuentro por ningún sitio a si que no he podido probar sus programas todavía) esto es asi(espero que no).... estoy haciendo algo mal....
Por otro lado en mi intento de aprender a programar en C los pics me he descargado el CCS PCWH 4.057 pero para ponerlo a funcionar me pide unos archivos de registro los cuales no encuentro por ningún sitio, tb he intentado hacerme con el MPLAB C18 pero es imposible compilar un archivo en C entre otras cosas pq por ejemplo los codigos fuente que se pueden coger de este foro pues en su cabecera incluyen dos o tres archivos los cuales tampoco encuentro, hay.... si mi ensamblador diese tanto de si como para programar el USB :D
Bueno un saludo, espero que mis preguntas no sean de autentico novato jeje aunque si me gustaría aclararlas...
PD: Por cierto que se me olvidaba un trabajo estupendo PalitroqueZ animo....
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 SubHola Pali, estoy probando los ejemplos:
- ejemplo6_parte5
- ejemplo6_parte6
El ejemplo6_parte5 no me funciona bien. No siempre que pulsas sobre enviar el caracter "a" lo hace, a veces lo hace y a veces no. Idem para la recepción del mensaje enviado por el PIC.
Creo que se debe a:Código: [Seleccionar]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 este procedimiento entra cada 10ms y está contínuamente cerrando y abriendo el puerto. Por eso si intentas enviar el caracter "a" y el puerto está cerrado pués no lo envia. Idem al recibir.
¿Qué te parece?
Otra cosilla, en el adjunto para bajar del ejemplo6_parte6 no aparece la parte de VB. El código se podría copiar pero la parte gráfica no. Que raro que en todo este año que ha pasado desde que lo publicaste nadie haya dicho nada.
Public Declare Function MPUSBGetDLLVersion Lib "mpusbapi.dll" () As Long
Public Declare Function MPUSBGetDeviceCount Lib "mpusbapi.dll" (ByVal pVID_PID As String) As Long
Public Declare Function MPUSBOpen Lib "mpusbapi.dll" (ByVal instance As Long, ByVal pVID_PID As String, ByVal pEP As String, ByVal dwDir As Long, ByVal dwReserved As Long) As Long
Public Declare Function MPUSBClose Lib "mpusbapi.dll" (ByVal handle As Long) As Long
Public Declare Function MPUSBRead Lib "mpusbapi.dll" (ByVal handle As Long, ByVal pData As Long, ByVal dwLen As Long, ByRef pLength As Long, ByVal dwMilliseconds As Long) As Long
Public Declare Function MPUSBWrite Lib "mpusbapi.dll" (ByVal handle As Long, ByVal pData As Long, ByVal dwLen As Long, ByRef pLength As Long, ByVal dwMilliseconds As Long) As Long
Public Declare Function MPUSBReadInt Lib "mpusbapi.dll" (ByVal handle As Long, ByVal pData As Long, ByVal dwLen As Long, ByRef pLength As Long, ByVal dwMilliseconds As Long) As Long
Private Sub Form_Load()
OpenMPUSBDevice 'abre comunicaciones
End SubNo se puede encontrar el punto de entrada denominado 'MPUSBOpen' en el archivo DLL 'mpusbapi.dll'.Estoy realizando el ejemplo de abrir/cerrar el puerto ¿Hace falta enlazar a la mpusbapi.dll de alguna manera especial? Yo declaro las librerias, asi:Código: [Seleccionar]Public Declare Function MPUSBGetDLLVersion Lib "mpusbapi.dll" () As Long
Public Declare Function MPUSBGetDeviceCount Lib "mpusbapi.dll" (ByVal pVID_PID As String) As Long
Public Declare Function MPUSBOpen Lib "mpusbapi.dll" (ByVal instance As Long, ByVal pVID_PID As String, ByVal pEP As String, ByVal dwDir As Long, ByVal dwReserved As Long) As Long
Public Declare Function MPUSBClose Lib "mpusbapi.dll" (ByVal handle As Long) As Long
Public Declare Function MPUSBRead Lib "mpusbapi.dll" (ByVal handle As Long, ByVal pData As Long, ByVal dwLen As Long, ByRef pLength As Long, ByVal dwMilliseconds As Long) As Long
Public Declare Function MPUSBWrite Lib "mpusbapi.dll" (ByVal handle As Long, ByVal pData As Long, ByVal dwLen As Long, ByRef pLength As Long, ByVal dwMilliseconds As Long) As Long
Public Declare Function MPUSBReadInt Lib "mpusbapi.dll" (ByVal handle As Long, ByVal pData As Long, ByVal dwLen As Long, ByRef pLength As Long, ByVal dwMilliseconds As Long) As Long
Cuando despues intento usar :Código: [Seleccionar]Private Sub Form_Load()
OpenMPUSBDevice 'abre comunicaciones
End Sub
Me dice que variable no esta declarada.
Sin usar esta declaración, me compila pero al intentar abrir me dice:Código: [Seleccionar]No se puede encontrar el punto de entrada denominado 'MPUSBOpen' en el archivo DLL 'mpusbapi.dll'.
La .dll esta en la misma carpeta, pero es como si no se "conectara" con la api. Uso visualbasic.net
Que gran Topic en serio................. mis mas sinceras felicitaciones para PalitroqueZ, me esta siendo de mucha ayuda ahora q empiezo con este PIC.
Saludos
del p...tas todo lo que han hecho con este pic, yo espero dominar el 877 (me ha sacado canas) y poder iniciarme en programas basicos con el 18F4550 como cuando me inicie con el 16F84A "prendiendo y apagando un led" :mrgreen:
Felicitaciones y gracias por estos aportes
Buenas, despues de haber probado con exito el ejemplo de Diego, del keyboard USB, me dispuse a probar hacer un joystick, asi que con el mismo cirtuito, intento hacer andar el AD del 18f4550, pero no hay caso.. no funciona, el resultado siempre es 0, probe cambiando distintos canales, distntas frecuencias de conversion, y nada, lo utilice muchas veces a la conversion AD con el 18f452, y ahora no puedo hacer andar en el 455, pego un trozo del programa donde configuro distintas cosas para el AD, a ver si alguien ve un error, lamentablemente no tengo otro pic para comprobar que no este quemado el AD.
En este ejemplo envio el dato por USB, tambien para asegurarme que no era error del USB, hice la prueba con el puerto serie, pero siempre lo mismo.
Desde ya gracias.
Alejandro.Código: CSS
void main() { int8 Trim[2]; int8 Buffer; set_tris_a(0b00001111); //set_tris_c(0b11110000); setup_adc_ports(ADC_CLOCK_DIV_64); setup_adc_ports( AN0_TO_AN3 ); setup_comparator(NC_NC_NC_NC); setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_8 ); setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1|RTCC_8_BIT); delay_ms(500); usb_init_cs(); port_b_pullups(false); set_tris_b(0b00000001); ext_int_edge(0,L_TO_H); enable_interrupts(int_ext); disable_interrupts(INT_TIMER1); disable_interrupts(int_tbe); enable_interrupts(INT_TIMER0); enable_interrupts(global); set_adc_channel(1); while (TRUE) { int8 rTemp; usb_task(); usb_debug_task(); if(usb_enumerated()) { if (fTX){ TxUSB[0]=read_ADC(); usb_put_packet(1, TxUSB, 8, USB_DTS_TOGGLE); fTX=0; } } } }
#include<p18F4553.h>
#include<spi.h>
#include<delays.h>
void envio(unsigned char valor)
{
unsigned char comando;
comando=0x00010001;
OpenSPI(SPI_FOSC_4, MODE_11, SMPEND);
WriteSPI(comando);
WriteSPI(valor);
CloseSPI();
}
void main (void)
{
int i;
for(i=0;i<=255;i++)
{
envio(i);
Delay1KTCYx(45);
}
}
Buen post, quiero configurar el pic a 48 Mhz con un cristal de 4 Mhz en la entrada, estoy programando en asm, pongo las palabras de configuración para tener los 48 Mhz como aqui esta explicado y luego simulo en proteus, pero no veo que el cpu corra a esa velocidad, en la opción de CPU speed tengo 4 Mhz, entones, a que le hace caso proteus, a ese valor que tiene o al de las palabras de configuración, ahora no tengo tal pic pero como podría probar en el circuito real que el pic funciona a 48 Mhz.
Gracias
he estado trasteando con el usb cdc, y tambien quiero poner al pic a hacer otras cosas mientras no esta conectado al COM, ahora, mi pregunta es si es camisa de fuerza utilizar el USB_CON_SENSE_PIN, ya que segun lei usb_task() devuelve true asi este definido o no el pin de sensado.
Edit: :-), listo, una confusion. ;-)
Hola PalitroqueZ muy buen trabajo, yo estoy decidiendome por iniciar con los 18F, pero he leido por allí que se necesita otro software más para usar los 18F, el C18, pero veo que tu has programado como normalmente se programaría con el C16, hay alguna diferencia importante entre ambos?, por que no logro comprender poruqe la mayoria programa con el C18 si también se puede con el de toda la vida y accesar a todos los módulos, además que con el C18 cambian algunas instrucciones, como la configuración de fuses. Gracias.