Problema de principiante en ensamblador con PIC y MPLAB

Muy buenas, realmente tengo buenas expectativas sobre este foro.
Les contaré mi triste historia (puedes saltarte a la duda buscando "*****"):
Hoy, escribo a 25 de Abril del 2020, por si es necesario decirlo (Es mi primera publicación), soy un estudiante de preparatoria en Mexico y lo que necesito entender es cómo programar en ensamblador.
He tenido un maestro en mi experiencia muy malo (aunque creo que de manera sarcástica todo mi grupo lo alaba por ello).
Basta con decir que no explica casi nada, por lo menos no este semestre.
No exagero, de verdad, estoy en el curso de Mecatrónica (vaya lio en el que me metí xd) y lo que debíamos de ver este momento era la programación de microcontroladores PIC, en assembler qué si no.
Y pues la primera evaluación fue sobre la composición física de microprocesadores y microcontroladores.
En la segunda unidad tocaba programación, primeras semanas todo bien, aunque honestamente lo mas cercano a escribir un código fue copiar uno EXACTAMENTE como venía en una presentación borrosa de powerpoint, cualquier error era morir tratando de ver que cero no pusiste y por su puesto, sin entender absolutamente nada. Y bueno, entra el COVID 19 en acción :(.
Nos encargó nueve prácticas en simulación sin saber ni una miseria de cómo funcionaba el assembler, algunos compañeros ni sabían instalar MPLAB o Proteus.
Ni siquiera sé exactamente qué quiere que haga cada cosa pero ya que.
Todo lo que he aprendido hasta ahora fue de manera autodidacta, así que puede tener un sin fin de errores.

*************
Ahora bien, ¿Por que no funciona?, MPLAB simplemente no detecta el cambio de banco, cualquier clase de error sería de gran ayuda que me lo hicieran saber.
Es una practica en simulación MUY fácil, pero no tengo gran idea de lo que hago, eso sí, todo el programa lo creé desde cero sin copiar el asm de otros.

Empieza en el renglón 4, Aparecen triángulos amarillos desde "LIST...." hasta "goto inicio", La simulación no funciona de ninguna manera, inicia dando señal sin presionar nada en un pin que ni siquiera se configura de salida, de estar correcto el programa, claro.
Las propiedades del proyecto indican que es para el PIC16F877A, justo el que tiene el Include del programa.
Código:
;Intermitencia usando el temporizador TMR0 a modo de oscilador  

LIST p=16F877A                ;Identifica el PIC a usar                              
INCLUDE "p16F877a.INC"  ;Libreria del PIC                                              

__CONFIG 0x1F39

org 0
goto Inicio  

Inicio
     bsf     STATUS,RP0     ;Establecer puertos
    movlw   b'111111'    
    movwf   TRISA
    bcf     TRISB,0                ;Led de salida, apreciable mejor con osciloscopio
    bcf     STATUS,RP0
    goto    Tiempos

Tiempos                            ;Tiempo a contar segun la entrada activada
Tiempo1ms
    btfss   PORTA,0             ;Testeo, ¿PORTA0 esta activa?
    goto    Tiempo10ms      ;No, prueba con el siguiente tiempo
    bsf     STATUS,RP0         ;Si, continua
    movlw   b'11010100'
    movwf   OPTION_REG      ;Cambio a prescaler de 32, en base a calculos con
    bcf     STATUS,RP0                ;cristal de 4 mhz
    bsf     PORTB,0
    movlw   d'32'                        ;Valor segun calculos para cuenta de 1ms
    movwf   TMR0  
    call    Testeo                 ;Llama a subrutina de testeo
    goto    Tiempo1ms       ;Vuelve a activar si aun PORTA0 esta encendida o
                                          ;busca otra entrada activada

Tiempo10ms
    btfss   PORTA,1              ;Testeo, ¿PORTA1 esta activa?
    goto    Tiempo50ms      ;No, prueba con el siguiente tiempo
    bsf     STATUS,RP0         ;Si, continua
    movlw   b'11010101'     ;Cambio a prescaler de 64, en base a calculos con
    movwf   OPTION_REG      ;cristal de 4mhz
    bcf     STATUS,RP0
    bsf     PORTB,0
    movlw   d'157'                ;Valor segun calculos para cuenta de 10ms
    movwf   TMR0
    call    Testeo                   ;Llama a subrutina de testeo
    goto    Tiempo10ms      ;Vuelve a activar si aun PORTA1 esta encendida o
                                           ;busca otra entrada activada

Tiempo50ms
    btfss   PORTA,2             ;Testeo, ¿PORTA2 esta activa?
    goto    Tiempos            ;No, regresa y prueba con el primer tiempo
    bsf     STATUS,RP0        ;Si, continua
    movlw   b'11010100'     ;Cambio a prescaler de 32, en base a calculos con
    movwf   OPTION_REG      ;cristal de 4mhz
    bcf     STATUS,RP0
    bsf     PORTB,0
    movlw   d'157'              ;Valor segun calculos para cuenta de 10ms
    movwf   TMR0
    call    Testeo                 ;Llama a subrutina de testeo
    goto    Tiempo50ms    ;Vuelve a activar si aun PORTA2 esta encendida o
                                        ;busca otra entrada activada

Testeo
    btfss   INTCON,2       ;¿Se ha desbordado? Observa el registro INTCON,TMR0I
    goto    Testeo            ;No, continua testeando
    bcf     INTCON,2        ;Si, borra registro y apaga LED
    bcf     PORTB,0
    return

END
Este es el mensaje de error, si bien si compila, no hace lo que debe y marca que los operandos no están en el banco 0, justo despues de cambiarme al banco 1 para buscarlo ahí y no en el 0, no entiendo por qué ocurre.
CLEAN SUCCESSFUL (total time: 137ms)
make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory 'C:/Users/LUISALBERTO/Desktop/Practicas PIC/Practica 7.X'
make -f nbproject/Makefile-default.mk dist/default/production/Practica_7.X.production.hex
make[2]: Entering directory 'C:/Users/LUISALBERTO/Desktop/Practicas PIC/Practica 7.X'
"C:\Program Files (x86)\Microchip\MPLABX\v5.30\mpasmx\mpasmx.exe" -q -p16f877a -l"build/default/production/Temporizador.lst" -e"build/default/production/Temporizador.err" -o"build/default/production/Temporizador.o" "Temporizador.asm"
Warning[205] C:\USERS\LUISALBERTO\DESKTOP\PRACTICAS PIC\PRACTICA 7.X\TEMPORIZADOR.ASM 5 : Found directive in column 1. (LIST)
Warning[205] C:\USERS\LUISALBERTO\DESKTOP\PRACTICAS PIC\PRACTICA 7.X\TEMPORIZADOR.ASM 6 : Found directive in column 1. (INCLUDE)
Warning[205] C:\USERS\LUISALBERTO\DESKTOP\PRACTICAS PIC\PRACTICA 7.X\TEMPORIZADOR.ASM 8 : Found directive in column 1. (__CONFIG)
Warning[205] C:\USERS\LUISALBERTO\DESKTOP\PRACTICAS PIC\PRACTICA 7.X\TEMPORIZADOR.ASM 10 : Found directive in column 1. (org)
Warning[203] C:\USERS\LUISALBERTO\DESKTOP\PRACTICAS PIC\PRACTICA 7.X\TEMPORIZADOR.ASM 11 : Found opcode in column 1. (goto)
Message[302] C:\USERS\LUISALBERTO\DESKTOP\PRACTICAS PIC\PRACTICA 7.X\TEMPORIZADOR.ASM 16 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\USERS\LUISALBERTO\DESKTOP\PRACTICAS PIC\PRACTICA 7.X\TEMPORIZADOR.ASM 17 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\USERS\LUISALBERTO\DESKTOP\PRACTICAS PIC\PRACTICA 7.X\TEMPORIZADOR.ASM 27 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\USERS\LUISALBERTO\DESKTOP\PRACTICAS PIC\PRACTICA 7.X\TEMPORIZADOR.ASM 41 : Register in operand not in bank 0. Ensure that bank bits are correct.
Message[302] C:\USERS\LUISALBERTO\DESKTOP\PRACTICAS PIC\PRACTICA 7.X\TEMPORIZADOR.ASM 55 : Register in operand not in bank 0. Ensure that bank bits are correct.
Warning[205] C:\USERS\LUISALBERTO\DESKTOP\PRACTICAS PIC\PRACTICA 7.X\TEMPORIZADOR.ASM 71 : Found directive in column 1. (END)
"C:\Program Files (x86)\Microchip\MPLABX\v5.30\mpasmx\mplink.exe" -p16f877a -w -m"dist/default/production/Practica 7.X.production.map" -z__MPLAB_BUILD=1 -odist/default/production/Practica_7.X.production.cof build/default/production/Temporizador.o
MPLINK 5.09, LINKER
Device Database Version 1.49
Copyright (c) 1998-2011 Microchip Technology Inc.
Errors : 0

MP2HEX 5.09, COFF to HEX File Converter
Copyright (c) 1998-2011 Microchip Technology Inc.
Errors : 0

make[2]: Leaving directory 'C:/Users/LUISALBERTO/Desktop/Practicas PIC/Practica 7.X'
make[1]: Leaving directory 'C:/Users/LUISALBERTO/Desktop/Practicas PIC/Practica 7.X'

BUILD SUCCESSFUL (total time: 2s)
Loading code from C:/Users/LUISALBERTO/Desktop/Practicas PIC/Practica 7.X/dist/default/production/Practica_7.X.production.hex...
Loading completed
 
Tenés el listado de todos los warnings con su número de línea. ¿Los corregiste?

El warning del banco simplemente te avisa que el registro NO está en el banco 0. Lo va a hacer siempre porque el ensamblador no se pone a revisar si ya lo activaste.

¿Que tal una descripción de lo que debe hacer el programa?

Cuando inicia (power on reset) el 16f877 el PORTA está configurado como analógico. Como digital lo lee en 0.

Tenés que insertar:
Inicio
bsf STATUS,RP0 ;Establecer puertos
movlw 6
movwf ADCON1

movlw b'111111'
movwf TRISA
........
 
Última edición:
Todas las advertencias del tipo "Found directive in column 1" quieren decir que esa instrucción NO debe ir en la columna 1. Debes colocarla en otra columna, por ejemplo insertando un tabulador u 8 o 16 espacios. Recuerda que programar en ensamblador tiene mucho de programación de los años 70 donde la POSICIÓN de lo que escribes en la línea es importante.

Una forma sencilla de "cambiar de banco" es usando la macro BANKSEL. Por ejemplo:

Código:
        BANKSEL TRISB
;        bsf     STATUS,RP0          ; Pone a 1 el bit 5 del STATUS. Acceso al Banco 1.
        clrf    TRISB               ; Las líneas del Puerto B se configuran como salidas.

        BANKSEL PORTA
;        bcf     STATUS,RP0          ; Pone a 0 el bit 5 de STATUS. Acceso al Banco 0.
        movf    PORTA,W             ; Lee el Puerto A.
Las macros BANKSEL están haciendo las mismas funciones que las instrucciones comentadas (las que modifican el registro STATUS). Solo tienes que:
  1. acordarte de cambiar de banco cuando sabes que las siguientes instrucciones afectan a registros de un banco diferente a donde te encuentras
  2. usar el nombre de un registro con BANKSEL para hacer el cambio
 
Hola, soy nuevo en esto de programar en lenguaje ensamblador, estoy empezando con algo simple como un led parpadeante, este sería mi código.
Ya lo probé en Proteus y sí funciona, pero a la hora de hacerlo en protoboard no me funciona.
Ya configuré el oscilador externo a 4 MHz (XT)
Uso 2 resistencias, una para el MCLR del PIC de 10K a positivo y una de 1K del pin RB0 al LED y el LED a negativo.
Cargo el programa con un PICkit2, (sí reconoce el PIC)
Estoy usando 1 cristal de cuarzo de 4 MHz y 2 capacitores de 22 pF y están a los pines 9 y 10 (ya sé que el cristal va a los 2 pines y los capacitores cada uno a negativo)
Ya intenté de todo y nos más no, no sé qué estoy haciendo mal.
Código:
list p=18F2510
    #include <p18f2510.inc>

    CONFIG  OSC = XT     ; 4MHZ CRISTAL
    CONFIG MCLRE = ON
    CONFIG BOREN = OFF
    CONFIG PWRT = ON
    CONFIG WDT = OFF
    CONFIG XINST  = OFF ; EXTENDED INSTRUCTIONS
    CONFIG  LVP = OFF
    CONFIG  CP0 = OFF           
   CONFIG  CP1 = OFF           
   CONFIG  CP2 = OFF           
   CONFIG  CP3 = OFF
    CONFIG  CPB = OFF
    ; FIN DE LA CONFIGURACION

 ORG 0x0000       ; Dirección de inicio
GOTO Inicio      ; Salta a la rutina de inicio

Inicio:
    ; Configurar el oscilador interno a 4 MHz
    MOVLW B'01110010'  ; Configurar el oscilador a 4 MHz
    MOVWF OSCCON
    ; Configuración de registros
    CLRF PORTB
    CLRF TRISB       ; Configurar todos los pines de PORTB como salidas
          ; Limpiar el puerto PORTB (apaga todos los pines)

    ; Bucle principal
MainLoop:
   movlw b'00000001'
    movwf PORTB ; Encendemos el LED conectado a RB0
   call Delay ; Mantenemos prendido 500 milisegundos
   movlw b'00000000' ; Apagamos el LED
   movwf PORTB
   call Delay ; Mantenemos apagado 500 milisegundos
    GOTO MainLoop   ; Repetir el bucle

; Subrutina de retardo
Delay:
    ; Configura el retardo según lo necesites
    MOVLW D'250'    ; Número de iteraciones para el retardo

DelayLoop:
    NOP            ; Operación no op (sin efecto) para mantener el retardo
    DECFSZ WREG, F ; Decrementa WREG y salta si es cero
    GOTO DelayLoop ; Repetir el bucle
    RETURN         ; Volver a la llamada

    END
 

Adjuntos

  • Captura de pantalla 2024-05-15 230011.png
    Captura de pantalla 2024-05-15 230011.png
    45.4 KB · Visitas: 19
  • WhatsApp Image 2024-05-15 at 11.01.40 PM.jpeg
    WhatsApp Image 2024-05-15 at 11.01.40 PM.jpeg
    149.7 KB · Visitas: 19
Hola, soy nuevo en esto de programar en lenguaje ensamblador, estoy empezando con algo simple como un led parpadeante, este sería mi código.
Ya lo probé en Proteus y sí funciona, pero a la hora de hacerlo en protoboard no me funciona.
Ya configuré el oscilador externo a 4 MHz (XT)
Uso 2 resistencias, una para el MCLR del PIC de 10K a positivo y una de 1K del pin RB0 al LED y el LED a negativo.
Cargo el programa con un PICkit2, (sí reconoce el PIC)
Estoy usando 1 cristal de cuarzo de 4 MHz y 2 capacitores de 22 pF y están a los pines 9 y 10 (ya sé que el cristal va a los 2 pines y los capacitores cada uno a negativo)
Ya intenté de todo y nos más no, no sé qué estoy haciendo mal.
Código:
list p=18F2510
    #include <p18f2510.inc>

    CONFIG  OSC = XT     ; 4MHZ CRISTAL
    CONFIG MCLRE = ON
    CONFIG BOREN = OFF
    CONFIG PWRT = ON
    CONFIG WDT = OFF
    CONFIG XINST  = OFF ; EXTENDED INSTRUCTIONS
    CONFIG  LVP = OFF
    CONFIG  CP0 = OFF       
   CONFIG  CP1 = OFF       
   CONFIG  CP2 = OFF       
   CONFIG  CP3 = OFF
    CONFIG  CPB = OFF
    ; FIN DE LA CONFIGURACION

 ORG 0x0000       ; Dirección de inicio
GOTO Inicio      ; Salta a la rutina de inicio

Inicio:
    ; Configurar el oscilador interno a 4 MHz
    MOVLW B'01110010'  ; Configurar el oscilador a 4 MHz
    MOVWF OSCCON
    ; Configuración de registros
    CLRF PORTB
    CLRF TRISB       ; Configurar todos los pines de PORTB como salidas
          ; Limpiar el puerto PORTB (apaga todos los pines)

    ; Bucle principal
MainLoop:
   movlw b'00000001'
    movwf PORTB ; Encendemos el LED conectado a RB0
   call Delay ; Mantenemos prendido 500 milisegundos
   movlw b'00000000' ; Apagamos el LED
   movwf PORTB
   call Delay ; Mantenemos apagado 500 milisegundos
    GOTO MainLoop   ; Repetir el bucle

; Subrutina de retardo
Delay:
    ; Configura el retardo según lo necesites
    MOVLW D'250'    ; Número de iteraciones para el retardo

DelayLoop:
    NOP            ; Operación no op (sin efecto) para mantener el retardo
    DECFSZ WREG, F ; Decrementa WREG y salta si es cero
    GOTO DelayLoop ; Repetir el bucle
    RETURN         ; Volver a la llamada

    END
No es lo mio(el asembler) pero... yo pondría el CONFIG MCLRE = ON en CONFIG MCLRE = OFF, te evitas la R de 10K y si esta haciendo bien contacto o no, etc.

La resistencia la bajaría a 330R(si no tenes de ese valor, dos de 1K en paralelo) y vería que el led realmente este conectado como debería y que GND este en esa parte del protoboard(donde conectaste el led).
 
Yo aquí veo un par de cosas:
DelayLoop:
NOP ; Operación no op (sin efecto) para mantener el retardo
DECFSZ WREG, F ; Decrementa WREG y salta si es cero
GOTO DelayLoop ; Repetir el bucle
RETURN ; Volver a la llamada

1) La variable WREG no está definida en el código posteado.
2) Si DECFSZ es similar a la instrucción DJNZ (Decrement and Jump if Not Zero) de otras versiones de Ensamblador, entonces ahí veo un desbordamiento (Overflow) de la variable WREG cuando alcance su máximo valor negativo.

Si nos fijamos, el GOTO vuelve a mandar la ejecución a DECFSZ cuando WREG alcanza cero; entonces ésta se sigue decrementando hasta desbordar. Nunca se llega al RETURN.

En resumen: El GOTO sobra, porque DECFSZ ya itera un bucle.
 
Atrás
Arriba