elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Entrar al Canal Oficial Telegram de elhacker.net


  Mostrar Temas
Páginas: 1 2 [3] 4
21  Programación / .NET (C#, VB.NET, ASP) / Ayuda!!! Mono y Java... [monodevelop] en: 20 Julio 2006, 19:16 pm

Hola a todos...

Pues estoy empezando con esto de .NET en linux y todo este rollo... y llevando en paralelo el aprendizaje de Java y C#, pero me llevo la sorpresa de que mono tiene compiladores para C#, y runtimes para Java... pero no un compilador para Java...

Cuando intento compilar un fichero de Java, con monodevelop, me sale lo siguiente: The Java addins has not been properly configured:


Como soluciono esto???[/color]
22  Informática / Electrónica / Por fin!!! Grabando nuestros programas en ASM y C en los PIC's en: 10 Mayo 2006, 03:51 am
Bueno, ya he posteado sobre los microcontroladores y sobre los circuitos que se pueden montar y eso; ahora que ya sabemos qué es un microcontrolador (exactamente los PIC 16C84 y 16F84), cómo probar programas simples en ASM y C, y tenemos los esquemas de los mismos para implementarlos en circuitos. Es hora de probar una tool que nos permitirá grabar los programas en nuestros PIC's y probar nuestros circuitos...

La tool que vamos a manejar es el ICProg (--descarga directa--) y las pruebas las he realizado con el grabador (o quemador) Te21se:

La puedes comprar en AP-ELEctronics ;)


En esta ocación vamos a configurar nuestra tool para que quede al pelo xD; lo primero descargarla, ahora copiamos la carpeta en algún lugar donde te quede cómodo abrir (c:\ por ejemplo). Ejecutamos el icprog.exe y posiblemente nos saldrá algo como esto (si es nuestra primera vez... eso se escuchó muy virginal xD):


Le damos ok, y tendremos lo siguiente (en algunos pc's da unos errores extraños, basta con cerrar la aplicación y volverla a lanzar):


Lo primero que haremos será configurar el idioma de la tool en "Español". Vamos al menu Settings->Options y picamos la pestaña Language.


Le damos ok, y ahora vamos al menú Ajustes->Tipo Hardware con lo que nos saldrá algo como esto:


MUY IMPORTANTE: Deberemos indicar correctamente el puerto COM al que vamos a conectar el cable. Ten en cuenta que si indicamos COM1 en ICPROG y conectamos el cable al COM2 no funcionará. En algunos ordenadores con módem interno, puede darse el caso que esté ocupando el COM1, y los puertos del ordenador sean el COM2 y el COM3.

En caso de errores en la grabación, se puede ir probando, bajando el valor de Retardo I/O. Aconsejo entre 4 - 7.

Ahora vamos a hacer una configuración general de nuestra aplicación; vamos a Ajustes->Opciones y colocamos todo como lo veremos a continuación:










Le damos OK y ya tenemos nuestro Icprog configurado ;)

Pasos a seguir para quemar nuestros PIC's

Voy a indicar algunas cosas que han de ser obvias para muchos de uds. que sí saben de electrónica... necesitas tener una tarjeta Piccard-1 (PIC16F84) o Piccard-2 (PIC16C84), junto con sus correspondientes circuitos integrados, un programador, el programa ICPROG y:

  • En el caso de PICCARD-1, dos archivos: uno .HEX para programar la PIC y el otro .BIN (en ocasiones también .HEX) para programar la EEPROM
  • En  el caso de PICCARD-2, un solo archivo para la PIC.
Nota: si no entiendes que es eso de la EEPROM, puedes hecharle un vistazo a este post ;)

Lo primero es insertar nuestro PIC en el zócalo adecuado del Te21se y en su posición correspondiente. Observa los chips de cerca, tienen una pequeña muesca en forma de media luna o de punto, que debe coincidir con la muesca de la misma forma de los zócalos del grabador, si los inviertes quemarás los put0s PIC's (no saldrá humo como en las películas xD, pero ya no funcionará más ;( ).

Una vez están correctamente insertados, conectamos el cable serie, por un lado al programador y por el otro a un puerto COM libre del ordenador. Ahora ejecutamos el programa ICPROG que ya deberemos tener bien configurado.

Indicamos que vamos a grabar el primero de los dos chips, el PIC16F84, con los siguientes pasos:

Ajustes -> Dispositivo -> Microchip Pic -> Mas -> PIC16F84


Ahora cargaremos el archivo que se va a grabar en el PIC, estos son los pasos:

Archivo -> Abrir Datos -> *.hex, (de los dos archivos hay que abrir el que tiene extensión .HEX puesto que el .BIN es para grabar el otro chip).

Esto se puede parecer a un editor hexadecimal, herramienta común entre los crackers. Una vez abierto, deberemos colocar las opciones Oscilador en XT y desactivar las opciones Bits configuración.


Listo!!!! Ahora solo no queda grabar la información del HEX en nuestros PIC's: Menu "Comando" -> "Programar todo":



Solución de Problemas

Este pequeño articulo de Solución de problemas frecuentes lo he pillado en un libro de Ap-Electronics. Dice así:

Si usando el programador no lee, no programa o genera errores de verificación (error de verificación en 0000H), se puede solucionar el problema en la mayoría de las ocasiones revisando los siguientes puntos:

  • El programador debe utilizarse desde un ordenador con Windows ME - 98 - 95. La familia Windows 2000 no soporta ICPROG.
  • Probar con un sólo elemento a programar o leer, en el zócalo correspondiente, es decir un PIC ó una EEPROM.
  • Probar con un sólo elemento a programar o leer, en el zócalo correspondiente, es decir un PIC ó una EEPROM.
  • Comprobar que la PIC y la EEPROM son los correctos, y han sido insertados con su muesca coincidiendo con la muesca del zócalo de programación, y que a su vez coincide con el PIN 1 en la serigrafía de la placa, marcado con un 1.
  • Comprobar que la PIC o la EEPROM se encuentra completamente insertado en su zócalo.
  • Comprobar que ha sido seleccionado en el menú el elemento que está programando en ese momento, es decir si se procede a programar un PIC16F876, el elemento seleccionado deberá ser el PIC16F876. En los anteriores pasos hemos indicado como seleccionarlo.
  • Comprobar que el menú Ajustes/Tipo Hardware (F3) se encuentra bien configurado.
  • La PIC y la EEPROM necesitan ser programados despacio, si su puerto está configurado a mucha velocidad esto puede originar fallos en la programación y verificación del mismo. Para reducir la velocidad de su puerto siga la siguiente secuencia de comandos con el ratón:

        Mi PC - Panel de control - Sistema - Administrador de dispositivos - Puertos COM y LPT - Puertos de comunicación COM1 ó COM2 - Configuración del puerto.

        El puerto puerto debe estar configurado de la siguiente manera:

            Bits por segundo: 9600 (ó menos en caso de errores)
            Bits de datos: 8 Paridad:
            Ninguna Bits de paridad: 1
            Control de flujo: Xon/Xoff

  • Al programar la PIC o la EEPROM, comprobar que el programa cargado y que se pretende programar en el integrado, tiene la extensión correcta, siendo generalmente *.HEX o *.BIN. Comprobar que el programa a programar en la PIC es el correcto y es el correspondiente al mismo, si intenta programar un programa de mayor tamaño a la capacidad del PIC, se producirá un mensaje de error.
  • Probar a utilizar en otro ordenador, ya que los programadores que se alimentan del puerto serie, son muy sensibles a la tensión que reciben desde el mismo y no todos los ordenadores son capaces de mantener la misma tensión durante el proceso de grabación.
Saludos!!!
23  Informática / Electrónica / Programación de Microcontroladores PIC16X84 [Diagramas de montaje + Programas] en: 2 Mayo 2006, 17:35 pm
Diagramas y SeudoEsquemas para implementar los Microcontroladores PIC16X84 en circuitos reales o protoboards + Programas en ASM y C

¡¡¡Put0 título tan largo que me he inventado xD!!! Nada, decir que obviamente los programas no los he inventado yo, sino que son la recopilación de los "ejemplos práticos" más usados. Los he sacado de unos cuantos libros cuyo nombre no me sé (en realidad son unas fotocopias que encontré por casualidad). Y aclarar que los dibujos los hice yo en Visio, y que talvez tengan uno que otro fallo, la verdad es que me costó un huevo hacer esos put0s dibujos; en fín, si encontrais algún fallo me lo comunicas por privado. Sino conoceis como es este rollo de los Microcontroladores PIC, podeis hecharle un vistazo a este post: Introducción a microcontroladores PIC [simulando nuestro programas en ASM y C] (no te demoras sino 20 o 30 minutillos leyéndolo).

Primer Ejemplo: Explorando interruptores y encendiendo luces.

SeudoEsquema de Montaje

Descripción: Lee el número binario introducido mediante 3 interruptores conectados a la puerta A, luego suma 2 unidades a ese valor y visualiza el resultado mediante 4 diodos led conectados a la puerta B.

Programa en Assembler:

Código:
;----------------------------------------------------------------------------
    LIST    P=16C84         ;Comando que indica el PIC usado
    RADIX   HEX             ;Los valores se representar n en hexadecimal
;----------------------------------------------------------------------------
    PUERTAA EQU     0X05    ;La etiqueta "PUERTAA" queda identificada con
                            ;la dirección 0x05, que si corresponde con el
                            ;banco 0 es el valor de PUERTAA y si es del
                            ;banco 1 con el de TRISA.
    PUERTAB EQU     0X06    ;Equivalencia de la etiqueta PUERTAB
    ESTADO  EQU     0X03    ;Estado corresponde con el valor 0x03.
    W       EQU     0       ;Identifica W con el valor 0.
;----------------------------------------------------------------------------
    ORG     0               ;Comando que indica al Ensamblador la
                            ;dirección de la memeoria donde se
                            ;situar  la instrución siguiente
;----------------------------------------------------------------------------
    bsf     ESTADO,5        ;Pone a 1 el bit 5 de ESTADO para direccionar
                            ;la p gina 1 de la memoria de datos.
    movlw   0xff            ;W <-- FF(Hex)
    movwf   PUERTAA         ;W --> TRISA
    movlw   0x00            ;W <-- 0
    movwf   PUERTAB         ;W --> TRISB (Las líneas de PB salidas)
    bcf     ESTADO,5        ;Pone a 0 el bit 5 de ESTADO pasando a
                            ;acceder al banco 0.
   
    inicio movf PUERTAA,W   ;W <-- PUERTAA. Se introduce el valor binario
                            ;de los interruptores.
    addlw   2               ;W <-- W + 2
    movwf   PUERTAB         ;W --> PUERTAB. El valor de W sale por las
                            ;líneas de PB a los led.
    goto    inicio          ;Salta a la instrucción precedida por la
                            ;etiqueta de inicio.
    END


Programa en C:

Código:
#INCLUDE <16C84.H>
void main(void)
{
    int valor;              /* Valor temporal */
    int * p_puertaa= 0x05;  /* Puntero a PuertaA */
    int * p_puertab= 0x06;  /* Puntero a PuertaB */
   
    SET_TRIS_A (0xff);      /* 0xff --> TRISA */
    SET_TRIS_B (0x00);      /* 0x00 --> TRISB */
    do
    {
        valor = * p_puertaa;/* PuertaA --> valor  */
        valor += 2;         /* se incrementa valor en 2 */
        *p_puertab = valor; /* valor --> puertaB */
    }while(true);          /* Bucle infinito */
}


Segundo Ejemplo: Más interruptores y diodos led.

Esquema de Montaje

Descripción: Muestra por cinco diodos led en la puerta B la entrada que proporcionan cinco interruptores en la puerta A.

Programa en Assembler:

Código:
    LIST    p=16c84    ; Se usa el PIC16C84
    RADIX   hex        ; Se emplea el sistema de numeración hexadecimal
   
; ZONA DE ETIQUETAS-----------------------------------------------------------------------
    W    EQU    0      ; Cuando el destino es W, d = 0
    F    EQU    1      ; Cuando el destino es el registro f, d = 1
    PUERTAA EQU 0x05   ; La Puerta A (datos) ocupa la dirección 5 del
                       ; banco 0 y el registro de configuración la
                       ; dirección 5 del banco 1
    PUERTAB EQU 0x06   ; La misma etiqueta para el registro de datos y el
                       ; de configuración de la Puerta B
    ESTADO  EQU 0x03   ; El registro Estado ocupa dirección 3 de los dos bancos

; COMIENZO DEL PROGRAMA -----------------------------------------------------------------

    ORG    0           ; El programa comienza en la dirección 0 (Vector Reset)
    goto   inicio      ; Se salta a la etiqueta “inicio”
    ORG 5              ; Se asigna la dirección 5 a la siguiente instrucción
   
    inicio bsf ESTADO,5 ; Pone a 1 el bit 5 de Estado. Acceso al banco 1.
    clrf    PUERTAB     ; Se configuran como salidas las líneas de la Puerta B
    movlw   0xff        ; El registro W se carga con unos
    movwf   PUERTAA     ; Se configuran como entradas las líneas de la Puerta A
    bcf     ESTADO,5    ; Pone a 0 el bit 5 de Estado. Acceso al banco 0.
    bucle movf PUERTAA,W; Carga el registro de datos de Puerta A en W
    comf    PUERTAA,W   ; Complementa a 1 la entrada y la deposita en W
    movwf   PUERTAB     ; El contenido de W se deposita en el registro de datos de
                        ; la Puerta B
    goto    bucle       ; Se crea un bucle cerrado e infinito
   
    END                 ; Fin del programa

Programa en C:

Código:
#include <16c84.h>
#byte   puertaa = 05   /* Posición de la puerta A */
#byte   puertab = 06      /* Posición de la puerta B */
void main( void )
{
    int temp;
    set_tris_a( 0xFF );     /* Puerta A configurada para entrada */
    set_tris_b( 0x00 );     /* Puerta B configurada para salida  */
    do
    {
        /* La variable temporal es necesaria porque    */
        temp = ~puertaa;    /* la complementación se traduce en dos pasos: */
        puertab = temp;     /* a) Copia de puertaa en temp                 */
    }
    /* b) Complementación de temp                  */
    /* De no hacerlo así los LED parpadearían      */
    while( TRUE );/* Repetir ininterrumpidamente       */
}


Tercer Ejemplo: Contando y visualizando.

Esquema de Montaje

Descripción: Hace un conteo desde 0 hasta 0x5f y muestra en las patitas RB.

Programa en Assembler:

Código:
;----------------------------------------------------------------------------
    LIST    P=16C84
    RADIX   HEX
;----------------------------------------------------------------------------

    W       EQU     0x00    ; Comienzo del campo de etiquetas.
    F       EQU     0x01
    PUERTAB EQU     0x06
    ESTADO  EQU     0x03
    CONTA   EQU     0x0C
   
;----------------------------------------------------------------------------

    ORG     0               ; El programa comienza en la dirección 0 y
    goto    inicio          ; salta a la dirección 5 para sobrepasar
    ORG     5               ; el vector de interrupción.

;----------------------------------------------------------------------------

    inicio  bsf     ESTADO,5    ; Seleciona el banco 1
        movlw   0x00            ; Se configura PuertaB como salida
        movwf   PUERTAB
        bcf     ESTADO,5        ; Selección del banco 0
       
;----------------------------------------------------------------------------

    clrf    CONTA           ; CONTA = 0
    bucle1  incf  CONTA,F   ; CONTA + 1 --> CONTA
        movf    CONTA,W         ; CONTA se carga en W
        movwf   PUERTAB         ; W se carga en el registro de datos PB
        movlw   0x5f            ; W <-- 0x5f
        subwf   CONTA,W         ; CONTA - W --> W
        btfss   ESTADO,2        ; Explora Z y si vale 1 se produce "brinco"
    goto    bucle1          ; Si Z = 0 se vuelve a bucle1
     
    bucle2  goto    bucle2  ; si Z = 1 se produce un bucle infinito
    end

Programa en C:

Código:
#include <16c84.h>			/* Tipo de PIC a usar */
#byte puertab=0x06
#byte conta=0x0C
void main(void)
{
    set_tris_b(0x00);    /* Configura la PB como salida */
    for (conta=0;conta<=0x5f;++conta)    /* Bucle que incrementa CONTA de 0 */
        puertab=conta;                   /* a 0x5f */
}


Cuarto Ejemplo: Controlando el tiempo.

SeudoEsquema de Montaje

Descripción: Programa que ilustra cómo realizar una temporización sin emplear interrupciones.

Programa en Assembler:

Código:
    LIST     P=16C84
    RADIX    HEX
; ------------------------------------------------------------------------

    PUERTAA  EQU  0x06
    OPTION   EQU  0x01
    ESTADO   EQU  0x03
    TMR      EQU  0x01
   
; ------------------------------------------------------------------------
   
    ORG   0    ; Inicio del programa en
               ; dirección 0
               
; ------------------------------------------------------------------------

    bsf    ESTADO,5     ; Banco 1
    movlw  b 1101 0110  ; Valor a cargar en
                        ; OPTION
    movwf  OPTION
    movlw  0x00
    movwf  PUERTAB      ; La Puerta B salida
    bcf    ESTADO,5     ; Banco 0
    clrf   PUERTAB      ; Las líneas de salida
                        ; de PB a 0
                       
    parpa bsf PUERTAB,7 ; Enciende el led RB7 = 1
    call  retardo       ; Llamada a subrutina de
                        ; RETARDO
    bcf   PUERTAB,7     ; Apaga el led, RB7 = 0
    call  retardo
    goto  parpa
   
    retardo clrf TMR0   ; TMR0 = 0 y empieza su
                        ; incremento
                       
    explora btfss TMR0,4; TMR0<4> = 1?
    goto   explora      ; No ha llegado TMR0 a 16d
    return              ; Ha llegado TMR0 al
                        ; valor 16d  y retorna
                        ; al programa principal
                       
    END

Programa en C:

Código:
#include <16C84.H>
#use delay( clock = 1000000 )  /* Especifica reloj de 1 MHz */
#byte puertab = 06              /* Dirección de la puerta B  */
void main( void )
{
    set_tris_b( 0x00 );
    puertab = 0;
    do
    {
        delay_us( 8700 );    /* Crea un bucle de espera de 8700 microsegundos */
        bit_set(puertab,7);  /* Enciende el LED */
        delay_us(8700);      /* Espera */
        bit_clear(puertab,7);/* Apaga el LED */
    }while(true);            /* Repetir siempre */
}


Quinto Ejemplo: Manejando Interrupciones.

SeudoEsquema de Montaje

Descripción: Refleja el estado de dos interruptores situados en RA0 y RA1 en RB0 y RB1 mientras hace parpadear un diodo en la línea RB7.

Programa en Assembler:

Código:
;----------------------------------------------------------------------------
   
    LIST    P=16C84
    RADIX   HEX
   
;----------------------------------------------------------------------------

    W    EQU    0
    F    EQU    1
    TMR_OPT EQU 0x01   ; TMRO en banco 0 OPTION en banco 1
    ESTADO EQU  0x03
    PUERTAA EQU 0x05   ; PA en banco 0 TRISA en banco1
    PUERTAB EQU 0x06   ; PB en banco 0 TRISB en banco1
    INTCON EQU  0x0B   ;
    CONTA  EQU  0x10   ; Contador auxiliar

;----------------------------------------------------------------------------

    ORG    0        ; Vector de Reset
    goto   inicio
   
    ORG    4        ; Vector de Interrupción
    goto   inter    ; Salta a comienzo de rutina de interrupción
    ORG    5
   
    inicio bsf  ESTADO,5        ; Selección del banco 1
    clrf   PUERTAB              ; Configura PUERTA B como salida
   
    movlw   b'00000011'         ; Configura RA0, RA1 como entradas
    movwf   PUERTAA
   
    movlw   b'00000111'
    movwf   TMR_OPT
   
    bcf     ESTADO,5            ; Banco 0
   
    movlw   b'10100000'         ; Se permite interrupción del
    movwf   INTCON              ; TMR0 y la globla (GIE)
   
    movlw   0x10
    movwf   CONTA               ; Se carga CONTA con 16 decimal
   
    movlw   0x0c
    movwf   TMR_OPT             ; Se carga TMR0 con 12 decimal
   
    bucle   btfsc   PUERTAA,0   ; Explora RA0 y brinco si vale 0
        goto    ra0_1           ; salta a RA0_1
        bcf     PUERTAB,0       ; Si RA0 = 0 sa saca por RB0 un 0
        goto    ra1x            ; A explorar RA1
       
        ra0_1 bsf   PUERTAB,0   ; Si RA0 = 1 se saca por RB0 un 1
   
        ra1x  btfsc PUERTAA,1   ; Examina ra1  y brinco si es 0
        goto    ra1_1           ; Salta  si RA1 = 1
        bcf     PUERTAB,1       ; Si RA1 = 0, RB1 = 0
       
        goto    bucle2
        ra1_1   bsf  PUERTAB,1  ; Si RA1 = 1 , RB1 = 1
    bucle2  goto    bucle       ; Bucle indefinido, se sale por la interupción
   
;----------------------------------------------------------------------------

    inter   decfsz  CONTA,1     ; RSI. Decrementa CONTA y brinco si vale 0
    goto    seguir
   
    conta_0 movlw   0x10        ; Si CONTA = 0 se carga
        movwf   CONTA
       
        btfsc   PUERTAB,7       ; Si RB7 = 0, brinco
        goto    rb7_1
        bsf     PUERTAB,7       ; Si RB7 = 0, se invierte
        goto    seguir
       
    rb7_1   bcf     PUERTAB,7   ; Si RB7 = 1 , se invierte
   
    seguir  movlw   b'10100000' ; Se restaura INTCON por desactivar las
        movwf   INTCON          ; interrupciones el procesador
        movlw   0x0c
        movwf   TMR_OPT         ; Se recarga TMR0 con 12
        retfie
       
        end

Programa en C:

Código:
#include <16c84.h>		/* Selección del PIC a usar */
#use delay(clock= 4000000) /* Reloj de 4 MHz */
#BYTE puertab = 6
#define maximo 16 /* Constante: maximo = 16 */
byte conta;
/*--------------------------------------------------------------------------*/
/* SERVICIO DE LA INTERRUPCIóN */
#INT_RTCC /* Interrupción por desvordamiento del timer*/
clock_isr()
{
    short valor;
    short novalor;
    valor = bit_test(puertab,7); /* El bit valor es igual al contenido */
                                    /* de RB7 */
                                   
    novalor = !valor;
    if (--conta==0)
    {
        output_bit (PIN_B7,novalor); /* Voltea RB7 */
        delay_us (5);
        conta = maximo;
    }
}

/* PROGRAMA PRINCIPAL */
main()
{
    short ra0,ra1;
   
    set_tris_b(0x00); /* Se inicializa PB */
    conta=maximo;
    set_rtcc(0); /* Se inicializa el timer a cero */
   
    setup_counters(rtcc_internal,rtcc_div_256);
   
    enable_interrupts(rtcc_zero); /* Se permite int del tmr0 */
   
    enable_interrupts(GLOBAL); /* Se activa GIE */
   
    /* Rutina de control de los leds e interruptores: */
    do
    {
        ra0 =  input(PIN_A0);
        ra1 =  input(PIN_A1);
       
        output_bit (PIN_B0,ra0);
        output_bit (PIN_B1,ra1);
    }
    while(true); /* Bucle infinito */
}


Séptimo Ejemplo: Proyecto para manejar un display de 7 segmentos.

SeudoEsquema de Montaje

Descripción: Programa que visualiza un número del 1 al 7 en un display de siete segmentos en la puerta B dependiendo del valor binario de tres interruptores situados en la puerta A.

Programa en Assembler:

Código:
    LIST    P=16C84
    RADIX HEX
   
    w EQU 0
    f EQU 1
    PCL EQU 02
    PUERTAA EQU   05
    PUERTAB EQU   06
    ESTADO  EQU   03
    VALOR EQU 12 ; Registro auxiliar
   
; RUTINA PRINCIPAL: Lectura de los interruptores y c lculo del valor a visualizar

    ORG   0
    goto  inicio
    ORG   5               ; Para saltar el Vector de
                          ; Interrupción
   
    inicio bsf ESTADO,5   ; Selección del banco 1
        clrw
        movwf  PUERTAB    ; Puerta B salida
        movlw  0xff
        movwf  PUERTAA    ; puerta A entrada
        bcf ESTADO,5      ; Selección banco 0
        explora  movf PUERTAA,w  ; Se cargan los
                                 ; interruptores en W
        movwf VALOR     ; Se usa un registro auxiliar
        comf    VALOR,f   ; Invertir los niveles de interuptores
        clrw
        btfss   VALOR,0   ; Si RA0 = 1, brinca
        goto    bit_1     ; Salta a explorar el bit_1
        addlw   0x01      ; Si RA0 =1, se suma
        bit_1 btfss VALOR,1; Si RA1 = 1, brinca
        goto    bit_2     ; Salta a explorar el bit_2
        addlw   0x02      ; Si RA1 = 1, se suman 2
        bit_2 btfss VALOR,2; Si RA2 = 1, brinca
        goto    visual    ; Salta al módulo del display
        addlw   0x04      ; Si RA2 0 1, se suman 4
        visual  call  display ; Salta al módulo del display
       
; DISPLAY: Rutina de visualización del acumulador en el display de 7 segmentos

    movwf   PUERTAB       ; Al retornar de la subrutina
                          ; el valor de W se saca por la
                          ; Puerta B
    bucle  goto  bucle    ; bucle infinito
   
; TABLA DE CONVERSION---------------------------------------------------------

    display  addwf  PCL,f  ; pcl + W -> W
                           ; El pcl se incrementa con el
                           ; valor de W proporcionando un
                           ; salto
    retlw   0x3F           ; Retorna con el valor del
                           ; código del 0
    retlw   0x06           ; Retorna con el código del 1
    retlw   0x5b           ; Retorna con el código del 2
    retlw   0x4f           ; Retorna con el código del 3
    retlw   0x66           ; Retorna con el código del 4
    retlw   0x6d           ; Retorna con el código del 5
    retlw   0x7d           ; Retorna con el código del 6
    retlw   0x07           ; Retorna con el código del 7
   
    END

Programa en C:

Código:
#include <16C84.H>
#byte puertaa = 05  /* Posición de la puerta A */
#byte puertab = 06  /* Posición de la puerta B */
void main( void )
{
    int temp = 0, tabla[8]={ 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07 };
    int indice = 0;
    set_tris_a( 0xFF );   /* Puerta A configurada para entrada */
    set_tris_b( 0x00 );   /* Puerta B configurada para salida  */
    temp = ~puertaa;      /* Se complementa la entrada de PA   */
    if ( bit_test( temp, 0 ) ) indice += 1;
    if ( bit_test( temp, 1 ) ) indice += 2;
    if ( bit_test( temp, 2 ) ) indice += 4;
    puertab = tabla[indice];
}


Ejemplos básicos de programación de Microcontroladores PIC16X84 sin esquemas ni diagramas; enunciados de los ejemplos:

  • Control de un dispositivo desde dos puntos: Se desea controlar una lámpara, en este caso un diodo LED desde dos interruptores, de forma que cuando los dos interruptores están abiertos el LED está apagado. A partir de esta situación, cada vez que cambie el estado de un interruptor, el estado del LED bascula  (si está apagado se enciende y viceversa)
  • Semáforo programabe: Se simula un semáforo con 3 diodos LED. Se dispone de 2 interruptores que según la combinación que adopten originan una secuencia de encendido de las luces del semáforo.
  • Dado electrónico: Este programa simula el juego del dado. Un dado típico tiene 6 caras, en cada una de las cuales viene dibujado un número del 1 al 6. Cada vez que se presiona un pulsador se produce un número aleatorio entre 1 y 6, el cual se visualiza en un display de 7 segmentos.
  • Temporizador programable: Con 3 microrruptores se selecciona un valor entre el 0 y el 7 (binario), que representa un tiempo en segundos y que ser  visualizado por el display de 7 segmentos. Durante el tiempo que dura la temporización un LED rojo permanece activado, así como un zumbador. Al finalizar se desactivan ambos elementos y el display se pone a 0.
  • Alarma: Se tienen 3 detectores digitales, cada uno de los cuales provocar la activación de un LED, diferente en cada caso. Uno de los detectores ser  un optoacoplador y los otros 2 se simularán mediante 2 microrruptores. El programa consiste en poner en marcha un zumbador cuando la alarma salte por causa de la activación de cualquiera de los detectores. También se enciende el LED correspondiente al detector. La alarma sólo funcionará cuando el microrruptor I1 de conexión esté a nivel alto.
  • Ejemplo tomado de Internet: (Autor: David Tait, david.tait@man.ac.uk) Este programa ilumina una serie de leds en secuencia principio-fin-principio (algo así como las luces del "El Coche Fantástico).
  • Manejo del WatchDog (perro guardián): El objetivo de este programa es mostrar en la práctica el funcionamiento del Watchdog en el PIC 16c84. El programa entra en un bucle infinito del que sale tras cumplirse la temporización asiganada al watchdog, que en este caso ser n 36 ms, es decir 2 veces la temporización nominal.


En un futuro post talvez coloque un pequeño glosario de las instrucciones de Assembler para esta gama de microcontroladores, para los que no entienden mucho los códigos; por lo demás espero que les sea de ayuda ;) Y anexo también el archivo donde tengo los (seudo)diagramas en formato *.vsd (Visio), por si lo necesitan o quisieran modificar algún put0 dibujito de esos.

Saludos!!!
24  Informática / Electrónica / Introducción a microcontroladores PIC [simulando nuestro programas en ASM y C] en: 5 Abril 2006, 00:50 am
EL PRIMER CONTACTO CON EL PIC16X84

De antemano disculpas por cualquier fallo en este escrito, ya que no es hecho por un “electrónico”, sino por un aficionado que pretende ser algún día un programador. Y a todas estas, lo bonito del los microcontroladores no está (para mi) en el hardware sino en la programación.

Los temas a tratar son los siguientes:

    •Introducción al PIC16X84 (Pequeño, pobre, pero resultón)
    •Variantes del PIC16X8X
    •Diferencias entre el PIC16C84 con lo demás modelos PIC16X8X
    •La frecuencia de funcionamiento, el reloj
    •¿Para qué y cómo programar PIC’s?
    •Primer ejemplo… Aprendiendo a Sumar (ASM)
    •Ejecutar nuestro programa (simulando con el Simupic’84)
    • ASM vs. C/C++; Eficiencia vs. Comodidad

Importante: es recomendado que la gente que esté interesada en la parte de electrónica revise todos los puntos... los que solo se interesan en la programación (que es en ASM y C), se pueden saltar a la parte de ¿Para qué y cómo programar PIC’s?

Bueno... he aquí mi granito de arena. Considerando que mucha gente  no conoce o quisiera conocer acerca de los microcontroladores, me veo en la obligación de aportar un poco acerca de, en mi opinión, el microcontrolador más fácil de manejar y programar (la familia PIC16X84, es decir PIC16C84 y PIC16F84).
Mucha gente, me incluyo, cuando está comenzando en este mundillo ve a los microcontroladores y a la programación en ASM como algo raro y de otro mundo... cuando en verdad es algo realmente sencillo. Así que si estás interesado en aprender un poco de “electrónica” o “Programación en ASM” esto te puede ayudar a aclarar muchas dudas.

Menos charla, más acción:

Pequeño, pobre, pero resultón
Este “maravilloso” PIC pertenece a la familia de la gama media y dentro de ella es uno de los más pequeños; solo tiene 18 patitas. Además es el que dispone de menos recursos.

El resto de sus parientes tiene conversores AD y DA, comparadores analógicos, tensión interna de referencia, más líneas de E/S, más capacidad en sus memorias, varios temporizadores y un largo etcétera de dispositivos de los que el PIC16X84 carece.

Es “pobre” de mantenimiento... pero he escogido este PIC, en sus dos versiones C y F, porque cumple con los requisitos esenciales para enseñar a manejar los microcontroladores y para comenzar para diseñar proyectos. Es práctico, es sencillo y es económico, pudiéndolo considerar como el paradigma para su empleo en todos los pequeños proyectos que realizan los aficionados, los estudiantes y los que quieren progresar en sus conocimientos de lo fácil a lo difícil. Además si aprendes a manejar este PIC, migrar hacia los demás es muy sencillo.

La razón exclusiva por la que este PIC es tan “requerido”, es por el tipo de memoria de programa que posee. El PIC16C84 posee una EEPROM de 1K palabras de 14 bits cada una. El PIC16F84 tiene la misma capacidad de memoria de instrucciones pero de tipo Flash. Ambos poseen una capacidad de 64 bytes EEPROM como memoria de datos auxiliar y opcional.

La memoria EEPROM y la Flash son eléctricamente grabables y borrables, lo que permite escribir y borrar el programa bajo prueba manteniendo el microcontrolador bajo el mismo dispositivo grabar y borrar. Esta característica supone una gran ventaja con la mayoría de los microcontroladores, que tienen como memoria de programa reescribible una tipo EPROM. Se graban eléctricamente, pero para borrarlas hay que exponerlas cierto tiempo a rayos ultravioleta, lo que implica tener que sacar el chip del zócalo para poderlo borrar.

Microchip ha introducido la memoria Flash porque tiene mayores posibilidades de aumentar su capacidad con relación a la EEPROM. Pero sin embargo la EEPROM soporta 1.000.000 ciclos de escritura/borrado frente a los 1.000 de la Flash.

Otra de las grandes ventajas del PIC16X84 (en cuanto a escritura, borrado y reescritura) es su sistema de grabación de datos, que se realiza en serie. Para escribir un programa en la memoria se manda la información en serie usando solo dos patitas: la RB6 para la señal de reloj y la RB7 para los bits de datos de serie. Bueno, no os asustéis con eso de los RB6 y RB7 que más adelante os lo explico.

A continuación la “Tarjeta de presentación de los PIC16X84” con sus datos personales más significativos:

Cita de: Ficha técnica de los PIC16X84
Memoria de programa: 1Kx14, EEPROM (PIC16C84) y Flash (PIC16F84)
Memoria de datos RAM: 36 bytes (PIC16C84) y 68 bytes (PIC16F84)
Memoria de datos EEPROM: 64 bytes para todos lo modelos
Pila (stack): De 8 Niveles
Interrupciones: 4 tipos diferentes
Encapsulado: Plástico DIP de 18 patitas
Frecuencia de trabajo: 10MHz máxima
Temporizadores: Sólo uno, el TMR0. También tienen “Perro guardián (WDT)”
Líneas de E/S Digitales: 13 (5 Puerta A y 8 Puesta B)
Corriente máxima absorbida: 80mA Puerta A y 150mA Puerta B
Corriente máxima suministrada: 50mA Puerta A y 100mA Puerta B
Corriente máxima absorbida por línea: 25mA
Corriente máxima suministrada por línea: 20mA
Voltaje de alimentación (VDD): De 2 a 6 V DC
Voltaje de grabación (VPP): De 12 a 14 V DC


Variantes del PIC16X8X
Se comercializan varios chips correspondientes a la familia de los PIC16X8X, que atienden diversas características.

    1. Frecuencia máxima de funcionamiento
    2. Tipo de oscilador externo usado para generar la frecuencia de reloj.
    3. Margen de voltaje de alimentación[/list]

    Los modelos que tienen de intermedio la referencia C, F o CR admiten el rango de alimentación de voltaje estándar, que es el que oscila de 4 a 4,5 V DC como mínimo, hasta 5,5 a 6 V DC como máximo. Los modelos con las letras LC, LF o LCR intermedias admiten el rango de voltaje “extendido”, que abarca desde los 2 V hasta los 6 V DC.

    La buena aceptación del PIC16C84 ha animado al fabricante Microchip a comercializar nuevas versiones. Ha diseñado cuatro nuevos modelos:

      •PIC16F84
      •PIC16CR84
      •PIC16F83
      •PIC16CR83

    Dos de ellos intercalan la letra F indicando así que la memoria EEPROM se ha sustituido por otra de tipo Flash. Los otros modelos la sustituyen por memoria ROM con máscara, pero todos ellos mantienen los 64 bytes de EEPROM para datos.


    Diferencias entre el PIC16C84 con lo demás modelos PIC16X8X

      1. La memoria de programa es de tipo Flash en los PIC16F8X y de tipo ROM en los PIC16CR8X
      2. El PIC16F84 y el PIC16CR84 tienen mayor capacidad de la RAM de datos. Disponen de 68 bytes en lugar de los 36 del PIC16C84.
      3. Se ha invertido la polaridad del bit de control PWRTE, que activa y desactiva un temporizador encargado de retrasar el funcionamiento del PIC al aplicarle la alimentación.
      4. Se ha incorporado un filtro a la entrada de la patita MCLR#, por lo que se requiere un pulso de mayor duración para generar el Reset.
      5. Se han mejorado muchas especificaciones eléctricas en los modelos F y CR.[/list]


      El aspecto externo
      Este PIC está desarrollado con tecnología CMOS de altas prestaciones y encapsulado en plástico con 18 patitas. Ok, ahora comento brevemente la misión de cada patita.

      VDD: Patita por la que se aplica la tensión positiva de la alimentación.
      VSS: Patita conectada a la tierra o negativo de la alimentación.
      OSC1/CLKIN: Patita por la que se aplica la entrada del circuito oscilador externo que proporciona la frecuencia de trabajo del microcontrolador.
      OSC2/CLKOUT: Patita auxiliar del circuito oscilador.
      MCLR#: Esta patita es activa con nivel lógico bajo, lo que se representa con el símbolo #. En pocas palabras con esta reseteas el PIC.
      RA0-RA4: Son las líneas de E/S digitales correspondientes a la puerta A. La línea RA4
      RB0-RB7: estas 8 patitas corresponden a las 8 líneas de E/S digitales de la puerta B. La línea RB0 multiplexa otra función, que es la de servir como entrada a otra petición externa de interrupción, por eso se le denomina RB0/INT.

      Citar
      Los PIC16X8X tienen un encapsulado de 18 patitas, dos de ellas soportan la tensión de alimentación, otras dos reciben la señal de oscilador externo y otra se utiliza para generar un Reset. Las 13 patitas restantes funcionan como líneas de E/S para controlar las aplicaciones.


      La frecuencia de funcionamiento, el reloj
      La frecuencia de trabajo del microcontrolador es sumamente importante para establecer la velocidad en el proceso de instrucciones y el consumo de energía.

      ¿Qué coños significa esto?... bien, paso a explicar. Por ej., cuando un PIC16X8X funciona a 10 MHz le corresponde un ciclo de instrucción de 400 ns... ¿por qué? Pues porque cada instrucción tarda en ejecutarse cuatro periodos de reloj, o sea, 4x100 ns. Ahhh se me olvidaba: cada instrucción se ejecuta en un ciclo, menos las de salto que se demoran el doble.


      Bueno muy bonito todo pero... ¿para qué y cómo programo microcontroladores?

      Muchas veces cuando nos metemos en el mundillo de la programación, nos preguntamos si los resultados de nuestra programación podrían ser más palpables, y a veces (por lo menos yo) ni nos imaginamos que podemos crear software que manipule Chips directamente.

      El para qué programar microcontroladores es muy sencillo. Por ejemplo, hoy en día, casi todos los aparatos funcionan con microcontroladores. Desde las puertas automáticas de un súper mercado, pasando por los controles de computadores, hasta la lavadora de mamá. Esto nos da a entender, a grosso modo, que el mercado de los microcontroladores es muy amplio y por ende apetecido; lo que se vuelve en una tentativa para comenzar conocer y manejar estos maravillosos dispositivos.

      Para el cómo he aquí una breve explicación de cómo se modela software para microcontroladores, los pasos a seguir son más o menos los siguientes:

        • Crear el algoritmo
        • Codificar
        • Compilar
        • Ejecutar y Depurar
        • Grabar
        • Montar

      Más o menos la explicación sería: diceñamos el algoritmo del programa que deseemos crear. En lo personal no me gustan los tales diagramas de flujo ni ninguna coñada de esas, si acaso el pseudo-código y listo.

      Codificar (o codear como dicen algunos) es la parte que más me gusta, y consiste en crear el código fuente del programa con el Block de Notas, el Edit, el Vim, el Emacs o cualquier editor de texto plano. Este archivo lo deberéis guardar con la extensión .ASM, ya te estaréis imaginando que la programación será en Assembler ¿no?

      Es muy común que uno oiga hablar del famoso Assembler… que ASM esto, que ASM lo otro, que ASM es difícil, que ahora es fácil, etc. Pero la verdad no le vemos mucho sentido utilizar este lenguaje (de bajo nivel) para programar (si acaso si nos interesamos un poco por él cuando sentimos curiosidad por el mundo del Cracking), ya que para eso está el C++, Java y los demás. Pues bien, llegó la hora de tratar de aprender un poco de este, y que deje de ser un bicho raro. Para ello desarrollaremos unos ejercicios, pero más adelante, ahora sigo explicando el modelado de software.

      La fase de compilación es muy similar a la que hay en lenguajes como C o Java, y consiste pasar el código por un “compilador” (en mi caso MPASM) que determinará si existen errores de sintaxis, y de lo contrario crea un archivo .HEX (es como cuando se crean .exe a partir de un código en C). La extensión es .HEX porque lo que hace es pasar el código a instrucciones en Hexadecimal (no exactamente, pero quedaros con ello mientras tanto).

      Bueno, después necesitamos verificar si en realidad nuestro software funciona. Pero NO resultaría muy viable pasar el software directamente a un Microcontrolador sin haberlo probado, por ello se han inventado los famosos “simuladores”. Como os podréis imaginar lo que hacen estos programas es simular la ejecución del programa en el chip, para poder depurar los posibles errores de lógica. Para que vayas averiguando uno de los mejores simuladores es el Simupic.


      El proceso de grabación se hace a través de una quemadora de PIC’s (en Colombia se le dice quemadora, en otros lados le dicen grabadora, tostadora y que se yo), que es un hardware que se conecta a un puerto serial de vuestra PC, y en donde se “incrusta” el microcontrolador a “quemar”.

      El proceso de grabación se lleva a cabo, obviamente, a través de un software especial. En mi caso utilizo de ICProg… más adelante tal vez explique su uso.

      El montaje es en sí el proceso en el que colocamos nuestro chip en el circuito final, o en una protoboard de ensayos. Esto obviamente para que cumpla con las acciones que hemos programado.

      Primer ejemplo… Aprendiendo a Sumar
      Bueno, antes de codear tenemos que aprendernos algunos conceptos… no os desesperéis. Todos los computadores saben sumar y nuestro PIC16X84 también. Bueno, el caso es que solo saben sumar en binario, porque son máquinas electrónicas digitales. El sumador del PIC es capaz de sumar dos datos de 8 bits cada uno. Dicho sumador tiene un registro, llamado W (de trabajo), en donde aloja uno de los dos sumandos. El otro sumando debemos decir lo que vale o en que posición de memoria está.

      Antes de poner el enunciado del problema, miraremos las instrucciones que vamos a usar:

      Instrucción mov
      Esta instrucción es típica en todos los procesadores y su misión es transferir el contenido de un registro “fuente” (f) a un “destino” (d). En los microcontroladores PIC todos los datos residen en posiciones de memoria de datos y sólo el registro de trabajo W se salva de esta regla. Esto significa que mov puede mover tres tipos de operandos fundamentales:

        1. El contenido del registro W
        2. El contenido de una posición de la memoria de datos o registro.
        3. Un literal o valor inmediato que se incluye en el código máquina de la propia instrucción.

      Para gestionar los posibles operandos existen tres variantes de mov:

      movf f,d: Mueve el contenido del operando fuente, que es una posición de la memoria de datos, al destino, que bien puede ser W cuando d=0, o el propio fuente cuando d=1.

      movwf f: Mueve el contenido del registro W a la posición de la memoria de datos identificada por f. Realiza la transferencia W->f.

      movlw k: Mueve el literal k incluido en el código de la instrucción al registro W, k->W.

      Instrucción add

      addwf f,d: Suma el contenido del registro W con el de f y deposita el resultado en W si el valor de d=0, mientras que si d=1 lo deposita en f.

      addlw k: Suma al contenido del registro W el literal que acompaña a la instrucción y deposita el resultado en W (W+k->W).

      Bien, hasta aquí todo bien, pero sé que con aún no os queda claro y la mejor forma de aclarar todo lo que he intentado explicar es con un ejemplo:

      Enunciado del problema
      El ejercicio debe manejar tres posiciones de memoria de datos. En la dirección 0x0c (recordemos que las posiciones de memoria se manejan con números hexadecimales) se depositará el primer operando; en la 0x0d el segundo y en la 0x0e el resultado de la suma de los primeros operandos. Como valor para el primer operando se va a usar 5 y como segundo operando el 12.

      Nota: en muchas fuentes de información se manejan los números hexadecimales de otra forma… por ejemplo es lo mismo si ves: 0x0c, h’0c’, 0c ó 0Ch. Esto nos indica que hay varias formas de  representar un numero hexadecimal, pero yo utilizo la forma en la que se antepone 0x porque es la más empleada, a demás de ser la que utiliza lenguajes como C/C++.


      Edición del programa
      Como ya lo había dicho, para editar un programa se puede usar cualquier editor de texto plano. Entonces creamos un archivo con el siguiente código, y lo guardamos como suma.asm:

      Código:
      LIST P=16C84			; Indica el modelo de PIC que se usa
      ; Es una directiva del Ensamblador

      ; Zona para etiquetas
      OPERANDO1 EQU 0x0c ; Define la posición del operando 1
      OPERANDO2 EQU 0x0d ; Define la posición del operando 2
      RESULTADO EQU 0x0e ; Define la posición del resultado

      ORG0 ; Comando que indica al Ensamblador
      ; la dirección de la memoria de
      ; programa donde se situará la
      ; siguiente instrucción

      movlw 05 ; 5->W (primera instrucción)
      movwf OPERANDO1 ; W->operando1
      movlw 02 ; 2->W
      movwf OPERANDO2 ; W->operando2
      movfw OPERANDO1 ; opernado1 -> W
      addwf OPERANDO2,0 ; W + operando2 ->W
      movwf RESULTADO ; W->resultado

      END ; Directiva de fin de programa

      A tener en cuenta: el uso de mayúsculas y minúsculas en este fragmento de código obedece a una serie de reglas o normas de estilo, comunes entre los programadores en ensamblador, que aunque no son obligatorias, facilitan la lectura del código fuente. Un resumen de las reglas empleadas es el siguiente:

        • Directivas de compilador en mayúsculas
        • Nombre de variables en mayúsculas
        • Nemónicos en minúsculas
        • Programa bien tabulado

      Solo por aclarar: los “punto y coma” ( ; ) después de cada instrucción se utilizan para comentariar el código. Es como el /* de C el # de Perl ó el // de C++ y Java. Finalmente guardamos nuestro archivo con la extensión .ASM y listo.

      Bueno todo muy bonito, pero como coños pruebo mi maldito programa ¿ehh? Púes bien para eso tendremos que valernos de un software especial, que nos compile el programa (que lo pase a instrucciones en hexadecimal; .ASM -> .HEX). Recomiendo el MPSIM de Microchip y el SIMUPIC de Microsystems Engineering. Lo que me lleva al siguiente capitulo.


      Manejando el Simulador SIMUPIC’84: el primer contacto
      El simulador SIMUPIC’84 es una herramienta que trata de facilitar la labor del programador del PIC. Como sabemos para crear un programa en ensamblador tenemos que recurrir a distintos programas; un editor, un ensamblador y un simulador. El SIMUPIC’84 trata de integrar todos en una sola herramienta, y agrega otras herramientas más, que facilitan el proceso de depuración entre otras.

      Para los que saben un poco del tema sabrán que este es un programa antiguo, pero es de los más fáciles de manejar por lo que lo he escogido. Lo primero que debemos hacer es bajarlo de Internet, entonces vas al google y lo buscas… ¿cómo, te da pereza? Ok, bájalo de aquí.


      Bueno, lo primero es descomprimirlo. Guardas la carpeta donde te quede más cómodo y ejecutas el archivo sim84.exe. Con lo que verás lo siguiente:


      Ok, ahora vamos a ver el funcionamiento básico del programa; primero hay que indicarle el nombre del fichero (.asm) con el que vamos a trabajar, esto lo hacemos dándole “enter” a la opción “Asignar Nombre”. Vamos a trabajar con nuestro primer programa (el que hicimos arriba), por lo tanto debemos guardar ese archivo (suma.asm) en la carpeta donde tengamos nuestro simupic.


      Paso siguiente vamos a la opción “Llamar al editor”. Esta opción nos permite crear un fichero nuevo (llamando al edit del Windows), o cargar un archivo ya existente (en este caso suma.asm).

      Hasta el momento solo hemos editado y cargado el código del programa en el simupic. Ahora debemos ensamblarlo (o compilarlo), por lo que vamos a la opción “Ensamblar”. Es de aclarar que el “ensamblaje” lo hace un programa externo llamado “MPASM”, pero nuestro simupic se encarga de llamarlo y utilizarlo por nosotros. Nos debe aparecer lo siguiente:


      En esa consola nos aparecen los posibles errores de sintaxis, y los molestos warnings. De momento solo nos interesa que no tenga errores, por lo que presionamos cualquier tecla para salir de esa ventana, y la siguiente que vemos es el reporte de los Warnings, simplemente salimos del edit.

      Recordemos que al ensamblar nuestro código fuente, lo que hacemos es crear un fichero .hex que contienes las instrucciones del fuente en hexadecimal. Por esto debemos cargar el fichero hexadecimal en el PIC (esta parte simula el momento en el que quemamos nuestro programa en un PIC de verdad). Vamos a la opción “Cargar fichero HEX” con lo que nos saldrá el siguiente dialogo:


      Fijémonos que al cargar el archivo .hex la parte inferior izquierda cambia:


      En esta parte podemos observar línea a línea el comportamiento de nuestro programa, y es de gran utilidad por que nos sirve como depurador.

      Ahora vamos a “simular” el programa, para analizar su comportamiento. Para ello vamos a configurar nuestro simulador para que nos muestre el comportamiento de las variables, es decir, qué valores toman al transcurrir el programa. Para ello vamos a la opción “Visualizar Registros” y después “Añadir registros”:



      Y después seleccionamos “W (Acumulador)”… recordemos que el registro W (registro de trabajo) es donde almacenamos los datos que necesitemos manipular.


      Luego de esto nos aparecerá en la ventana superior derecha, el registro que hemos agregado y el valor que contiene:


      Es de aclarar que las variables y registros de nuestro PIC almacenan un byte, es decir 8 bits, por lo que las variables y registros que pongamos en esa parte, constarán de 8 números binarios. Si te estás preguntando qué coños es el tal PCL, explico; el PCL es un “apuntador” que le indica al PIC la posición de memoria donde se encuentra la instrucción (en binario) que se debe efectuar. Esto no es así exactamente pero por ahora nos basta.

      Pero en el programa tenemos tres variables (OPERANDO1, OPERANDO2, RESULTADO), que sería importante tener en cuenta para analizar el programa. Para añadirlas a la lista vamos a la opción “Visualizar Registros” y “Añadir registros”, y seleccionamos la opción “Mediante Dir. Hex.”:


      Allí debemos indicarle la posición en memoria en donde se encuentra la variable… recordemos el fragmento de código donde inicializamos las variables:

      Código:
      OPERANDO1 EQU 0x0c		; Define la posición del operando 1
      OPERANDO2 EQU 0x0d ; Define la posición del operando 2
      RESULTADO EQU 0x0e ; Define la posición del resultado

      A la variable OPERANDO1 se le asigno la posición 0x0c; a la variable OPERANDO2 se le asigno la posición 0x0d; a la variable RESULTADO se le asigno la posición 0x0e.

      Por ello en el cuadro de dialogo que nos pide la dirección de memoria de las variables debemos digitar esas direcciones; pero no todas a la vez, sino “una por una”:


      Observemos que no digitamos 0x0c sino 0c, ya que se asume que lo que vamos a digitar es un numero en sistema hexadecimal. Después le damos continuar y asignamos una referencia a esa variable, por ej. Op1:


      Repetimos la misma operación con las variables OPERANDO2 y RESULTADO, y nos fijamos que en la parte superior derecha tengamos algo como:


      Ahora sí vamos a “simular” nuestro programa, pero primero vamos a la opción “Opciones de simulación” y le damos “Reset en el PIC” (esto no creo tener que explicarlo); Ahora nos vamos a la opción “Trazar” para ver el comportamiento de nuestro programa. Analizamos un poco la primera instrucción a la que apunta PCL:


      Esta instrucción equivale a la instrucción movlw 05 de nuestro código fuente. Y le indica al PIC que acumule el valor 5 en el registro de trabajo W. Fijémonos como esto se ve reflejado a nuestra derecha:


      En el registro W tenemos 00000101 que es el equivalente de 5 en notación binaria. Ahora cada vez que demos un “enter” el programa va ir avanzando línea por línea (con el apuntador PCL). Ahora, analizaremos qué pasa cada vez que demos enter (cada item equivale a un enter):

        1. En el registro W tenemos 00000101 (5 en decimal); esto equivale a la instrucción movlw 05.
        2. (en el segundo enter) En el registro op1 tenemos 00000101 (5 en decimal), ya que almacenamos lo que tenía W en OPERANDO1 (referenciado por op1); esto equivale a la instrucción movwf OPERANDO1.
        3. En el registro W tenemos 00000010 (2 en decimal); esto equivale a la instrucción movlw 02.
        4. En el registro op2 tenemos 00000010 (2 en decimal), ya que almacenamos lo que tenía W en OPERANDO2 (referenciado por op2); esto equivale a la instrucción movwf OPERANDO2.
        5. En el registro W tenemos 00000101 (5 en decimal), ya que copiamos el contenido de OPERANDO1 a W; esto equivale a la instrucción movfw OPERANDO1.
        6. En el registro W tenemos 00000111 (7 en decimal), ya que sumamos el contenido de OPERANDO2 con W y el resultado lo almacenamos en W; esto equivale a la instrucción addwf OPERANDO2,0.
        7. En el registro res (que referencia la variable RESULTADO) tenemos 00000111 (7 en decimal), ya que le almacenamos lo que tenía W; esto equivale a la instrucción movwf RESULTADO.

      Cuando ya hemos ejecutado todas las instrucciones nos aparecerá un mensaje indicándonos que el programa ha finalizado:


      ASM vs. C/C++; Eficiencia vs. Comodidad

      Parte importante de este tutorial es hacer un paralelo entre la programación en ASM y en C/C++, ya que cualquier programa para un microcontrolador, además de codificarse en ASM, también puede ser codificado en C. Obviamente en C, al ser un lenguaje de “alto nivel”, se dispone de una mayor comodidad a la hora de programar, pero ello conlleva un pequeño sacrificio en cuanto a tiempo de ejecución. Al grano, vamos a hacer el mismo programa que habíamos hecho en un principio (suma.asm) pero ahora en C (suma.c):

      Código:
      /* Programa que suma el contenido de dos variables en memoria y almacena */
      /* el resultado en una tercera variable de resultado. Equivalente al     */
      /* ejercicio 1.                                                          */
      #include <16c84.h>
      void main( void )
      {
      int operando1 = 5, operando2 = 2, resultado;
      resultado = operando1 + operando2;
      }

      El programa ha sido compilado con el PCM de la casa Custom Computer Services que comercializa Microsystems Engineering y se ha empleado el SIMUPIC’84 para desensamblar su código y traducirlo a ensamblador. El resultado es el siguiente:

      Código:
      00 movlw 00
      01 movwf 0x0a
      02 goto 05
      03 nop
      04 nop
      05 clrf 0x04
      06 clrf 0x03
      07 movlw 0x0c
      08 movwf 0x0e
      09 movlw 0x0d
      0A movwf 0x0f
      0B movlw 0x0e
      0C movwf 0x10
      0D movf 0x0e,0
      0E movwf 0x04
      0F movlw 0x05
      10 movwf 0x00
      11 movf 0x0f,0
      12 movwf 0x04
      13 movlw 02
      14 movwf 0x00
      15 movf 0x00,0
      16 movwf 0x11
      17 movf 0x0e,0
      18 movwf 0x04
      19 movf 0x00,0
      1A movwf 0x12
      1B movf 0x0f,0
      1C movwf 0x04
      1D movf 0x00,0
      1E addwf 0x12,0
      1F movwf 0x12
      20 movf 0x11,0
      21 movwf 0x04
      22 movf 0x12,0
      23 movf 0x00
      24 sleep
      25

      ¡¡¡Demonios, el código resultante está compuesto por 37 instrucciones!!! Esto es casi cuatro veces el programa que habíamos hecho anteriormente en assembler. Esto ya os dará una idea de lo que implica programar en C microcontroladores: tamaño en el programa y por ende tiempo de ejecución.
      25  Informática / Tutoriales - Documentación / Crea tu propia extensión para Firefox [programación en XUL] en: 22 Marzo 2006, 20:12 pm
      Este tuto contiene:

      • Pequeña introducción a XUL
      • Nuestro primer programa en XUL
      • Un programa más complejo
      • Comunicándonos con el usuario
      • Otros widgets de XUL
      • Creación de Menús
      • RDF
      • El registro chrome
      • Modularidad en XUL
      • Nuestra primera extensión
      • XPI


      Pequeña introducción a XUL

      XUL es un lenguaje basado en XML para el desarrollo de interfaces de usuario multiplataforma del que se dice será la pesadilla de .NET de Microsoft. Su nombre deriva de las siglas de XML-based User-interface Language y fue creado por la gente del proyecto Mozilla apoyándose en su motor de renderizado, Gecko, que se encarga tanto del visualizado de webs como de la construcción de la interfaz de usuario.

      Si quereis saber más sobre XUL, podeis encontrar una lista de sus principales ventajas en el documento 'The Joy of XUL' y algún tutorial en sitios como XUL-Planet.


      Nuestro primer programa en XUL

       Para que veais por encima la estructura de un programa en XUL vamos a escribir un programa de tipo ‘Hola Mundo’, aunque como todos los programadores que se creen originales y rebeldes en lugar de un ‘Hola Mundo’ nuestro programa mostrará alguna frase geek; por ejemplo ‘I know kung foo’.

      Usando un editor de texto cualquiera (¿que tal vim?) escribimos lo siguiente, teniendo cuidado con las mayúsculas y las minúsculas, ya que XML es case sensitive, y lo guardamos como foobar.xul por ejemplo:

      Código:
      <?xml version="1.0"?>
      <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
      <!--Esto es una ventana-->
      <window id="ventana-principal" title="The Kung Foo Style" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
      <box>
      <button label="Matrix has you" onclick="alert('I Know Kung Foo');" />
      </box>
      </window>

      Si abrimos Mozilla o Firefox, nos vamos a Archivo→Abrir y seleccionamos nuestro fichero foobar.xul veremos algo similar a esto:


      Ahora que ya habeis visto la sencillez de XUL vamos a ir línea por línea para ver que es cada cosa. Con la primera línea, <?xml version=”1.0”?> lo que hacemos es declarar este archivo como un archivo xml. Un documento XUL siempre tiene que empezar con esta línea, no tiene mas importancia.

      La segunda línea nos permite indicar que hoja de estilo queremos utilizar para definir el aspecto de la aplicación. Estamos hablando de documentos css como los que se utilizan para definir el estilo de una página web, si; mientras XUL define que widgets vamos a utilizar en nuestra aplicación se usa css para definir el aspecto que tendrán estos. En este ejemplo en concreto estamos importando global.css referenciado por chrome://global/skin/ (chrome:// es un tipo especial de URL, podríamos haber utilizado una hoja de estilos creada por nosotros si quisieramos tal como si fuera un documento HTML).

      En la tercera línea tenemos un comentario. Los comentarios siempre tienen que estar entre <!– y –> como define XML y es ignorado al interpretar el documento XUL.

      Debajo, en la cuarta línea, estamos creando una ventana nueva con <window>, cuyos atributos son id para darle un nombre y poder referenciarla mas tarde, title que indica el texto a mostrar en la barra de título y xmlns que indica el espacio de nombres a utilizar. Un espacio de nombres indica los elementos que se reconocen como válidos a la hora de interpretar el fichero; en este caso en concreto solo se reconocerán los elementos definidos en XUL, eso es lo que hace la URL http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul (notar el there is only xul).

      En la sexta línea tenemos una etiqueta box, por box model, el modelo de gestión del layout (como se colocan los objetos dentro de la ventana) que utiliza XUL. Probad a eliminar el <box> y </box>, vereis que la interfaz se descoloca.

      Dentro del box utilizamos la etiqueta button para crear un botón que tendrá como texto a mostrar ‘Matrix has you’, definido por el atributo label. Ese onclick le sonará a la gente que utilice javascript; lo que hace es que al pulsar sobre nuestro botón (onclick) muestre un alert con el texto que le pasamos como argumento. Como habreis imaginado esto completa el cuadro de las aplicaciones XUL (por ahora): XUL define los widgets de la aplicación, con css definimos el aspecto de estos y con javascript su funcionamiento.

      Por último cerramos la etiqueta window con </window>, tal como se hace con las etiquetas de HTML (XHTML es un subconjunto de XML, como lo es XUL, de ahí las semejanzas).


      Un programa más complejo

      Vamos a ver algún nuevo concepto sobre XUL. El programa que veremos esta vez es un poco mas complejo que el que vimos en la anterior entrega. Para empezar creamos una carpeta para el programa, por ejemplo c:\caffeine\ con una imagen de tipo gif con nombre aceptar y creamos nuestro fichero caffeine.xul dentro de ese directorio con el siguiente texto:

      Código:
      <?xml version="1.0"?>
      <window id="ventana-principal" title="Ventana" width="400" height="200" screenX="20" screenY="20" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
      <box>
      <button id="boton1" class="dialog" label="Aceptar" image="file://c:\caffeine\aceptar.gif" accesskey="a"/>
      <button image="file://c:\caffeine\aceptar.gif" disabled="true" accesskey="c"/>
      <button/>
      </box>
      </window>

       Como veis tenemos la primera línea que indica que el documento es un documento XML. Al crear la nueva ventana en la siguiente línea vemos algún atributo que no conociamos aún: width que indica el ancho de la ventana en pixels, height que hace lo propio con el alto y screenX y screenY que nos da la posición inicial de la ventana en pixels.

      Dentro de la ventana como vemos se defininen tres botones. En el primer botón que declaramos, boton1, tenemos un atributo class que indica la clase de botón que es boton1 (nos sirve para definir estilos distintos en la hoja de estilo, si no sabes css no te interesa); un atributo image, para mostrar una imagen en el botón y el atributo acceskey que asocia un acelerador con el botón.

      El segundo botón que creamos tiene la peculiaridad de que no tiene texto (no tiene un atributo label), sino que simplemente tiene una imagen. Además esta deshabilitado con el atributo disabled y tiene como tecla de acceso directo ‘c’. Por último el tercer botón ilustra el que se puede crear objetos que no tengan atributos. En este caso dado que no definimos un texto a mostrar y tampoco una imagen el botón estará vacio.

      Si hacemos doble click sobre el archivo caffeine.xul veremos algo parecido a esto:


      Como último apunte, fijaros en que he comentado que tenemos que abrir el archivo haciendo doble click sobre el en lugar de hacerlo desde Archivo→Abrir. Esto es así por que si lo hicieramos de la segunda forma tendríamos una ventana dentro de la ventana de nuestro navegador, con lo cual no se vería el efecto de cambiar el tamaño de la ventana o cambiar el título. Además como apunte, si utilizais Mozilla Firefox y al hacer doble click sobre el archivo .xul os dice algo parecido a ‘c is not a registered protocol’ teneis que cambiar la asociacion para los archivos xul de firefox.exe -chrome “%1” que será seguramente lo que tengais a firefox.exe -chrome “file:%1”//.


      Comunicándonos con el usuario

      En este tercer ejemplo sobre XUL vamos a construir una versión mas elegante del Hola Mundo que nos permita introducir el texto que queremos que salga en el alert. El código del programa es el siguiente:

      Código:
      <?xml version="1.0"?>
      <window id="ventana-principal" title="Caffeine" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
      <vbox>
      <hbox>
      <label value="Texto a mostrar"/>
      <textbox id="miTexto" maxlength="10"/>
      </hbox>
      <button label="Mostrar" onclick="var texto=document.getElementById('miTexto');alert(texto.value);"/>
      </vbox>
      </window>

      Ejecutad el programa y lo primero que vereis es que la ventana no ocupa todo el espacio del escritorio aún cuando no hemos especificado un ancho y un alto. Esto es así por el layout manager de XUL que se encarga de calcular la posición y el tamaño de los elementos de la interfaz de forma que no haya problemas cuando el usuario cambie el tamaño de las ventanas, por ejemplo. El layout manager de XUL se basa en dos etiquetas principalmente que son <vbox> y <hbox>. Con vbox lo que hacemos es indicar al gestor que posicione los elementos que van a estar dentro de <vbox></vbox> uno debajo de otro; con hbox, que es equivalente al <box> que hemos usado en ejemplos anteriores, le indicamos que los coloque de izquierda a derecha. Combinando estas dos etiquetas, espaciadores y los elementos flexibles podemos crear layouts complejas.

      Si echamos un vistazo al código además de un vbox y un hbox de los que ya hemos hablado vemos dos cosas nuevas, el widget label y el widget textbox. Un label o etiqueta sirve para mostrar un texto en pantalla (un texto corto, para textos largos usariamos description) y el textbox o caja de texto para dar la posibilidad de escribir al usuario. El atributo value de label indica el texto que se mostrará. En el caso del textbox le damos un nombre con id, miTexto, ya que lo necesitaremos en el código javascript para obtener el texto que escribió el usuario en él. Además usamos el atributo maxlenght para indicarle que el máximo número de caractéres que pueden introducirse es 10.

      Como último apunte un vistazo al onclick del botón ya que aquí es donde ocurre toda la magia. Como ya vimos en el ejemplo del ‘Hola Mundo’, onclick define una acción que se ejecutará cuando se haga click sobre ese elemento; en este caso cuando se presione el botón mostrar se ejecutará el código javascript que le pasamos. No es el objeto de estas entradas el explicar javascript pero basta con saber que se declara una variable llamada texto que apunta al elemento de la interfaz cuyo nombre es ‘miTexto’ y después se crea una ventana alert con el texto que contenga este.


      Otros widgets de XUL

      Esta vez vamos a terminar de ver los widgets básicos de XUL, junto con los botones, las cajas de texto o las etiquetas que ya vimos anteriormente. El código del programa ejemplo es el siguiente:

      Código:
      <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
      <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
       
      <tabbox orient="vertical">
      <tabs orient="horizontal">
      <tab label="Radiobuttons"/>
      <tab label="Checkboxes"/>
      <tab label="Listbox"/>
      <tab label="Imagenes"/>
      </tabs>
       
      <tabpanels>
      <radiogroup orient="vertical">
      <radio label="Cafe solo"/>
      <radio label="Cafe con leche"/>
      <radio label="Descafeinado"/>
      </radiogroup>
      <box>
      <checkbox label="Donuts"/>
      <checkbox label="Croisants"/>
      <checkbox label="Caracolas"/>
      </box>
      <image src="file://C:\widgets\mozilla.png"/>
      </tabpanels>
      </tabbox>
       
      </window>

      Las pestañas se declaran mediante la etiqueta tabbox. orient nos dice si la orientación, en este caso de las pestañas, será horizontal o vertical. Cada una de las pestañas esta compuesta por dos componentes diferenciados, las pestañas en si, que vienen definidas por una serie de etiquetas tab dentro de un elemento tabs y el contenido de las pestañas que se define dentro de tabpanels. Dentro de tabpanels habrá tantos elementos como pestañas definamos en tabs (esto no es necesariamente cierto pero vamos a simplificar) y se seguirá una correspondecia por orden de declaración a la hora de asignar el contenido que corresponde a cada pestaña. En este caso, por ejemplo, en la pestaña 1 tenemos un elemento radiogroup compuesto por varios elementos radio, en la pestaña 2 tenemos una serie de checkboxes que agrupamos en un box para que sea un solo elemento y en la tercera pestaña tenemos una imagen.

      Veamos ahora los otros widgets. En primer lugar, en la primera pestaña tenemos radiobuttons, que representan opciones excluyentes. Un grupo de radiobuttons se define con radiogroup y cada uno de los radiobuttons con radio, como podemos ver. Los checkboxes son opciones no excluyentes que se definen con la etiqueta checkbox. Por último las imágenes se definen con la etiqueta image que tiene como atributo la ruta a la imagen (src de source, fuente).


      Creación de Menús

      Antes de empezar con cosas mas serias vamos a ver como se implementan los menús en XUL.

      Código:
      <?xml version="1.0"?>
      <?xml-stylesheet href="chrome://global/skin" type="text/css"?>
      <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
      <menubar>
      <menu label="Archivo">
      <menupopup>
      <menuitem label="Nuevo"/>
      <menuseparator/>
      <menuitem label="Abrir"/>
      <menuitem label="Salvar"/>
      <menuitem label="Cerrar"/>
      </menupopup>
      </menu>
      <menu label="Editar">
      <menupopup>
      <menuitem label="Deshacer"/>
      <menuseparator/>
      <menuitem label="Copiar"/>
      <menuitem label="Cortar"/>
      <menuitem label="Pegar"/>
      </menupopup>
      </menu>
      <menu label="Ver">
      <menupopup>
      <menuitem label="Regla"/>
      <menu label="Fuente">
      <menupopup>
      <menuitem label="Arial"/>
      <menuitem label="Verdana"/>
      </menupopup>
      </menu>
      <menu label="Color">
      <menupopup>
      <radiogroup>
      <radio label="Rojo"/>
      <radio label="Azul"/>
      <radio label="Negro"/>
      <radio label="Verde"/>
      </radiogroup>
      </menupopup>
      </menu>
      <menuitem label="Pantalla Completa"/>
      </menupopup>
      </menu>
      </menubar>
      </window>

      menubar define la barra de menús. Dentro de menubar tenemos un conjunto de etiquetas menu que son las que definen las entradas de menú en si. Si al pulsar sobre el menú se va a desplegar una lista de submenús, entonces utilizamos menupopup y menuitem para cada uno de los submenús. En el caso de que no hubieramos agrupado los submenús (menuitems) en un menupopup se habrían mezclado todas las entradas en una sola, que no es lo que queremos. Además tenemos otro elemento que es menuseparator, que introduce una línea para dividir el menú en partes. Notar también que los submenús también pueden ser menús con varias entradas como vemos en el caso de fuente en que definimos un nuevo menú y no un menuitem. Como último comentario decir que en lugar de menuitems o menús, como entradas dentro de los menús también podríamos tener otros elementos como checkboxes o radiobuttons como vemos en el caso del menú color.


      RDF

      Vamos a hacer un inciso para hablar sobre RDF. RDF es un estándar de la W3C cuyo nombre deriva de las siglas de ‘Resource Description Framework’ y que es un subconjunto de XML, al igual que XUL, que nos sirve para expresar hechos (cosas que son ciertas, la información en forma de predicados que tenemos sobre el mundo real). Sería algo parecido a los predicados de Prolog. Por ejemplo, un predicado del tipo ‘A Linus le gustan los pingüinos’ en RDF podría expresarse como:

      Código:
      <Description about="Linus">
      <le-gustan>pingüinos</le-gustan>
      </Description>

      La etiqueta Description sirve para representar uno o mas hechos, con un atributo about para indicar sobre quien es ese hecho, es decir, el sujeto del hecho. Description puede contener una o varias etiquetas hijas siendo cada una de ellas un predicado.

      Código:
      <Description about="Linus">
      <le-gustan>pingüinos</le-gustan>
      <informatico>true</informatico>
      <linuxero>true</linuxero>
      <nacionalidad>finlandesa</nacionalidad>
      </Description>

      En este ejemplo definimos una serie de predicados sobre Linus, con una etiqueta definida por nosotros mismos para desribir ese predicado y con el valor entre las etiquetas.

      Ahora, ¿como expresariamos el hecho de que a Linus le gustan además de los pingüinos los sombreros o los camaleones?. Podríamos usar varios predicados le-gustan pero RDF nos proporciona un método mejor. En RDF se definen tres etiquetas que sirven como contenedoras: <Bag>, que define un conjunto de items; <Seq>, que define un conjunto de items ordenados y <Alt>, que define un conjunto de elementos que son alternativos, es decir, que se consideran equivalentes. Los elementos de un contenedor se encierra entre <li> y </li> (li de list, lista, al igual que la etiqueta de XHTML). Veamos un ejemplo:

      Código:
      <Description about="Linus">
      <Bag ID="Gustos">
      <li>pingüinos</li>
      <li>sombreros</li>
      <li>camaleones</li>
      </Bag>
      <informatico>true</informatico>
      <linuxero>true</linuxero>
      <nacionalidad>finlandesa</nacionalidad>
      </Description>

      Ahora tenemos una lista de los gustos de Linus usando un Bag que sería equivalente a un predicado con varios valores. Para identificar el predicado que define este Bag usamos el atributo ID. Seq y Alt serían similares, tan solo cambia su significado.

      Para finalizar esta pequeña introducción a RDF vamos a ver un ejemplo completo para explicar un par de cosas que quedan en el tintero.

      Código:
      <RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:BEBIDAS="http://www.caffeine.com/rdf#">
       
      <RDF:Bag about="http://www.caffeine.com/tipos-de-bebida">
      <RDF:li>
      <RDF:Description about="http://www.caffeine.com/infusiones/te">
      <BEBIDAS:nombre>Te</BEBIDAS:name>
      <BEBIDAS:precio>1,12</BEBIDAS:precio>
      </RDF:Description>
      </RDF:li>
      <RDF:li>
      <RDF:Description about="http://www.caffeine.com/infusiones/tila">
      <BEBIDAS:nombre>Tila</BEBIDAS:name>
      <BEBIDAS:precio>0,9</BEBIDAS:precio>
      </RDF:Description>
      </RDF:li>
      <RDF:li>
      <RDF:Description about="http://www.caffeine.com/cafes/solo">
      <BEBIDAS:nombre>Cafe solo</BEBIDAS:name>
      <BEBIDAS:precio>1,2</BEBIDAS:precio>
      </RDF:Description>
      </RDF:li>
      </RDF:Bag>
      </RDF:RDF>

      Lo primero que tenemos que comentar es la línea con la que comienza el RDF. Esta es similar al window de XUL en el que definimos que espacio de nombres vamos a utilizar. Usaremos RDF que está definida en tal URL y BEBIDAS que está definido en tal otra. Relacionado con esto, el RDF: que aparece antes de las palabras clave de RDF o el BEBIDAS: que aparece antes de los nombres de los predicados indica el espacio de nombres que estamos utilizando, es decir, RDF:li por ejemplo significa que nos estamos refiriendo a la etiqueta li que está definida dentro de RDF.


      El registro chrome

      Hasta ahora dividiamos un programa XUL en la interfaz en si, creada con XUL; el aspecto de los widgets, definido con CSS y la funcionalidad, programada en javascript. Sin embargo javascript no nos permite cosas como acceder al disco duro, de modo que si tuvieramos que limitar la funcionalidad de los programas basados en XUL a lo que podemos hacer con javascript, estos no tendrían demasiada utilidad.

      La solución a este problema nos viene dada en forma de una libreria escrita en código dependiente de la plataforma llamada XPCOM y una capa intermedia entre javascript y esta librería llamada XPConnect, que traduce los objetos XPCOM en objetos javascript que puedan ser manipulados en nuestro programa.

      El problema de esto es que la seguridad de Mozilla dejaría mucho que desear si cualquier script pudiera hacer cosas como borrar los archivos del disco duro. Aquí es donde vemos la utilidad de chrome.

      Como ya se comentó la url chrome:// se refiere al directorio chrome dentro del directorio de instalación de Mozilla/Firefox. Solo los scripts que se encuentren en este directorio tienen permiso para utilizar XPConnect, lo cual implica que para usar los objetos de XPCOM necesitamos instalar nuestra aplicación en chrome. Sin embargo no basta simplemente con mover nuestros ficheros a ese directorio, si no que tenemos que añadir una serie de entradas a installed-chrome.txt para que nuestra aplicación sea añadida al ‘registro chrome’ de forma que Mozilla pueda resolver las urls chrome:// al directorio en que esta instalada nuestra aplicación.

      Lo primero que tenemos que hacer es crear un archivo de tipo rdf llamado contents.rdf que proporcionará información a Mozilla sobre el nombre de la aplicación, el autor, la versión...

      Código:
      <?xml version="1.0"?>
       
          <RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
       
          <RDF:Seq about="urn:mozilla:package:root">
          <RDF:li resource="urn:mozilla:package:caffeine"/>
          </RDF:Seq>
       
          <RDF:Description about="urn:mozilla:package:caffeine"
          chrome:displayName="The Caffeine XPerience"
          chrome:author="Zootropo"
          chrome:name="caffeine"
          chrome:extension="true"/>
       
          </RDF:RDF>


      En este ejemplo displayName es el nombre completo para la aplicación; author el autor de la aplicación, name el identificador de la aplicación (como se referirá Mozilla a él, tiene que ser igual que el valor después de urn:mozilla:package:) y extension indica si la aplicación es una extensión, de forma que se mostrará en la lista de extensiones de Mozilla en el caso de que sea true (cierto).

      Una vez creado nuestro fichero contents.rdf lo copiamos a la carpeta de nuestra aplicación. Editemos ahora el fichero installed-chrome.txt que se encuentra dentro del directorio chrome, teniendo en cuenta cerrar antes el navegador, para registrar nuestra aplicación de forma que Mozilla sepa donde encontrarla. Al final del fichero añadimos por ejemplo para el caso de que el directorio de la aplicación sea caffeine/content/caffeine/ dentro del directorio chrome:

      Código:
        content,install,url,resource:/chrome/caffeine/content/caffeine/

       Solo queda borrar el fichero chrome.rdf que contiene la información sobre las extensiones registradas en chrome para que vuelva a crearse cuando ejecutemos Mozilla/Firefox y tenga en cuenta nuestra aplicación. La información de cada una de las aplicaciones la recolectará basándose en installed-chrome.txt para encontrarla y en el contents.rdf que creamos para procesar el contenido de nuestra aplicación.

      Ahora deberíamos ser capaces de poder ejecutar cualquier archivo xul de nuestra aplicación (y por añadidura referirnos a cualquier archivo de nuestra aplicación) usando una url chrome de la forma:

      Código:
        chrome://id-aplicacion/content/archivo.xul

      Por ejemplo para abrir el archivo foo.xul de la aplicación con id caffeine podríamos simplemente escribir chrome://caffeine/content/foo.xul


      Modularidad en XUL

       A la hora de organizar los ficheros de nuestra aplicación se sigue un estándar de facto en el que tenemos tres subdirectorios dentro de la carpeta de nuestra aplicación: content, local y skin.

      El directorio content incluye un subdirectorio con el nombre de nuestra aplicación que a su vez contiene todos los archivos xul de la aplicación, además de los archivos js con el código javascript de la aplicación y un fichero contents.rdf que nos dice entre otras cosas cual es el archivo .xul principal.

      En el directorio locale se incluyen una serie de subdirectorios con el código del idioma correspondiente, por ejemplo es-ES para castellano o en-US para inglés de estados unidos. Dentro de cada uno de estos directorios tenemos un subdirectorio con el nombre de la aplicación que incluye a su vez los ficheros DTDque sirven para separar la aplicación de los mensajes de esta para facilitar el proceso de traducción y un fichero contents.rdf.

      Por último el directorio skin contiene otro subdirectorio de nombre classic que incluye un directorio con el nombre de nuestra aplicación con los ficheros css que se utilizan para modificar el aspecto de la aplicación y un archivo contents.rdf.

      Hasta ahora el código javascript que hemos utilizado estaba incrustado dentro de los ficheros xul, en el siguiente ejemplo veremos como importar el código de un fichero js separado del código xul. Como simple comentario, el código css que hemos utilizado hasta ahora estaba almacenado en archivos css aparte como dicta la norma para conseguir modularidad; sin embargo, al igual que el código javascript, el código css puede almacenarse en un fichero aparte o incrustado dentro del propio archivo xul.

      Código:
      <?xml version="1.0"?>
          <!DOCTYPE window SYSTEM "chrome://caffeine/locale/caffeine.dtd">
       
          <?xml-stylesheet href="chrome://caffeine/skin/caffeine.css" type="text/css"?>
          <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:nc="http://home.netscape.com/NC-rdf#">
       
          <script type="application/x-javascript"
          src="chrome://caffeine/content/caffeine.js"/>
       
          <button onclick="funcion();" label="&nombreBoton;" accesskey="&teclaAcceso"/>
       
          </window>

      La línea de script es la que se encarga de importar el código javascript desde el fichero javascript especificado de forma que podemos usar la función funcion() al hacer click en el botón aunque no la hallamos definido en este fichero. Podemos ver también la forma en que se importan los ficheros dtd con los mensajes de la aplicación en la segunda línea del código fuente. Hasta ahora no habíamos utilizado ficheros dtd, sino que incluíamos el texto de la aplicación imbuida dentro de esta; ahora con estos ficheros llevamos la modularidad de xul hasta el extremo, separando del código xul el funcionamiento, la apariencia y los mensajes.

      El uso de los mensajes que se definen en los DTDs podemos verlo en el label y la accesskey del botón, un símbolo ampersand, el nombre que le dimos al mensaje en el dtd y punto y coma. El fichero DTD para este programa sería:

      Código:
          <!ENTITY nombreBoton "Mi Boton">
          <!ENTITY teclaAcceso "M">

      Para cada mensaje como vemos tenemos un !ENTITY, la segunda entrada de !ENTITY es el nombre del mensaje que se utilizará para referirse a él en el código XUL como ya vimos y el tercero el valor. En este DTD nombreBoton es “Mi Boton” pero podríamos tener otro DTD para el inglés en cuyo caso sería “My Button”, etc, de forma que la traducción de la aplicación es mas sencilla al separar el código y los mensajes.

      Por último como ya dijimos cada uno de los directorios de la aplicación incluye un fichero contents.rdf para poder registrar ese directorio en el registro chrome. Veamos el caso del contents.rdf de los locales:

      Código:
          <?xml version="1.0"?>
          <RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
       
          <!-- Lista de todos los locales que incluimos, en este caso solo es-ES -->
          <RDF:Seq about="urn:mozilla:locale:root">
          <RDF:li resource="urn:mozilla:locale:es-ES"/>
          </RDF:Seq>
       
          <!-- Informacion sobre cada uno de los locales -->
          <RDF:Description about="urn:mozilla:locale:es-ES"
          chrome:displayName="Castellano (ES)"
          chrome:name="es-ES">
          <chrome:packages>
          <RDF:Seq about="urn:mozilla:locale:es-ES:packages">
          <RDF:li resource="urn:mozilla:locale:es-ES:caffeine"/>
          </RDF:Seq>
          </chrome:packages>
          </RDF:Description>
       
          </RDF:RDF>

      Y el contents.rdf de los skins:

      Código:
          <?xml version="1.0"?>
       
          <RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
       
          <RDF:Seq about="urn:mozilla:skin:root">
          <RDF:li resource="urn:mozilla:skin:classic/1.0" />
          </RDF:Seq>
       
          <RDF:Description about="urn:mozilla:skin:classic/1.0">
          <chrome:packages>
          <RDF:Seq about="urn:mozilla:skin:classic/1.0:packages">
       
          </RDF:Seq>
          </chrome:packages>
          </RDF:Description>
       
          </RDF:RDF>


      Estos dos contents.rdf no necesitan comentarios. Son muy parecidos al contents.rdf del directorio contents. Tan solo queda registrar en el registro chrome contents, locals y skins. Si recordamos en el anterior post sobre XUL al registrar el contents añadíamos a installed-chrome.txt una línea similar a esta:

      Código:
        content,install,url,resource:/chrome/caffeine/content/caffeine/

      Si echamos un vistazo a las demás entradas en installed-chrome veremos que algunas comienzan con skin, otras con locale y otras con contents. Esto es lo único que tenemos que cambiar a la hora de registrar skins y locales, lo demás es similar, por lo tanto para nuestra aplicación de ejemplo tendríamos que añadir las líneas:

      Código:
        skin,install,url,resource:/chrome/caffeine/content/caffeine/
        locale,install,url,resource:/chrome/caffeine/locale/es-ES/
        content,install,url,resource:/chrome/caffeine/skin/classic/caffeine/


      Nuestra primera extensión

       Ahora que hemos visto un poco por encima como funciona XUL vamos a ponernos un poco mas serios y vamos a crear una pequeña extensión para nuestro navegador. Por ahora algo sencillo como añadir una nueva entrada de menú al menú de herramientas de Firefox, que nos muestre un alert con la hora del sistema cada vez que se haga click sobre él. El proceso para Mozilla sería un proceso bastante parecido. Para ello tenemos que ver que son los overlays, cuya traducción al castellano sería algo asi como superposiciones.

      Lo primero vamos a recordar que toda la interfaz de Mozilla y Firefox esta hecha con XUL, por lo tanto será razonable suponer que en algún lugar tiene que haber un fichero xul que lo define. Y acertariais al hacer esta suposición. La interfaz del navegador esta definida en un archivo llamado browser.xul en el subdirectorio chrome dentro de la carpeta en la que esta instalado nuestro navegador, pero si entrais en esa carpeta para echar un vistazo al código no lo encontrareis. browser.xul esta empaquetado dentro de uno de esos archivos .jar que veis.

      Un archivo jar es simplemente un archivo .zip con la extensión renombrada. Podemos descomprimirlo con winzip u otro programa de compresión de archivos. Si descomprimimos browser.jar tendremos una carpeta browser que alberga una carpeta content en la que tenemos a su vez las carpetas browser y browser-region. Dentro de la primera se encuentra además del browser.xul al que nos referíamos otros archivos .xul, archivos js con código javascript y archivos css, hojas de estilo.

      Si abrimos el archivo browser.xul tendremos una ventana del navegador de Firefox pero con la peculiaridad de que no veremos las barras de herramientas, los botones u otros widgets de las extensiones que tengamos instaladas. Esto es así por que cuando abrimos una ventana del navegador estamos abriendo browser.xul, pero también otros archivos .xul que se superponen. Sería algo así como coger varios dibujos en papel cebolla y ponerlos uno encima de otro, algo así como las capas de Photoshop. Esto es lo que vamos a ver ahora, el overlay.

      Lo primero que tenemos que hacer es crear una carpeta para nuestra aplicación, por ejemplo ‘hora’ completando una estructura de directorios hora/content/hora. Dentro del directorio mas profundo de esta jerarquía creamos un archivo hora.xul con el siguiente código:

      Código:
          <?xml version="1.0"?>
       
          <overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:nc="http://home.netscape.com/NC-rdf#">
       
          <popup id="menu_ToolsPopup">
       
          <menuitem
          oncommand="fecha=new Date(); hora=fecha.getHours(); minuto=fecha.getMinutes(); segundo=fecha.getSeconds(); alert(hora + ' : ' + minuto + ' : ' + segundo);" label="Mostrar Hora;"/>
       
          </popup>
       
          </overlay>

      Lo que estamos haciendo aquí es crear un documento XUL que solo contiene una entrada de menú dentro de un popup que queremos superponer sobre el navegador. La única diferencia con los ejemplos que hemos visto hasta ahora es que en lugar de definir una ventana definimos un overlay pero aparte del nombre no hay mucha diferencia. Simplemente indicamos a Mozilla que este no es un documento xul completo, si no que vamos a combinarlo con otro/s documentos xul.

      Ahora veamos como funcionaría el overlay con un caso sencillo antes de pasar a mayores. Supongamos un archivo XUL que importa el overlay que acabamos de definir; para ello usaría algo parecido a este código:

      Código:
          <?xul-overlay href="chrome://hora/content/hora.xul"?>

      Lo que ocurriría entonces es que para cada elemento con un id definido en el archivo de overlay se buscaría el mismo elemento con el mismo id en el documento sobre el que queremos superponer. Antes de nada tendríamos que haber abierto el fichero browser.xul para ver donde se definen las entradas de menú del menú herramientas y cual es el ID de conjunto que las contiene. Ese trabajo ya esta hecho; como se puede ver en el código tenemos un elemento popup con id menu_ToolsPopup, aquí es donde está la clave.

      En el caso de que no se encuentre una instancia de ese elemento con ese ID entonces este elemento no se tiene en cuenta al hacer el overlay. Si por el contrario si se encuentra, entonces el elemento y todo lo que se defina dentro de este en el overlay pasará a superponerse al documento raíz, lo cual quiere decir que el elemento del documento raíz adquirirá todos los atributos que se definan en el overlay además de todos sus subelementos.

      En este ejemplo el documento raíz es el que se encargaba de añadir el overlay usando la etiqueta xul-overlay, sin embargo esto no nos es de utilidad en nuestro caso ya que no queremos tener que cambiar el código de browser.xul. La solución es hacer que sea el overlay el que diga a que documento se tiene que superponer. Esto podemos hacerlo añadiendo la información de los overlay a nuestro contents.rdf

      Código:
          <?xml version="1.0"?>
       
          <RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
       
          <RDF:Seq about="urn:mozilla:package:root">
          <RDF:li resource="urn:mozilla:package:hora"/>
          </RDF:Seq>
       
          <RDF:Description about="urn:mozilla:package:hora"
          chrome:displayName="Mostrar Hora 0.1"
          chrome:author="Zootropo"
          chrome:authorURL="http://zootropo.blogspot.com"
          chrome:name="hora"
          chrome:extension="true"
          chrome:description="Añade una opción al menú de herramientas para mostrar la hora actual.">
          </RDF:Description>
       
          <RDF:Seq about="urn:mozilla:overlays">
          <RDF:li resource="chrome://browser/content/browser.xul"/>
          </RDF:Seq>
       
          <RDF:Seq about="chrome://browser/content/browser.xul">
          <RDF:li>chrome://hora/content/hora.xul</RDF:li>
          </RDF:Seq>
       
          </RDF:RDF>

      Vemos que tenemos un par de listas nuevas, una referida a urn:mozilla:overlays en el que los elementos de la secuencia son los documentos sobre los que se va a hacer el overlay (en este caso el browser.xul para superponer a nuestro navegador) y otra secuencia con el archivo xul sobre el que hacemos el overlay como sujeto y como entradas de la secuencia los archivos xul a superponer.

      Borramos overlay.rdf como en el post anterior, añadimos una entrada nueva a installed-chrome.txt para el content de nuestra aplicación (no tendremos locale porque la única función javascript que utilizamos esta embebida en el archivo xul ni skin ya que no utilizamos ningún css) y reiniciamos nuestro navegador, tras lo cual tendremos una nueva entrada al final del menú de herramientas que nos permitirá ver la hora del sistema.



      XPI

       Ahora que ya hemos terminado nuestra pequeña extensión para Firefox vamos a ver como podemos crear un xpi para que se instale automáticamente. La extensión xpi viene de XPInstall donde XP se refiere a Cross (X) Platform o multiplataforma, es decir, que puede ser ejecutado en distintas plataformas (Windows, Linux, Mac OS,...).

      Un xpi es un simple archivo zip con extensión renombrada que contiene un fichero de instalación y los ficheros que componen la extensión. En el caso de las versiones anteriores a la 0.9 se utilizaba install.js como script instalador, ahora en cambio se utiliza un fichero rdf, install.rdf, pero podemos incluir ambos si queremos que la extensión se pueda instalar en la versión 0.9 y también en las anteriores.

      Un archivo install.rdf tendría un aspecto parecido a este:

      Código:
          <?xml version="1.0"?>
          <RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
          <Description about="urn:mozilla:install-manifest">
          <em:id>{eb78c871-3d9d-433f-b49b-12468119be89}</em:id>
          <em:name>Mostrar Hora</em:name>
          <em:version>0.1</em:version>
          <em:description>Muestra la hora del sistema en un alert al hacer click sobre la entrada de menu correspondiente.</em:description>
          <em:creator>Zootropo</em:creator>
          <em:homepageURL>http://zootropo.blogspot.com </em:homepageURL>
       
          <em:file>
          <Description about="urn:mozilla:extension:file:hora.jar">
          <em:package>/content/hora/</em:package>
          </Description>
          </em:file>
          <em:targetApplication>
          <Description>
          <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
          <em:minVersion>0.9</em:minVersion>
          <em:maxVersion>0.9</em:maxVersion>
          </Description>
          </em:targetApplication>
       
          </Description>
          </RDF>

      Tenemos primero una serie de predicados de información sobre nuestra aplicación que son los siguientes:

      • em:id que se refiere a un id único que podemos generar con esta utilidad de Microsoft y no al identificador de la extensión
      • em:name, el nombre de la extensión
      • em:version, la versión de nuestra extensión.
      • em:description, una descripción de la utilidad de nuestra aplicación.
      • em:creator, nombre del creador de la aplicación.
      • em:homepageURL, página web de la extensión.
      • em:optionsURL, ventana que se mostrará al hacer click sobre las preferencias.
      • em:aboutURL, ventana que se mostrará como About de la aplicación.
      • em:iconURL, icono para identificar la extensión.
      • em:updateURL, URL opcional para la autoactualización.
      Tenemos después un predicado em:file que agrupa información sobre los ficheros de nuestra aplicación, donde se encuentra content, skin y locale dentro del archivo .jar, y otro predicado em:targetApplication sobre el programa para el que está destinado nuestra extensión. em:id se refiere al id del navegador, en este caso Firefox y minVersion y maxVersion se refieren respectivamente a la versión mínima y máxima de la aplicación.

      Si no quereis complicaros podeis utilizar para crear los xpi un script creado por Ted Mielczarek que podeis encontrar en su página web. También podeis consultar la traducción del documento de Ben Gooder sobre install.rdf.

      Ahora que tenemos todos los archivos necesarios lo primero que tenemos que hacer es crear un archivo jar que incluya los archivos de nuestra extensión. Comprimimos en un mismo archivo zip las carpetas content, locale y skin de nuestra aplicación (o content solo si no hemos definido las otras dos). Cambiamos la extensión del archivo resultante a .jar de forma que nos quede un archivo hora.jar en este ejemplo y ya tenemos el archivo jar que empaqueta nuestra aplicación, nos queda empaquetar el .jar y el archivo de instalación en un xpi. Para eso creamos una carpeta chrome a la que movemos hora.jar y comprimimos en un .zip la carpeta chrome y el install.rdf (e install.js en el caso de que lo tengamos) y renombramos la extensión del archivo a .xpi.

      El archivo xpi resultante para que comprobeis como se instala automáticamente como cualquier otra extensión de firefox es este.

      Fuente Original: Mundo Geek
      Autorizado por el autor original: zootropo
      Licencia: http://creativecommons.org/licenses/by/2.0/
      26  Foros Generales / Sugerencias y dudas sobre el Foro / No veo cuantos mensajes tengo en: 15 Marzo 2006, 22:06 pm

      Pues eso... la verdad es que hace como dos meses cuando veo algun post mio aparece esto:


      No habia reportado nada ya que la verdad no me interesa si tengo o no mensajes... pero ya me entró el bichito de la curiosidad ¿porqué pasa eso, ehhh?. He visto en otros foros SMF y no pasa esto. ¿a alguno de uds. les pasa?

      Saludos!!![/color]
      27  Foros Generales / Sugerencias y dudas sobre el Foro / Como funciona el sistema de estrellas en un foro SMF en: 20 Febrero 2006, 23:48 pm

      Pués se que ya se ha hablado del sistema de estrellas, y que el-brujo quitó esa vaina. Pero, no he visto un foro (en otra web) que tenga eso, y que deje que uno ayude a otros usuarios a incrementar estrellas.

      Talvez esa sea mi duda: ¿las estrellas se incrementaban de acuerdo a la cantidad de mensajes? o... ¿los demás usuarios hacian que las estrellas se incrementaran?

      Lo que pasa es que en la epoca en que existia eso no conocía esta web. Es más, nisiquiera tenía acceso a internet.

      Nada, solo eso. Si el post sobra, adelante podeis borrarlo. Solo que no me quiero quedar con la duda.

      Saludos!!!
      28  Foros Generales / Sugerencias y dudas sobre el Foro / ¿Error o Bug en el foro de elhacker.net? en: 20 Febrero 2006, 20:00 pm

      Pues por todos es bien sabido que existen usuarios Colaboradores y Moderadores, que se la pasan colaborando (valga la redundancia), y por ello recolectan bastante tiempo en las estadísticas. Por ejemplo el caso de Riven Ward, que a reunido como 80 dias conectado al foro, muy por encima de el famoso brujo.

      Pero hoy fisgoneando, me doy cuenta de que un usuario con el nick chapus, tenia como 2000 dias conectado. Esta es una cifra enorme, casi imposible, mejor dicho imposible. Además no tiene ni un post.

      Entonces mi pregunta es: ¿es un error del foro? o talvez ¿se está explotando un bug?. ¿quien me saca de la duda?.

      Por si las moscas, les dejo el link para las estadísticas del foro --Aquí-- para que se pillen mejor.

      Saludos!!!
      29  Foros Generales / Sugerencias y dudas sobre el Foro / Opción de borrar posts en: 18 Febrero 2006, 02:58 am
      Nada, quería saber porqué se quito la opción de borrar (), para los usuarios sin privilegios.

      Saludos!!!
      30  Media / Juegos y Consolas / Primeras imágenes de Bomberman para XBox 360 en: 16 Febrero 2006, 23:23 pm
      Esto lo encontré por ahí y me pareció curioso:

      Se revelan las primeras imágenes de la llegada de este clásico personaje al Xbox 360.

      Hudson Soft ha liberado a través de la revista Famitsu, las primeras imágenes del juego Bomberman Act Zero, el cuál marca la llegada del clásico personaje a la nueva máquina de Microsoft.

      Este juego se situará en el futuro de la serie, teniendo un cambio estético importante, mostrandose como un juego más adulto. El título saldrá al mercado japones el próximo 25 de Mayo, haber como toman los japos el cambio de estética "cute" que siempre ha tenido el personaje, por algo más maduro.

      He aquí las imágenes:


      [/color]
      Páginas: 1 2 [3] 4
      WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines