Autor Tema: Empezando con ASM  (Leído 3117 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado fco1306

  • PIC16
  • ***
  • Mensajes: 128
Empezando con ASM
« en: 08 de Enero de 2015, 18:00:22 »
Hola, buenas.
Estoy comenzando con el asm.
Tengo este programa que simulo bien en proteus
Código: [Seleccionar]

; **** Encabezado ****
list p=16F88
#include <P16F88.INC>
__CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
CLOCK equ 8000000

  PDel0 EQU 0B
  PDel1 EQU 0C
  PDel2 EQU 0D

org 0
bsf status,5 ;pone a uno el bit 5 del registro STATUS (el rp0 para pasar al banco 1)
movlw B'00000' ; carga 00000 en W
movwf TRISA ; puerto a todos salidas pasa w que es 00000 a trisa
movlw B'00000000' ; carga 00000000 en W
movwf TRISB ; puerto b todos salidaS
bcf STATUS,5 ; pone a cero el bit 5 del registro STATUS (el rp0 para pasar al banco 1)
 
BCF PORTB,0 ; ponemos a 0 RB0
BCF PORTB,1 ; ponemos a 0 RB1
BCF PORTB,2 ; ponemos a 0 RB2
BCF PORTB,3 ; ponemos a 0 RB3
BCF PORTB,4 ; ponemos a 0 RB4
BCF PORTB,5 ; ponemos a 0 RB5
BCF PORTB,6 ; ponemos a 0 RB6
BCF PORTB,7 ; ponemos a 0 RB7
 
; luego haremos todos juntos
 
INICIO ; etiqueta
BSF PORTB,0 ; pone a 1 RB0
BSF PORTB,1 ; ponemos a 1 RB1
BSF PORTB,2 ; ponemos a 1 RB2
BSF PORTB,3 ; ponemos a 1 RB3
BSF PORTB,4 ; ponemos a 1 RB4
BSF PORTB,5 ; ponemos a 1 RB5
BSF PORTB,6 ; ponemos a 1 RB6
BSF PORTB,7 ; ponemos a 1 RB7
CALL DEMORA
BCF PORTB,0 ; pone a 0 RB0
BCF PORTB,1 ; ponemos a 0 RB1
BCF PORTB,2 ; ponemos a 0 RB2
BCF PORTB,3 ; ponemos a 0 RB3
BCF PORTB,4 ; ponemos a 0 RB4
BCF PORTB,5 ; ponemos a 0 RB5
BCF PORTB,6 ; ponemos a 0 RB6
BCF PORTB,7 ; ponemos a 0 RB7
CALL DEMORA
GOTO INICIO ; va a inicio
 




DEMORA  movlw     .14       ; 1 set numero de repeticion  (C)
        movwf     PDel0     ; 1 |
PLoop0  movlw     .72       ; 1 set numero de repeticion  (B)
        movwf     PDel1     ; 1 |
PLoop1  movlw     .247      ; 1 set numero de repeticion  (A)
        movwf     PDel2     ; 1 |
PLoop2  clrwdt              ; 1 clear watchdog
        decfsz    PDel2, 1  ; 1 + (1) es el tiempo 0  ? (A)
        goto      PLoop2    ; 2 no, loop
        decfsz    PDel1,  1 ; 1 + (1) es el tiempo 0  ? (B)
        goto      PLoop1    ; 2 no, loop
        decfsz    PDel0,  1 ; 1 + (1) es el tiempo 0  ? (C)
        goto      PLoop0    ; 2 no, loop
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2  clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.



END


Enciende y apaga leds conectados al puerto B.
El problema que cuando lo paso a la electrónica no funciona.
Se puede pensar que el problema está en la electrónica, pero cuando hago el mismo programa en pic simulador ide ,en basic, encender y apagar el puerto b, funciona perfectamente.
No sé si será problema de configuración de fuses o de definición de frecuencia de reloj. Uso uno externo de 8 Mz.
Un saludo

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Empezando con ASM
« Respuesta #1 en: 08 de Enero de 2015, 18:58:00 »
Citar
PDel0 EQU 0B
PDel1 EQU 0C
PDel2 EQU 0D

movwf     PDel0     ; 1 |
movwf     PDel1     ; 1 |
movwf     PDel2     ; 1 |

Veo que estas usando PDelx para designar el lugar de memoria. No se como actua el compilador pero yo siempre exprese los valores decimales como 0x0B .
Por otra parte mirando el datasheet esas posiciones de memoria no son para la creacion de una variable, ya que corresponden a estos registros: PCLATH , INTCON , PIR1
Deberian de ubicarse apartir de 0x20, no se ni como funciono en la simulacion.

Consejo para el programa, si tenes que poner a 0 un registro usas CLRF registro. Ejemplo en tu TRISA / TRISB / PORTB inicial, a no ser que tengas que mover un valor especifico y directamente cargas el valor en W y luego al registro. Tu programa quedaria asi y haria lo mismo.

Código: [Seleccionar]
org 0
bsf status,5 ;pone a uno el bit 5 del registro STATUS (el rp0 para pasar al banco 1)
CLRF TRISA ; puerto a todos salidas pasa w que es 00000 a trisa
CLRF TRISB ; puerto b todos salidaS
bcf STATUS,5 ; pone a cero el bit 5 del registro STATUS (el rp0 para pasar al banco 1)
 
        CLRF PORTB
; luego haremos todos juntos
 
INICIO ; etiqueta
        CLRF PORTB  ; PORTB = 0 , es mas ni hace falta esta instruccion, lo pongo para asegurarme nomas
        DECF PORTB  ; PORTB = 0xFF
CALL DEMORA
        CLRF PORTB  ; PORTB = 0
CALL DEMORA
GOTO INICIO ; va a inicio

Tambien recordar que si queres utilizar el PORTA como salida, debes de setearlo como digital ( en el reset siempre esta como analogico ) esto se logra poniendo a 0 los bits del registro ANSEL, y RA5 es solamente entrada

Desconectado Chaly29

  • Moderador Global
  • DsPIC33
  • *****
  • Mensajes: 4315
Re: Empezando con ASM
« Respuesta #2 en: 09 de Enero de 2015, 16:27:08 »
Hola fco1306, más allá de lo que acaba de comentar KILLERJC, que está correcto (salvo lo de como escribir un numero hexadecimal), es bueno no olvidarse (aunque no se use) asignar la dirección de las interrupciones de la siguiente manera:

Código: ASM
  1. ORG     .0
  2.         bcf     STATUS,RP0                      ;Selecciono el banco 0         
  3.         bcf     STATUS,RP1
  4.         goto    INICIO
  5.  
  6.         ORG     .4
  7.         clrf    INTCON
  8.         return

Los "bcf" son para asegurarme de que arranco en el banco 0. El "clrf INTCON" es por si algún motivo las interrupciones se han activado, por supuesto esto en el caso de que deban estas desactivadas. Y el "return" para que siga normalmente el programa.

La RAM puedes designarlas de la siguiente manera:

Código: ASM
  1. cblock  20
  2.                 PDel0
  3.                 PDel1
  4.                 PDel2
  5.         endc

Por medio de este comando le indicas al compilador que las variables PDel0, PDel1 y PDel2 comience a hubicarlas a partir de la posición 20 hexadecimal. De esta manera te ahorras de escribir y definir todos los "EQU"

También es bueno para que no te tire tantos errores el compilador (errores sin sentido) colocar debajo de la declaración del micro a usar y la declaración de las librerías incluidas la siguiente instrucción:

Código: ASM
  1. ; **** Encabezado ****
  2.  
  3.  
  4.         list p=16F88
  5.         include <P16F88.INC>
  6.         ERRORLEVEL      -302
  7.  
  8.  
  9.         __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
  10.         __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF
  11.         CLOCK equ 8000000
  12.  
  13. ;-----------------------------------------------------------------------------------------------------------
  14. ; Definiciones de la memoria RAM
  15.  
  16.         cblock  20
  17.                 PDel0
  18.                 PDel1
  19.                 PDel2
  20.         endc
  21.  
  22. ;-----------------------------------------------------------------------------------------------------------
  23.  
  24.         ORG     .0              ; Vector del inicio/reset
  25.         bcf     STATUS,RP0      ;Selecciono el banco 0         
  26.         bcf     STATUS,RP1
  27.         goto    INICIO
  28.  
  29.         ORG     .4              ; Vector de interrupciones
  30.         clrf    INTCON          ; Borro todas las interrupciones
  31.         return
  32.  
  33. ; Programa principal
  34.  
  35. INICIO ; etiqueta
  36.         clrf    INTCON          ; Borro todas las interrupciones
  37.         bsf     STATUS,RP0      ; pone a uno el bit 5 del registro STATUS (el rp0 para pasar al banco 1)
  38.         movlw   B'00000'        ; carga 00000 en W
  39.         movwf   TRISA           ; puerto a todos salidas pasa w que es 00000 a trisa
  40.         movlw   B'00000000'     ; carga 00000000 en W
  41.         movwf   TRISB           ; puerto b todos salidas
  42.         bcf     STATUS,RP0      ; pone a cero el bit 5 del registro STATUS (el rp0 para pasar al banco 1)
  43.  
  44.         clrf    PORTA           ; Borro todo el puerto A
  45.         clrf    PORTB           ; Borro todo el puerto B
  46.  
  47. RETORNO
  48.         movlw   B'00000000'             ; Borro puerto B
  49.         movwf   PORTB
  50.         call    DEMORA
  51.         movlw   B'11111111'             ; Seteo puerto B
  52.         movwf   PORTB
  53.         call    DEMORA
  54.         goto    RETORNO
  55.  
  56. ;-------------------------------
  57. ; Rutina de demora
  58.  
  59. DEMORA  movlw   .14             ; 1 set numero de repeticion  (C)
  60.         movwf   PDel0           ; 1 |
  61. PLoop0  movlw   .72             ; 1 set numero de repeticion  (B)
  62.         movwf   PDel1           ; 1 |
  63. PLoop1  movlw   .247            ; 1 set numero de repeticion  (A)
  64.         movwf   PDel2           ; 1 |
  65. PLoop2  clrwdt                  ; 1 clear watchdog
  66.         decfsz  PDel2,f         ; 1 + (1) es el tiempo 0  ? (A)
  67.         goto    PLoop2          ; 2 no, loop
  68.         decfsz  PDel1,f         ; 1 + (1) es el tiempo 0  ? (B)
  69.         goto    PLoop1          ; 2 no, loop
  70.         decfsz  PDel0,f         ; 1 + (1) es el tiempo 0  ? (C)
  71.         goto    PLoop0          ; 2 no, loop
  72. PDelL1  goto    PDelL2          ; 2 ciclos delay
  73. PDelL2  clrwdt                  ; 1 ciclo delay
  74.         return                  ; 2+2 Fin.
  75.  
  76. ;-----------------------------------------------------------------------------------------------------------
  77.         END

Espero te sea de ayuda.

Para escribir valores en .asm por ejemplo:
                                                                                               cero
        30       =   .48    =      H'30'      =  D'48'  =  B'00110000'  =   A'0'
hexadecimal   decimal   hexadecimal   decimal        binario         ASCII2

Todos son el mismo número, pero escrito en diferentes nominaciones

Un saludo.

Atte. CARLOS.

La teoría es cuando se sabe todo y nada funciona. La práctica es cuando todo funciona y nadie sabe por qué.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Empezando con ASM
« Respuesta #3 en: 09 de Enero de 2015, 20:52:19 »
Gracias chaly, me acostumbre al C y ver un numero sin 0x ya me hace pensarlo como si fuera decimal a pesar que se que uno lo puede definir ( .XX )

Código: ASM
  1. ORG     .4
  2.         clrf    INTCON
  3.         return

No deberia ser RETFIE ?

Desconectado Chaly29

  • Moderador Global
  • DsPIC33
  • *****
  • Mensajes: 4315
Re: Empezando con ASM
« Respuesta #4 en: 09 de Enero de 2015, 23:40:48 »
Hola KILLERJC, jajaja muy interesante, a mi me está pasando exactamente lo mismo con el C. Muy acostumbrado al .asm.

No, no debe ser RETFIE, en este caso no, porque precisamente estamos queriendo que las interrupciones estén desactivadas. El RETFIE lo que hace es poner en 1 el bit 7 del INTCON que sería el "GIE: Global Interrupt Enable bit", cuando se produce una interrupción el micro automáticamente coloca ese bit en "0" y desactiva todas las interrupciones, cuando completa la rutina de la interrupción debes usar el RETFIE para retornar al programa principal y activar nuevamente todas las interrupciones.

Entonces y en este caso que no queremos las interrupciones activas, y por si algún error a activado las interrupciones usamos:

Código: ASM
  1. ORG     .4      ; Vector de interrupciones
  2.         clrf    INTCON  ; Desactivamos todas las interrupciones (bastaría con poner a cero el bit 7 GIE)
  3.         return          ; Retornamos al programa como si nada hubiese pasado

Y es por esto que en este caso no se usa RETFIE.

Un saludo.

Atte. CARLOS.

La teoría es cuando se sabe todo y nada funciona. La práctica es cuando todo funciona y nadie sabe por qué.

Desconectado fco1306

  • PIC16
  • ***
  • Mensajes: 128
Re: Empezando con ASM
« Respuesta #5 en: 13 de Enero de 2015, 18:37:59 »
 :) :)Muchas gracias por vuestra ayuda.
La verdad es que ha sido un error de principiante. Acostumbrado al pic simulator que no tienes que indicar la posición de memoria y me está costando comenzar con el asm.
Una duda que tengo desde hace tiempo es si sirve de algo indicar al compilador la frecuencia del cristal que usas. Si la expresión
CLOCK equ 8000000 sirve de algo o como he visto en otros sitios xtal equ 8000000
Un saludo