• No se han encontrado resultados

Primeros Pasos Con El 18F4550

N/A
N/A
Protected

Academic year: 2021

Share "Primeros Pasos Con El 18F4550"

Copied!
133
0
0

Texto completo

(1)

2010

Primeros pasos con el 18F4550

www.unpocodelectronica.netau.net

[

PRIMEROS PASOS CON EL

18F4550

]

(2)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 2

Introducción Etapa Osciladora

Conociendo el PiN1 MCLR PORTx vs LATx

Módulo CAD o ADC (I) Módulo CAD o ADC (II) Primera Práctica: PiCUSB USB CDC (I)

USB CDC (II)

Monitorear el puerto COM virtual Detectando el HOST (I)

Detectando el HOST (II) Primera Aplicación CDC Conociendo al SnoopyPRO mpusbapi.dll (I) mpusbapi.dll (II) mpusbapi.dll (III) mpusbapi.dll (parte 4) mpusbapi.dll (parte 5)

mpusbapi.dll (Primera Aplicación)

Agradecimientos y Méritos Correspondientes

(3)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 3

Introducción:

Mis Primeros pasos son una serie de artículos que describen la introducción al mundo de los uC-PIC 18F de Microchip, a través del 18F4550.

el enfoque está orientado a aprender desde cero de alguien (el autor) que viene de conocer y utilizar la serie uC-PIC 16F e intenta conocer poco a poco las nuevas funcionalidades, características y módulos que ofrece la serie 18F.

se empieza hablando sobre el aspecto físico y analogías con el uC-PIC 16F877, particularidades en pines, para después entrar hablar, sobre el módulo convertidor analógico digital (ADC) y el módulo “estrella” de 18F4550 como lo es Bus Serial Universal (USB), donde se hace un estudio paso a paso para hacer las primeras transmisiones, basándose en las librerías que provee el compilador de C de CCS. como nota adicional, quisiera decir que esta serie de artículos de mis primeros pasos

con el 18F4550, fué escrita hace mas de 2 años por lo que las ideas expresadas en sus

contenidos pueden estar estar “obsoletas” o “fuera de carril”.

He querido dejar casi intacto esta serie de artículos desde su origen, ya que la intención es mirar con la perspectiva de un novato la introducción a los 18F tal como yo lo hice cuando tuve en mis manos el primer 18F.

el enfoque de estos artículos, fué usando una redacción un poco coloquial, mis excusas para aquellos que sientan que no hay una redacción propia de un artículo.

Configurando la Etapa Osciladora mediante los bits de Configuración

(Fuses)

Lo primero que hice fue adaptar mi programador para este PIC, mi programador es por puerto paralelo y lo use en conjunción con el winpic800 de Sisco, para poder grabar el 18F4550.

-Lo segundo, meterme de cabeza en la datasheet a ver que cosas nuevas trae este señor, respecto al anterior 16F877 (del cual vengo) y ¡uff! si que trae una montaña de

(4)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 4 Pinout del 18F4550

ya sabemos que el 18F4550 posee 40 pines, bien y por lo que se ve en la imagen, tiene cierta similitud con el 16F877 (la misma ubicación del pin vdd, vss, mclr entre otros) el siguiente paso es saber como trabaja la configuración del oscilador, en verdad a primera vista con el diagrama del clock que aparece en la Pág. 26, parece complicado, pero no es tan difícil, si se ve como si fuera el juego del laberinto, se pueden activar los bits de los registros necesarios y así configurar el oscilador para el cristal que usemos y el tiempo del ciclo de instrucción.

En la página de PicManía de Diego (RedPic) hay un artículo llamado: Consiguiendo 4 Mhz para los 48 Mhz necesarios en los PIC’s con USB 2.0, siguiendo las instrucciones podemos configurar el CPU del 18F4550 a 48Mhz con solo seleccionar los word

configuration correctos.

como yo tengo un cristal de 4MHZ, lo usaré para poner a trabajar el CPU a 48MHZ, y ¿porque 48 MHZ? ¡claro! si se puede llegar hasta ahí, ¡entonces a trabajar al máximo!

según la elección de mi cristal dibujé el camino a tomar para que la etapa del oscilador tenga 48Mhz a la entrada del cpu, partiendo de los 4MHZ que le entran

(5)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 5 Configuración del modulo oscilador de 4MHz a 48Mhz

esto es necesario porque lo primero que debemos tomar en cuenta son los fuses que se van a usar y la configuración del oscilador forma parte de ello

para colocar el fuse de configuration y ya que es la primera vez, tomaré prestado de la que he visto en ex_usb_serial2.c que trae de ejemplo del compilador PCWH de CCS

1 2 3 4 5 6 ...

//configure a 20MHz crystal to operate at 48MHz

#fuses

HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN #use delay(clock=48000000)

(6)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 6 esto hay que analizarlo, hay algunos conocidos y otros nuevos (que se van a explicar), así que vayamos a la página 288 de la datasheet y al archivo cabecera 18F4550.h HSPLL: para cristales >4MHZ usando el PLL, en el código ejemplo como XTAL=4MHZ -> se cambiará a XTPLL

MCLR: significa que el pin 1 cumplirá la función de Master CLeaR (¿y como arranca el PIC cuando no hay MCLR?)

USBDIV: significa que el clock del usb se tomará del PLL/2, para nuestro código es irrelevante, ya que no usaremos el módulo USB, pero lo dejaremos (o es “1″ ó es “0″) PLL5: significa que el PLL prescaler dividirá en 5 la frecuencia del cristal, si uso el cristal de 4MHZ no habrá falta dividir por lo que se usará PLL1

CPUDIV1: el PLL postscaler decide la división en 2 de la frecuencia de salida del PLL de 96MHZ, si queremos 48MHZ, lo dejaremos como está.

VREGEN: habilita el regulador de 3.3 volts que usa el módulo USB, no lo usaremos por los momentos, se cambiará por NOVREGEN

existen mas fuses para configurar, y habría que determinar como el compilador configura el resto

si miran el la página 288, notaran que existe mas de un configuration word (específicamente 7), no como en 16F877 que había solo uno.

bueno, nuestro fuse quedará así:

1 2

#fuses

XTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,NOVREGEN ahora viene escribir un código sencillo para poner arrancar el PIC, el programita lo que va a hacer es, encender y apagar el PORTB en intervalos de 1 seg. y para ello hay que averiguar como está configurado por defecto cada pin, me refiero a esto, ya que he manejado un poco el 16F877 y por ejemplo el pin RB3 siempre hay que configurarlo en el fuse si se va a utilizar como i/o digital

al mirar la página 293 nos encontramos otro fuse:

PBADEN: PORTB A/D Enable bit

¿¡Cómo!?, ¿el portb tiene funciones de entrada analógica?, pues sip, así que también hay que meter esa opción en el fuse. Vamos hacer una prueba, vamos a dejar tal cual quedó nuestro fuse, para ver como lo hace el compilador y lo sabremos cuando carguemos el .hex en el winpic800

(7)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 7 vamos a escribir este código en lenguaje C de CCS (para facilitar el aprendizaje pero sigo con el dilema si lo hago en C ó en asm, para conocer mejor al micro) y el

simulador será el MPLAB-SIM, que podemos hacer, hasta la fecha en que escribí esto el proteus todavía no trae el 18F4550

1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2

// 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,NOVREGE N

// 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

} }

(8)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 8 3 3 3 4 3 5 3 6 3 7 3 8 3 9 4 0 4 1 4 2 4 3

las lineas que están delimitadas, las saqué del código _rtc.c que escribió RedPic, en estas lineas se desactivan otros modulos, como por ejemplo el CAD, SPI, PSP, las interrupciones y las resistencias de amarre que están en el PORTB, para este PIC hay que averiguar como están configurados por defectos cada pin y allí veremos si hace falta habilitar ó deshabilitar ciertos modulos (esto se aplica también para los fuses)

Esto último lo digo porque el simulador es una cosa y el funcionamiento real es otra, en el caso de los fuses, nosotros podemos determinar la configuración porque el winpic800 nos lo dirá, pero en el caso de los módulos activados o desactivados por defecto, no siempre el simulador acertará, así que para estar seguros es mejor escribir las configuraciones en el programa. (esperemos que con esas sea suficiente) bueno, compilemos y simulemos a ver que tal.

(9)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 9 que bien nos compiló exitosamente, vamos a cargar el MPLAB-SIM y abrimos también la ventana de los SFR, para ir viendo como están los registros que nos interesa y los que nos pueden interferir.

nota: se me pasó por alto, con los pasos que indica el wizard crean el proyecto para el código que estamos probando y después configuran la frecuencia del CPU (los fuses no hacen falta configurarlo, porque el MPLAB los carga del que ya habíamos programado) vamos a ver como quedó el configuration bits

Bits de Configuración en MPLAB

¡epa! aquí dice que el portb tiene algunas entradas analógicas, vamos a ver que dice el

temp18.lst (el listado que genera el compilador)

1 2 3 4 5 6 7 8 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

efectivamente está la opción PBADEN, pues ya comprobamos que se debe colocar NOPBADEN en fuse, si es que queremos que RB[4-0] funcione como salida digital. el fuses quedará: 1 2 #fuses XTPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,NOVREGEN ,NOPBADEN

(10)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 10 compilamos y vemos nuevamente la ventana configuration bits

Bits de Configuración Corregido

ahora si nos aparece los pines RB[4-0] como i/o digitales.

Si por ejemplo simulamos con la opción PBADEN, verán como en el portb no habrá problemas, hará lo que el código le dice, pero cuando vayamos a probar el PIC, no será así. ¿Se dan cuenta? hay que estar pendiente de esos detallitos que nos pueden causar dolor de alma.

viendo los registros PORTB y uno nuevo, el LAT., verán que cambiarán de estado:

(11)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 11 Tiempo en Mplab-SIM

en la ventana stopwatch, se observa que por cada línea ejecutada ocurren mas de un ciclo de reloj, esto es típico del C, si queremos ver que ocurre en cada ciclo, nada mas carguemos Disassembly Lisa y veremos el código en C con su correspondiente asm

(12)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 12 una vez ya simulado y verificado, viene la parte crítica, y es la de programar el PIC,

montarlo en el protoboard y rezar para que funcione, podemos llegar a 2 resultados: -Que si funciona y realmente nos llena de alegría y podemos dar el siguiente paso ó

– Que no funciona y hay que volver a revisar todo nuevamente :-s

la segunda opción es la frecuente y que no nos gusta mucho, pero es la que nos dá el conocimiento. ¡Manos a la obra!

amigos, de buena suerte que todo ¡¡funcionó al primer arranque!! y es que se tomaron las previsiones una y otra vez, antes de conectar el PIC, verifiqué niveles de tensión, posición de los pines, etc.

http://www.youtube.com/watch?v=Wlpz-R9b0pY

en realidad con este primer ejemplo lo que se pretende, es aprender a configurar el oscilador y a configurar los fuses, que es lo básico a la hora de programar un PIC.

(13)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 13

Conociendo el Pin1 MCLR

Vamos con el segundo ejemplo. Quedaron 2 dudas al aire, el MCLR y el nuevo Registro de Funciones eSpeciales LATx.

vamos a tratar primero lo del MCLR.

donde busquen en la datasheet el MCLR, verán que hay una opción para desactivarlo (es es que si empieza desde el propio fuse) y lo que se me ocurre es que el PIC puede trabajar sin el Master CLeaR , sin los 5 voltios reglamentarios y que si queremos hacer un reset, será por software, cuya instrucción existe (se llama RESET)

si ven en la Pág. 126 verán que RE3 solo puede funcionar como entrada digital, así que tendremos que pegar un switch si queremos probarlo, (y vamos a colocarlo para que sea un cero en condiciones iniciales).

voy a modificar un poco el ejemplo1, cambio el fuse a NOMCLR (y automáticamente el pin RE3 <- entrada) de manera que si lee un pulso alto se enciendan los led´s del portb y si lee un pulso bajo se activan los led´s del portc.

otro detalle, leyendo la configuración del portc, me encuentro con que no existe RC3 y eso no es todo, RC4 y RC5 solo funcionan como entrada digital, parece que es el precio a pagar por implementar nuevos módulos ( ver Pág. 119)

El pin RC3 del 18F4550

Pines RC4, RC5 del 18F4550

vaya, vaya, como haremos. Bueno lo que se puede hacer es usar el resto de los pines que si funcionan como salida digital. RC[7-6,2-0]

1 2 3 4 5 6 7 8

// 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

(14)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 14 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 3 3 3 4 3 5 3 6 3 7 3 8 3 9 XTPLL,NOMCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL1,CPUDIV1,NOVRE GEN,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(7); // 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 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); // saca un nivel bajo en el portc delay_ms(1000);

output_c (0xff); //saca un nivel alto en portc delay_ms(1000);

} } }

(15)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 15 4 0 4 1 4 2 4 3 4 4 4 5 4 6 4 7 4 8 4 9 5 0

en los pines no usados del portc, del ejemplo1, no le dimos importancia, pero RC[5-4] estaban como entrada digital (según el MPLAB el módulo USB está deshabilitado por defecto) y no nos dimos cuenta y dejamos esos pines al aire, para resolver esto, coloqué unas resistencias de 1k a VSS

Nota acerca de RC4 y RC5 del 18F4550

después de compilar exitosamente (gracias Dios, jeje) y verificar los fuses veremos en la simulación en MPLAB a ver que pinta tiene:

(16)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 16 yo creo que no importa si limpiamos el TRISC, porque de todas manera RC[5-4]

quedaran como entradas, observen que en la simulación aparecen esos pines como salidas activándose (aunque el LATC aparece RC[5-3]<-0 ¿raro no?), ya hice la prueba y no encienden los led´s para esos pines.

nota: el circuito para este ejemplo está en el adjunto, en el circuito del ejemplo1 omití un componente que había puesto en el protoboard, es un condensador de 100nF entre VDD y VSS.

el montaje funcionando:

http://www.youtube.com/watch?v=YPHsHsEao10

el objetivo de este ejemplo fue el como trabajar el pin 1 del PIC 18F4550 y los detalles que trae el portc

el adjunto con el código fuente, circuito eléctrico, etc.

PORTx vs LATx

-¿Qué es eso de LATA, LATB,..?- si miran en la página 71 de 39632c.pdf, tenemos del LATA-LATE. La segunda que vemos el LAT es en la página 113 y ya empiezan a especificar su funcionamiento, el LAT significa output latch ó salida del latch, si comparamos una salida de este pic con uno del 16F877

(17)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 17 El pin RC3 del 18F4550

la diferencia principal que se ve allí es el buffer RD LAT cuya función es leer el estado de la salida del LAT (¿que función puede tener el leer la salida del LAT?) y WRLAT or PORT en el clock, bueno amigos como el datasheet no dá mayores explicaciones porque dice que puede ser cualquiera de los 2. Puedo escribir en el pin usando LATx,pin ó PORTB. Así que consultando los links de arriba, todos coinciden: el registro existe por cuestiones de rapidez al cambiar un flanco en un pin.

yo recuerdo que para evitar escrituras erróneas en la familia 16F manejando bit´s se recomienda colocar un nop entre pines:

1 2 3 bsf porta,0 nop bsf porta,1

obviamente que la existencia del registro LATx es una mejora ya que en un ciclo de instrucción garantizas la escritura en un pin del puerto, pero esto habría que

comprobarlo con un ejemplo

quería pegar este código en ensamblador pero dentro de entorno C 1 2 3 4 #asm bsf PORTB,0,1 bsf PORTB,1,1 #endasm

(18)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 18 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

donde a es un operando que tiene que ver con el tipo de acceso al banco de memoria RAM (bueno, ¿pero no se supone que la memoria RAM es lineal?), esa duda la dejaremos pendiente por los momentos.

entonces lo mejor es ensamblar desde el mpasmwin y ya que vamos a usar el 100% ensamblador, es bueno saber saber la configuración de los puertos, para ello veremos la inicialización de los puertos que salen a partir de la Pag 113 (corresponde al capítulo 10 I/O PORTS) y en la plantilla 4550temp.asm que está en la carpeta code dentro de

MPASM Suite

el archivo hlpPIC18ConfigSet.chm enseña como configurar los fuses

una nota curiosa vean la dirección señalada (viendo el listado en asm generado por el CCS del ejemplo2)

(19)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 19 así será de fea la programación en asm para los 18F que el propio MPLAB me lo dice, jaja

pero volviendo en serio, aquí vamos a tener que repetir un poco el ejemplo1, configurar los fuses que ya no se llamaran fuses, sino word configuration, configuratión bits. (ver Pag . 287)

La directiva de configuración de palabras se puede escribir CONFIG y seguido los bits involucrados (en 16F se escribe __CONFIG xx & yy &..) para mayor comodidad se puede escribir CONFIG CP = OFF, OSC = LP,..

tomando el fuse del ejemplo1 nuestra palabra de configuración quedará así:

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

aquí hay que escribirlos toditos, porque no se sabe como estan por defectos, pero sin complicar mucho la explicación lo que se hizo fué ver como el CCS configuraba los 7 word y llevarlos al asm, y eso fué lo que está arriba.

este ejemplo3 hará lo siguiente:

-RB0 es un switche (normalmente en “0″)

-si hay un cero en RB0-> se encenderán los led´s de RB[6,4,2] -si hay un “1″ en RB0-> se encenderán los led´s de RB[7,5,3,1] -en cada caso se apagarán los led´s no mencionados.

para la escritura del PORTB, primero se utilizará el clásico PORTB, a ver que sucede y después el LATB 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

; 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

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

(20)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 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 ;//---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

como pueden ver, en este código se va a comprobar que pasa si usamos la instrucción PORTB para manejar datos de salida y LATx

notas:

(21)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 21 movff 0×1,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)

-hay otra instrucción nueva el BRA, suena al salto que se utiliza en BASIC (que sería BRANCH) y ¿porque no usamos el goto? bueno también sirve, una diferencia que leí, es que el goto puede saltar mas lejos, para nuestro ejemplo el BRA sirve, lo dejaremos. ahora compilaremos el ejemplo3 y simularemos con el MPLAB (mirar con atención la ventana de la derecha, es la de Registros Funciones eSpeciales):

http://www.youtube.com/watch?v=uhYkxjsU6wU

el warning se debe a que la instrucción limpia un registro de solo 6 bits, los menos significativos, pero no hay rollo.

en la simulación vemos que ningún pin del puertoB cambia, ni el LATB, pero como yo soy necio, voy a grabar ese mismo código en el pic, haber que hace.

nota: la palabra de configuración la comparé con el del ejemplo1, e hice un cambio el BOR=ON el watchdog, aunque cambió, no altera el programa.

el video en protoboard:

http://www.youtube.com/watch?v=tAMmVcAKKGk

¡Qué! ¿y porque se quedan prendidos esos 3? vamonos a revisar el código, parece que hay un error en las instrucciones B(s/c)F, especificamente en el último argumento, yo les puse “1″.

Ese argumento tiene que ver con el acceso al banco de memoria, si vemos un momento el listado que genera el dissasembler:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ... 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: ;//---

(22)

---w ---w ---w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 22 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 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

(23)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 23 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 vemos que hay varias instrucciones que tienen un tercer argumento, este argumento define como se va a accesar al banco de memoria RAM. En la pagina 66 aparece el mapa de la memoria de datos

(24)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 24 mapa de la memoria

la memoria se divide en bancos y dependiendo de un tal BSR(registro selector de banco) se puede accesar a diferentes direcciones.

como esto es un tema aparte(que apenas estoy conociendo), solo diré, que por defecto el tercer argumento es “0″ ó como lo llama el mpasmwin (y el CCS también): ACCESS. Es válido si no se coloca nada, el MPLAB, lo asume como a=0 (ver pagina 67) se colocará “0″ en todas los B(s/c)F y el código quedará así:

1 2 3

; código ejemplo para hacer funcionar por tercera vez al PIC18F4550 mediante encendido

(25)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 25 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 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

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 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

(26)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 26 65 66 67 68 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

haciendo la simulación (mirar con atención la ventana de la derecha, es la de Registros Funciones eSpeciales):

http://www.youtube.com/watch?v=m-7uVP1ji6w

allí muestra que el PORTB cambia los estados de acuerdo a la programación escrita, ahora procedemos a grabar el pic y ver el comportamiento

http://www.youtube.com/watch?v=AwaivT3Fg3g

ahora si hace lo que tiene que hacer, encender los led´s pares e impares dependiendo del switcheo. pero entonces quiere decir que si se puede trabajar con el PORTB como salida.

vamos a tomar el otro caso, sustituiremos el PORTB por LATB en la escritura de los pines de salida (llamemos ejemplo3_lat).

el código cambiará así: 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8

; 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,NOVREGE N,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

(27)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 27 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 3 3 3 4 3 5 3 6 3 7 3 8 3 9 4 0 4 1 4 2 4 3 4 4 4 5 4 6 4 7 4 8 4

; 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

(28)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 28 9 5 0 5 1 5 2 5 3 5 4 5 5 5 6 5 7 5 8 5 9 6 0 6 1 6 2 6 3 6 4 6 5 6 6 6 7 6 8 6 9 7 0 7 1 7 2 7 3 7 4 7 5 7 6 7 7 7 8 7 9 end

(29)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 29 8

0 8 1

haciendo de nuevo la simulación: (mirar con atención la ventana de la derecha, es la de Registros Funciones eSpeciales)

http://www.youtube.com/watch?v=6ysIB7npYao

el puerto B se escribe como debe ser, muy bien. Ahora a quemar el pic y probar en el protoboard

http://www.youtube.com/watch?v=S559xGjpR6g obtenemos el mismo resultado.

La conclusión de este tercer ejemplo, bueno la verdad es que no se pudo demostrar el uso/comportamiento del PORTX frente al LATx, como escritura a los pines, creo que eso lo dirá la experiencia, ensayando y programando con el pic como ya lo han hecho los que saben sobre el tema.

(30)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 30

Módulo CAD o ADC (Parte1)

Usando el Módulo del Convertidor Analógico Digital (CAD ó ADC en inglés) Esta vez vamos a utilizar un módulo que se utiliza frecuentemente: el módulo del Convertidor Analógico Digital(CAD ó ADC en inglés), yo he realizado uno que otro montaje con este módulo, pero nunca lo he explicado (por allí dijeron que es mas difícil explicar que aplicar lo aprendido), así que intentaré aportar de lo que estoy conociendo. las fuentes consultadas:

-PICmicro® 18C MCU Family Reference Manual (39500a.pdf página 583) -configurar el estímulo del ADRESL

-Conceptos

-SALTO EN EL CONVERTIDOR A/D DE UN 16F877 -convertir 10 bits y quedarme con 8

nos vamos directo para la página 261 del 39632c.pdf, que es el datasheet del la familia PIC18F2455/2550/4455/4550 y allí está un capítulo dedicado a este módulo.

-las diferencias que leí respecto al 16F877, le agregaron un adcon2 y hay 13 posibles entradas analógicas multiplexadas.

-la configuración PCFG3:PCFG0 luce mas ordenada.

-Le agregaron unos bits que son muy interesantes ACQT2:ACQT0 para manejar el tiempo de adquisición, ya lo explicaremos.

- desde el punto de vista del 16F87xA(dentro de la familia 16) no ha cambiado las opciones del clock de CAD (hay 7 opciones)

Quisiera hacer un resumen del funcionamiento del CAD para poder explicar las nuevas opciones que trae el 18F4550 y las mejoras respecto al 16F877

La definición del Convertidor Analógico Digital, la podemos conseguir en la wikipic y se puede desglosar de la siguiente manera:

(31)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 31 Circuito entrada analógica

de acuerdo a la imagen anterior:

-existen unos pines que se pueden configurar como entrada analógica, del cual se toma uno a la vez.

-dado un arreglo R-C,que existe dentro, o a la entrada del módulo CAD se toma un nivel de tensión en un tiempo discreto, ese voltaje se almacenará en el condensador interno (Chold)

-el tiempo que tarde ese condensador en cargarse, lo determinaremos nosotros de 2 maneras:

-mediante un retardo por software (configurando un timer, ó generando ciclos de instrucción.

-mediante un retardo por hardware (configurando los bits ACQT2:ACQT0 en ADCON2)

este tiempo, es el tiempo de adquisición ó Tacq (acquire), y es fundamental para obtener precisión en el resultado digital. Ojo no confundir con Tad, como lo hice alguna vez, (las iniciales en inglés se asemejan a las iniciales en español).

en el caso del 16F877, mediante cálculos teóricos era Tacq ~ 20uS

(32)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 32 en el caso del 18F4550, el tiempo mínimo que sacan es Tacq ~ 2,45uS

Tiempo de Adquisición 18F4550

esto aparece en la página 266. Se nota que disminuyó el tiempo y aumentando así la velocidad en el CAD

el retardo por hardware (que así lo quise llamar) ó programmable acquisition time es algo nuevo, es posible configurar el Tacq:

Diferencias de ciclos de Tacq

en la figura 21-4 es como siempre lo habiamos visto, antes de activar el GO_DONE había que introducir el Tacq. Ahora usando la configuración por hardware, tenemos la figura 21-5 donde sucede después de haber seteado al GO_DONE (no algodón, )), haciéndolo automático.

(33)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 33 -luego viene el proceso de hacer la conversión, es decir, tomar el valor analógico de lo que está cargado en el condensador Chold y llevarlo a un número binario.

-en este proceso de conversión hay otros parámetros, uno de ellos es el reloj de conversión,

esto quiere decir que el módulo CAD, trabaja con un reloj distinto del CPU y que puede depender o no de éste. Eso lo dirá la debida configuración de los bits ADCS2:ADCS0 del registro ADCON2

Cuando digo que puede ser independiente del CPU, es porque puede trabajar con un reloj interno (un oscilador RC) cuya aplicación sería poner a dormir el PIC mientras se está haciendo una conversión, ¿y que utilidad puede tener esto?, bueno al estar

trabajando solo el módulo CAD, se reduce el ruido de conmutación de los otros periféricos y puede aumentar la precisión del valor digital obtenido.

Desventajas: usando el oscilador interno se tarda mas la conversión (en el orden de los mS, que podría sería mucho tiempo para algunos eventos)

cuando inicia la conversión, lo primero que hace es desconectar el condensador Chold de la entrada analógica, y mediante una aproximación sucesiva, se vá guardando bit a bit de los 10 bits que hay, el resultado digital (ver figura 21-4)

esto también tiene su tiempo y es el tiempo (retardo) de conversión analógico digital por bit, llamado Tad. Según la pagina 267 se requiere de un tiempo de 11Tad para realizar una conversión, el Tad mínimo para el CAD del 18F4550 es 700nS(pagina 400) pero haciendo algunos cálculos de acuerdo a la tabla 21-1

Frecuencia Operación Tad

(34)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 34 Secuencia Conversión A/D

Nota: el Tacq sacado por hardware depende de Tad

Bits selección Tacq

posteriormente viene todo lo que se venia aplicando anteriormente, esperar a que GO_DONE =0 ó esperar la interrupción del CAD y tomar el valor que está en la pareja de bytes ADRESH:ADRESL (limpiar la bandera ADIF si es es por interrupción) en general, los pasos para un CAD, serian (Pág. 265):

(35)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 35 pasos requeridos para realizar una conversión

desde luego que todo esto es pura teoría, así que vamos a darle con un ejemplo para nuestro ejemplo (ejemplo4):

-usaremos un reloj de conversión de 64Tosc = Fosc/64 ya que seguiremos usando un clock de 48Mhz y esto es lo que recomienda la tabla 21-1

-usaremos el Tacq por hardware, así que si nuestro Tad= 1.33uS, entonces usando un tacq= 2Tad= 2*1.33uS = 2.66uS

-seleccionaremos el canal AN0, el resto como i/o digital.

-haremos la conversión AD y después indicaremos el resultado en 10 leds.

aunque yo no se para que tanta precisión, si estoy trabajando en C, y no se que como hará eso el compilador.

cálculo preciso + cálculo(teórico)= cálculo preciso + error ( práctico)

cálculo preciso + error ( teórico)= cálculo preciso + error ( práctico) + error ( teórico) 1

2

// usando el CAD en el 18F4550 // 30-Dic-2006

(36)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 36 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 3 3 3 4 3 5 3 6

#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,NOVREGE N,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

} }

(37)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 37 3 7 3 8 3 9 4 0 4 1 4 2 4 3 4 4 4 5 4 6 4 7 4 8 4 9

buscando en el CCS no conseguí alguna constante declarada para los bits ACQTx así que tuve que crearlos y hacer una OR incluyente con las demás constantes dentro de la función setup_adc().

int ADC_ACQT_2TAD=0×1;

para comprobar si esto es correcto, voy a compilar y miraré en la ventana SFR del MPLAB para ver como quedó el registro ADCON2

http://www.youtube.com/watch?v=wI9DlXFLGEI

Pero fue en vano, el CCS no me deja cambiar los bits 3,4,5 de ADCON2, así que me voy por ensamblador, sustituyo la línea setup_adc(ADC_CLOCK_DIV_64 ||

ADC_ACQT_2TAD ); por: 1 2 3 4 #asm movlw 0b10001110 ;justificacion_derecha,2Tad,Fosc/64 movwf 0xFC0 ; direccion de ADCON2

(38)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 38 ahora si aceptó el cambio, entonces se hace la simulación nuevamente, pero antes

introduzco el cambio de ADRESx mediante estímulos, en una de las fuentes consultadas ( ver arriba) el amigo Maunix explica como hacerlo, ahora si arrancamos con el

MPLAB-SIM

http://www.youtube.com/watch?v=Fzf2_wvbiQU

el estímulo no está funcionando, de verdad que pasé un rato creyendo que estaba mal configurado el Register Injection, pero después me di cuenta que faltaba la instrucción setup_adc(), si así como lo leen, ¿como se hace entonces si lo había quitado?, bueno, lo coloque de nuevo y le añadí el pedacito en assembler para que aceptara el cambio en ADCON2 1 2 3 4 5

setup_adc(ADC_CLOCK_DIV_64 );//|| ADC_ACQT_2TAD ); #asm

movlw 0b10001110 ;justificacion_derecha,2Tad,Fosc/64 iorwf 0xFC0,1 ; direccion de ADCON2

#endasm

claro, que cambié el movwf por iorwf, para que me aceptara los nuevos bits sin alterar el estado anterior de ADCON2,

también es bueno decir que por aquí se puede cambiar la justificación, hay otra cosa interesante, en CCS hay una directiva #DEVICE ADC=xx , sería bueno analizar que pasa si cambio ADC=10 por ADC=16, ¿esto hará la justificación hacia la izquierda?, sería otro estudio.

vamos a simular de nuevo,

nota: el archivito llamado adresito.txt tiene estas líneas guardadas:

1A0 2AA 3FF

(39)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 39 esas líneas corresponden al supuesto valor de ADRESH:ADRESL y serán cargadas por el estímulo en un bucle

http://www.youtube.com/watch?v=H4ozbfY1PGY

me dio curiosidad y ví el listado en ensamblador, metí un breakpoint en el momento de escoger el canal y hasta que se cargan la pareja ADRESH:ADRESL

Tiempo muestra medido en MPLAB-SIM

calculando el tiempo teórico: Tacq= 2*Tad + 11*Tad= 2*(64/48Mhz)

+11*(64/48Mhz)=17.33uS bastante aproximado con los 18.33 uS que dá el MPLAB-SIM.

el siguiente paso es programar el PIC y probarlo en el protoboard, hay un detallito que se está olvidando,la resistencia Rs, que es la que vá a la entrada AN0, según los cálculos teóricos máximo de 2.5k, yo usaré un potenciómetro que le medí 2k que es lo que tengo a mano, ¿habrá algún cambio? eso habrá que verlo en el protoboard.

ja ja con tanta cablamenta, me imagino el ruido que debe haber allí.

Lo importante es que hicimos arrancar el módulo CAD y que hicieras las respectivas conversiones.

hice unas mediciones con el tester, y me di cuenta que al insertar la punta en AN0 parece que introduce variaciones, así que conecté un TL082 como seguidor de voltaje, para poder medir sin interferencias. peeeero me topé con un problemita, hay un detalle

(40)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 40 cuando intentas medir niveles cercano a 0 volts usando el TL082. Buscando por ahí

conseguí una página donde explican el fenómeno (llamado latch-up), a mi me sucede esto porque alimento al operacional con +Vcc=+5 y -Vcc=0.

Solución: alimenté al operacional con +Vcc=+12 y -Vcc= -12 y ¡listo!. volví hacer mediciones, esta vez arreglando mejor las conexiones: - una especie de apantallamiento a la entrada AN0

- acerqué mas el C=100nF de alimentación del PIC. y varios resultados obtenidos:

datos obtenidos tabulados

según estos datos obtenidos, la precisión es mas o menos… uhmmm, será por el montaje en protoboard, si ya se que todo es relativo… voy hacer otra prueba, voy a aumentar el Tacq al máximo permitido por ADCON2, esto es 20Tad = 20 * 1.33uS = 26.6 uS bastante tiempo de sobra que sumándole 11Tad = 11* 1.33uS =14.63uS daría una conversión aproximada de 41.23uS

para Tacq=20Tad -> ADCON2<-0b10111110, entonces el código cambiará: 1 2 3 4 #asm movlw 0b10111110 ;justificacion_derecha,20Tad,Fosc/64 iorwf 0xFC0,1 ; direccion de ADCON2

#endasm

repitiendo todo el procedimiento anterior, compilando y simulando y después grabar el micro, llegamos a revisar el montaje en el protoboard:

(41)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 41 Segunda recopilación datos

Conclusión:

Bueno señores, esos resultados como que mejoraron un poco, uhmmmm… la verdad es que nunca he podido obtener valores calculados en la práctica, quizás un montaje mejor elaborado en baquelita y bien filtrado pueda aumentar la precisión.

espero que les pueda instruir en algo.

Módulo CAD o ADC (Parte 2)

Continuando con el CAD, seguí haciendo varias mediciones con el código realizado anteriormente y descubrí nuevos detalles

- según la página 602 de 39500a.pdf

Colocar condensador 100nF en AN0

allí recomiendan colocar un condensador de 100nF a la entrada de AN0 si la señal no cambia tan rapidamente, a mi me sirve pues estoy variando con un destornillador y eso es mas lento que inyectar una señal de baja frecuencia.

-para la alimentación en AN0, usé un 7805 aparte, para separar los voltajes.

-noté una variación de Vdd, no se porque la alimentación del 7805 cambia cuando varío el potenciómetro en AN0, así que en las mediciones tomé en cuenta ese valor de Vdd que es mi Vref, en cada dato que sacaban los leds.

(42)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 42 nuevos datos

valor práctico vs calculado

según la gráfica se nota una mejoría en la precisión, pero yo sigo obstinado a conseguir mas precisión, después de un buen rato debugeando con el MPLAB SIM, observé la pestaña MPLAB SIM que está adentro de la ventana OUTPUT y me salía este mensaje:

1 2

ADC-W0001: Tad time is less than 1.60us

ADC-W0010: A Minimum of 2 TADs are required before another conversion should be started.

-el primer mensaje es cierto porque el ADCON2 está para FOSC/64 = 1.33uS, pero recuerden que me estoy guiando por las recomendaciones de la datasheet.

-con el segundo mensaje, el MPLAB SIM me dió un regaño, muy cierto me salté esos tiempos:

(43)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 43 Tiempo mínimo Tad

esto sale en la página 265 3Tad = 3*(64/48MHZ)=3.99uS

entonces modifiqué el programa, metiendo un delay_us(5) y grabé el pic, y volví a tomar datos, ¡pero un momento! en la página 268 dice que pueden ser 2Tad:

Tiempo mínimo 2Tad

yo con mi manía lo saqué para ambos valores(2Tad y 3Tad) y aquí estan los resultados: para tiempo entre muestras >= 2Tad:

(44)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 44 Muestra 3uS práctico vs calculado

para tiempo entre muestras >= 3Tad:

(45)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 45 Muestra 5uS práctico vs calculado

¡¡¡Ahhh!!! se dan cuenta señoras y señores, los valores son cercanos a lo calculado, o sea, que ese tiempito entre conversión y conversión es MUUY IMPORTANTE y yo voy a seguir sacandole punta a este ejemplo (que ahora se llama ejemplo4_parte2). nota:

-esto ya se sale de la iniciación con el 18F4550, formaría parte de la configuración básica de un módulo CAD.

-observen en los resultados que la variación de Vdd fué muy poca !?!?

voy a modificarlo como quería en un principio, tratar que el CAD se tarde lo mínimo en hacer una conversión, es decir, con Tacq=2Tad y un 2Tad entre muestras, para ellos cambiamos por estas lineas:

1 2 3 4 5 6 #asm

movlw 0b10001110 //justificacion_derecha,2Tad,Fosc/64 ...

...

delay_us(3); // para pasar >= 2Tad a la sig CAD

...

y una vez mas, empiezo a tabular datos, jeje

(46)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 46 datos obtenidos Tacq y 2Tad para 3uS

de estos ultimos resultados tengo varias conclusiones:

-que si es posible hacer un conversión con aceptable precisión, usando el mínimo tiempo de la Adquisición por hardware.

-que el Vdd variaba (y esto es una sospecha) debido a incremento de corriente de parte de los leds, noten en los datos que a medida que mas led´s se encendian, Vdd iba disminuyendo, esto no tiene que ver con la configuración del CAD.

-que hay que estar pendiente con los minimos detalles que dicen en la datasheet, tal es el caso del mínimo Tad entre muestras.

(47)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 47

Primera Práctica: PiCUSB

Ahora vamos a hablar del módulo USB, Esto si es nuevo para mi y como la “fiebre” es tan grande… me salté todas las barreras y me fuí derechito con el ejemplo del amigo Jaime J1M, el del encender un par de led´s. Así que voy a describir esta pequeña aventura, como para la bajar la “fiebre” un poco.

bien, el primer paso, conseguir el código del PicUSB en la página www.hobbypic.com buscar el archivo picusb.zip (allí está todo, circuito eléctrico, código fuente, etc.). - allí hay un pdf donde aparece el circuito eléctrico, para el 18F2550, bueno yo estoy usando el 18F4550 y sirve también. solo hay que cambiar el encabezado por #include

<18F4550.h>

- usar un software para enviar los comandos que activaran los led´s, yo aún no tengo el visual C#, pero ya que el amigo Diego RedPic realizó uno que es compatible con el mismo código, lo usé y se llama PicUSBDelphi.exe (forma parte del archivo

PicUSBDelphi.zip que se baja desde la página picmania.garcia-cuervo.net/usb_0_desencadenado.php).

Programa PiCUSB de RedMania

este archivo se encuentra en PicUSBDelphi.zip, y funciona con la librería mpusbapi.dll que debe estar en el mismo directorio.

- seguido conectar todo. Hay que revisar los contactos del conector USB. Yo usé el plug estándar tipo A (visto de la parte de abajo)

(48)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 48 Conector USB tipo A

cuyos pines van así: (tomado de especificaciones USB2.0 capítulo 6 página 99)

Disposición pines conector USB tipo A donde:

1=Vbus 2=D- 3=D+ 4=Gnd

ese plug lo conecté a una extensión, por si acaso medí la tensión de Bus=5.1 volts. - ahora si viene la parte de conectar y enchufar al puerto de la PC, y….

el windows me detectó un nuevo dispositivo USB, hay que elegir la carpeta donde están los controladores que están en el mismo picusb.zip, son 4 archivitos:

(49)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 49 picusb.cat

picusb.inf picusbci.dll wdmstub.sys

después el windows hace todo lo que tiene que hacer (configurar dispositivo, etc.)

Propiedades del Dispositivo USB

y listo, se encendió el circuito en el protoboard. parece que la misma alimentación del puerto alimenta al circuito

-ahora falta cargar el programa en la PC y hacer las respectivas pruebas: http://www.youtube.com/watch?v=XZN4L9kimr0

como podrán ver en este ejemplo, aquí no se habla de programación ni de

funcionamiento, simplemente me lancé a probar ese código y siento especial alegría porque ¡ya pude hacer mi primera transmisión de datos a un PIC vía USB! Gracias a J1M y RedPic.

(50)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 50

Usando el Módulo USB CDC (Parte 1)

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 características 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 leída, pues 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 envié 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

Invocando el control mscomm.ocx en vb

(51)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 51 Programa ejemplo CDC-VB

como verán hay 2 botones cada uno para enviar la orden al PIC y después éste, nos envié la respectiva cadena, dicha orden será un byte ó un carácter, posteriormente esa cadena se guardará en la caja de texto.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44

' 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

(52)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 52 45 46 47 48 49 50 51

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é fue 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: 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 0 2 1 2 /* 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?

(53)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 53 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 3 3

//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

http://www.youtube.com/watch?v=uCn2wOmnv2M

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.

(54)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 54

Usando el Módulo USB CDC (Parte 2)

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

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 ejemplo anterior 1 2 3 4 5 6 7 8 9 1 0 1 1 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 /* 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

(55)

w w w . u n p o c o d e l e c t r o n i c a . n e t a u . n e t Página 55 2 0 2 1 2 2 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 0 3 1 3 2 3 3 3 4 3 5 3 6 3 7 3 8 3 9 4 0 4 1 4 2 4 3 4 4 4 5 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:

- no hay conexión

Referencias

Documento similar

Sin embargo, mientras que la primera de tales actividades tiene lugar necesariamente siempre que exista una petición de referéndum, las otras dos no se llevan a cabo en todo caso,

y para evitarla cede una parte de su asignación mensual con destino á rep¡a- rar y continuar esta obra magestuosa, logrando con gran satisfacción suya

BUBER'NEUaiAMN, Margarete ¡ Von Potsáam ndch Moskau. SMíionen eines Irftveges. Stuttgart, 1957; Deutsche Verlags-Anstalt, 480 págs... DAHM: Deutsches Reckt. Die geschichüichen

Pero cuando vio a Mar sacar el fuego de bajo su ala, voló de vuelta a su tribu a contarles lo que había visto.... Justo antes de que el sol saliera, Tatkanna se despertó y comenzó

Observen que tenía (una.. 6 posesión, ya había empezado mal y no lo sabía), pero no importaba, pues solo quería tener otro cuerpo cerca, el de un varón y que no fuera familiar..

Volviendo a la jurisprudencia del Tribunal de Justicia, conviene recor- dar que, con el tiempo, este órgano se vio en la necesidad de determinar si los actos de los Estados

Un examen detenido del artículo 149, i, que enumera las compe- tencias exclusivas del Estado, nos enseña la diversa terminología que se emplea para referirse a aquellos supuestos en

Se ha diseñado y aplicado una encuesta en la que se incluyeron preguntas que permitiesen verificar las hipótesis. Se denomina “Virtualización de las actividades