No funciona DECFSZ 16F628a

#1
Hola. ¿Cómo están? Llevo dos días buscando alternativas y soluciones en la web para un problema que me tiene muy mal.
Tal vez puedan ayudarme a encontrar qué estoy haciendo tan mal.
Necesito transmitir 8 bits por los pines de un PIC16F628A y para ello tengo la siguiente rutina:
Código:
#INCLUDE <P16F628A.INC>         ; Lista de etiquetas de microchip

__CONFIG    _CP_OFF & _PWRTE_OFF & _WDT_ON & _XT_OSC &_LVP_OFF

INT_VAR                UDATA_SHR
TOTALBIT            RES 1; EQU    0x16

Transmitir            ;Rutina de Transmisión
    movwf    DatoTX        ; Cargo el valor que viene en W para transmitir
    clrwdt
    bsf        PORTB,2        ; Habilitar transmisión RS485 DE=1 RE=1
    bcf        PORTB,1        ; Bajo el nivel para indicar inicio de transmisión   

    movlw    d'8'               ; Para leer los 8 bits
    movwf    TOTALBIT
IniTX
    Call    DEMORA50    ; Espero 2 ciclos para
    Call    DEMORA50    ; indicar bit de inicio
CicloTX
    bsf        PORTB,3        ; transmitir un UNO(LED)
    Call    DEMORA250    ; Llamar al retardo entre bits   
    bcf        PORTB,3        ; transmitir un CERO(LED)   
    Call    DEMORA250    ; Llamar al retardo entre bits
    rrf        DatoTX        ; Rotar a la derecha el byte (en CARRY esta el primer bit)
    btfsc    STATUS,C    ; Carry es cero?
    goto    EsUNO        ; No,es un uno
EsCERO
    bcf        PORTB,1        ; transmitir un CERO(DATO)
    clrwdt
    Goto    SigBit
EsUNO
    bsf        PORTB,1        ; transmitir un UNO(DATO)
    clrwdt
    Goto    SigBit

SigBit
    decfsz    TOTALBIT,1
    goto    CicloTX           ; Faltan bits de transmitir
    bsf        PORTB,1        ; transmitir un UNO: linea en espera
    bcf        PORTB,2        ; Deshabilitar transmisión RS485, poner "en escucha"
    clrwdt
    bcf        PORTB,3       ; Apagar led testigo de Tx
    bsf        PORTA,1       ; Encender relé

    RETURN
Llamo a la rutina de la siguiente manera:
Código:
movlw 0xAA     ;Dato a transmitir es AA
Call Trasnsmitir
Uso esta parte para darme cuenta de que no decrementa correctamente contando los destellos del led que suman 256 antes de salir (encender el relé)
Código:
  bsf        PORTB,3        ; transmitir un UNO(LED)
  Call    DEMORA250    ; Llamar al retardo entre bits   
  bcf        PORTB,3        ; transmitir un CERO(LED)   
  Call    DEMORA250    ; Llamar al retardo entre bits
Debería contar 8 parpadeos del led y luego salir, pero cuenta hasta 256 y recién sale.
Las rutina de demora funcionan bien porque hice un test con un led y no fallan (la de 50 y la de 250 funcionan bien).
Pero el descuento de TOTALBIT no funciona.
También probé haciendo DECF TOTALBIT,1 y luego BTFSS STATUS,Z pero no funciona.
En la simulación con MPLAB no falla pero cuando lo paso al PIC ¡No funciona!
Cambié dos PIC pensando que podrían tener una falla interna.
Cambié de lugar la rutina para que el compilador la asigne a distintas porciones de memoria.
Ya no sé qué más probar. Me estoy volviendo loco. o_O

¿Alguna idea?

Muchas gracias.
Disculpen, no sé subir el código para que se pueda leer, la verdad que así como está no te dan ni ganas de leer.
 
#2
Hola, me llamo la atencion tu inconveniente y me propuse probarlo.
1ero: Cuidado con los nombres cuando llamas a la subrutina Transmitir. Pusiste Trasnsmitir.
2do: Como no tengo el codigo completo, rellene y modifique el que subiste para poder trabajarlo. Inicialmente no use el WDT y esas definiciones de variables me parecieron raras asi que las cambie.
3ero: Reemplaze tus retardos por uno solo de 1seg para poder verlo.
4to: Use un cristal de 4MHz
5to: Supuse que RA1,RB1,RB2 y RB3 son salidas(me gustaria si podes subir el diagrama electrico del RS485 por curiosidad)
6to: A la instrucción RRF le faltaba un parámetro, igualmente no afectaba en nada(RRF DATOTX,1)
7to: Por las dudas inicio la subrutina y pongo en cero el CARRY, no cambia mucho...
Haciendo esto, envia los 8 bits y queda B1 y A1 en 1. Lo debuggee y anda, lo simule en PROTEUS y anda y lo arme con unos LEDs y anda....se ven las transiciones.
Dejo de andar cuando le habilite el WDT, ya en la simulación me cortaba el programa, no se si es realmente necesario para tu trabajo...
Fijate si te sirve de algo...
Código:
    list    P=PIC16F628A
    #include"P16F628A.inc"

;__CONFIG    _CP_OFF & _PWRTE_OFF & _WDT_ON & _XT_OSC &_LVP_OFF
;Lo voy a hacer cona la interfaz del MPLAB, CON EL wdt DESHABILITADO
;la palabra de configuracion es 3F61

;INT_VAR                UDATA_SHR
;TOTALBIT            RES 1; EQU    0x16
;No se que es esto???
DATOTX        EQU    020H
TOTALBIT    EQU    021H

;REGISTROS PARA EL RETARDO
CONT3    EQU    022H
CONT2    EQU    023H
CONT1    EQU    024H

    ORG    0
        ;DESHABILITO LOS COMPARADORES DEL PUERTOA
        CLRF    PORTA
        MOVLW    007H
        MOVWF    CMCON

        ;PASO AL BANCO 1 PARA DEFINIR LAS E/S EN LOS TRIS
        BSF        STATUS,RP0
        MOVLW    0FDH
        MOVWF    TRISA
        MOVLW    0F1H
        MOVWF    TRISB
        BCF        STATUS,RP0
        ;PASO AL BANCO 0

        MOVLW    0AAH     ;Dato a transmitir es AA
        CALL    TRANSMITIR

FIN        GOTO    FIN;BUCLE INFINITO FINAL

TRANSMITIR            ;Rutina de Transmisión
        MOVWF    DATOTX        ; Cargo el valor que viene en W para transmitir
        ;CLRWDT
        BSF        PORTB,2        ; Habilitar transmisión RS485 DE=1 RE=1
        BCF        PORTB,1        ; Bajo el nivel para indicar inicio de transmisión   

        MOVLW    .8               ; Para leer los 8 bits
        MOVWF    TOTALBIT

        BCF        STATUS,C;pongo en 0 el carry antes POR LAS DUDAS

INITX
        ;CALL    DEMORA50    ; Espero 2 ciclos para
        ;CALL    DEMORA50    ; indicar bit de inicio
        CALL    RETARDO1SEG
CICLOTX
        BSF        PORTB,3        ; transmitir un UNO(LED)
        ;CALL    DEMORA250    ; Llamar al retardo entre bits
        CALL    RETARDO1SEG
        BCF     PORTB,3        ; transmitir un CERO(LED)   
        ;CALL    DEMORA250    ; Llamar al retardo entre bits
        CALL    RETARDO1SEG
        RRF        DATOTX,1        ; Rotar a la derecha el byte (en CARRY esta el primer bit)
        BTFSC   STATUS,C    ; Carry es cero?
        GOTO    ESUNO        ; No,es un uno
ESCERO
           BCF        PORTB,1        ; transmitir un CERO(DATO)
        ;CLRWDT
        GOTO    SIGBIT
ESUNO
        BSF        PORTB,1        ; transmitir un UNO(DATO)
        ;CLRWDT
        GOTO    SIGBIT

SIGBIT
        DECFSZ        TOTALBIT,1
        GOTO        CICLOTX           ; Faltan bits de transmitir
        BSF            PORTB,1        ; transmitir un UNO: linea en espera
        BCF            PORTB,2        ; Deshabilitar transmisión RS485, poner "en escucha"
        ;CLRWDT   
        BCF            PORTB,3       ; Apagar led testigo de Tx
        BSF            PORTA,1       ; Encender relé

        RETURN

RETARDO1SEG
        MOVLW    .10
        MOVWF    CONT3
TRES    MOVLW    .200
        MOVWF    CONT2
DOS        MOVLW    .165
        MOVWF    CONT1
UNO        DECFSZ    CONT1,1
        GOTO     UNO
        DECFSZ    CONT2,1
        GOTO     DOS
        DECFSZ    CONT3,1
        GOTO     TRES
        RETURN       
    

    END
 

Temas similares


Arriba