Autor Tema: Migrar reloj de PIC16F84a a PIC16f628a  (Leído 3070 veces)

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

Desconectado Virginia

  • PIC10
  • *
  • Mensajes: 2
Migrar reloj de PIC16F84a a PIC16f628a
« en: 18 de Junio de 2016, 12:11:06 »
Estoy tratando de migrar el codigo y no puedo, alguien me ayuda? :(
Les dejo el codigo

;*************************************************************
; RELOJ DE 12 HORAS
;*************************************************************

          LIST P=PIC16F628A               ;Procesador utilizado.
#INCLUDE <P16F628A.INC>          ; Lista de etiquetas de microchip

      __CONFIG _LVP_OFF & _MCLRE_OFF & _BODEN_OFF & _CP_OFF & _PWRTE_ON & _WDT_ON & _INTOSC_OSC_NOCLKOUT

W       EQU 0
F       EQU 1
Z       EQU 3
PORTB   EQU 06
STATUS  EQU 03
INTCON  EQU 0BH
TMR0    EQU 01H
PCL     EQU 02H
FRAC_INI   equ      D'12'   ; Constante para inicio cuenta de fracciones de segundo
SEGS_INI   equ      D'196'   ; Constante para inicio cuenta de segundos
MINS_INI   equ      D'196'   ; Constante para inicio cuenta de minutos
HORS_INI   equ      D'244'   ; Constante para cuenta de horas
HORS_12H   equ      D'243'   ; Constante para cuenta de horas

ADJMIN      equ   D'9'      ; Número de "frac_sec" que se necesita sumar cada minuto
                       ; para ajustar el tiempo
ADJHOR      equ   D'34'      ; Número de "frac_sec" que se necesita restar cada hora
                       ; para ajustar el tiempo
ADJDIA      equ   D'3'      ; Número de "frac_sec" que se necesita sumar cada 12 horas
                       ; para ajustar el tiempo

; Activación de RB1-3 para las entradas de los pulsadores
PULSADOR   equ   B'00001110'   ; RB1, RB2 y RB3

; Asignación de banderas. Los pulsadores activos proporcionan un "1"
CHG      equ   H'03'          ; Indica que se ha activado un pulsador o que es necesario
                       ; actualizar los valores de la hora que tienen que mostrarse
                       ; en los displays
PSEG      equ   H'04'      ; Pulsador A, modo segundero.
PMIN      equ   H'05'      ; Pulsador B, avance rápido minutos.
PHOR      equ   H'06'      ; Pulsador C, avance rápido horas.
P_ON      equ   H'07'      ; Un pulsador ha sido activado

DSPOFF      equ   B'11111111'       ; Displays apagados (PORTA) gfedcbap
CERO      equ   B'01111110'     ; 01111110
UNO         equ   B'00001100'      ; 00001100
DOS         equ   B'10110110'      ; 10110110
TRES      equ   B'10011110'      ; 10011110
CUATRO      equ   B'11001100'      ; 11001100
CINCO      equ   B'11011010'      ; 11011010
SEIS      equ   B'11111010'      ; 11111010
SIETE      equ   B'00001110'      ; 00001110
OCHO      equ   B'11111110'      ;11111110
NUEVE      equ   B'11011110'      ; 11011110
SEGM_OFF   equ   H'00'      ; Todos los segmentos apagados. Separador entre horas y minutos apagado (RB0).
frac_sec   equ   H'0C'      ; Fracciones de segundo (1/244)
segundos   equ   H'0D'      ; Segundos
minutos      equ   H'0E'      ; Minutos
horas      equ   H'0F'      ; Horas
conta1      equ   H'10'      ; Variable 1 para bucle contador
display      equ   H'11'      ; Indicador de display que debe actualizarse
digito1      equ   H'12'      ; Display unidad de minuto / unidad de segundo
digito2      equ   H'13'      ; Display decena de minuto / decena de segundo
digito3      equ   H'14'      ; Display unidad de hora
digito4      equ   H'15'      ; Display decena de hora
banderas   equ   H'16'      ; Banderas; 3-CHG, 4-PSEG, 5-PMIN, 6-PHOR, 7-P_ON

;**************************************************************
    ORG   0x00         ;Vector de Reset
   goto   INICIO
   org   0x05      ;Salva el vector de interrupción
;**************************************************************

; SUBRUTINAS
;**************************************************************
CODIGO_7S            ; Devuelve el código 7 segmentos
   addwf   PCL,F
   retlw   CERO
   retlw   UNO
   retlw   DOS
   retlw   TRES
   retlw   CUATRO
   retlw   CINCO
   retlw   SEIS
   retlw   SIETE
   retlw   OCHO
   retlw   NUEVE

;**************************************************************
; Comienzo del programa
;**************************************************************
;
INICIO
;  Configurar puertos como salidas, blanquear display
   bsf   STATUS,RP0              ; Activa el banco de memoria 1.
    clrf   TRISB            ; Las líneas del Puerto B se configuran como salida.
   movlw   B'00000111'          ; Configuración del registro Option, RB Pull Up desconectadas
   movwf   OPTION_REG          ; TMR0 en modo temporizador (uso de pulsos de reloj internos, Fosc/4)
                           ; prescaler TMR0 a 1:16
   bcf   STATUS,RP0              ; Activa el banco de memoria 0.
    clrf   PORTB
;
; Establecer estados iniciales de las salidas
   movlw   DSPOFF
   movwf   PORTA         ; Apaga los displays
   movlw   B'00000001'      ; Todos los segmentos apagados. Separador
   movwf   PORTB         ; entre horas y minutos encendido (RB0).
;
; Inicialización de variables:
   movlw   H'01'
   movwf   TMR0         ; Pone 01h en TMR0
   movlw   B'11111110'
   movwf   display         ; Inicia display seleccionando decena de hora
   movlw   CERO
   movwf   digito1         ; Aparecerá un "0" en el display unidad de minutos
   movwf   digito2         ; Aparecerá un "0" en el display decena de minutos
   movlw   DOS
   movwf   digito3         ; Aparecerá un "2" en el display unidad de hora
   movlw   UNO
   movwf   digito4         ; Aparecerá un "1" en el display decena de hora
   movlw   B'00000000'
   movwf   banderas      ; Coloca todas las banderas a 0
;
; Inicia las variables de tiempo
   movlw   FRAC_INI
   movwf   frac_sec      ; 12
   movlw   SEGS_INI
   movwf   segundos      ; 196
   movlw   MINS_INI
   movwf   minutos         ; 196
   movlw   D'255'
   movwf   horas         ; Las horas comienzan con 12 por lo que "horas" ha de ser 255
;
;**************************************************************
PRINCIPAL ; Rutina principal cíclica
;**************************************************************
;
;  Esperar al desbordamiento de TMR0
TMR0_LLENO
;   4 MHz -> 1 MHz
;   1.000.000 Hz / 16 = 62.500 Hz
;   62.500 Hz / 256 = 244,140625 Hz -> 4,096 ms
   movf   TMR0,W
   btfss   STATUS,Z      ; TMR0 cuenta libremente para no perder ciclos del reloj
               ; escribiendo valores
   goto   TMR0_LLENO
;
; Se ha desbordado TMR0 y se han contado 256.
; Tarda en desbordarse 4.096 ciclos de reloj, 4,096 ms
   incfsz   frac_sec,F      ; Se añade 1 a frac_sec
   goto   COMPROBAR_CHG      ; Se comprueba el estado de ?CHG? por si se ha activado
               ; algún pulsador o es necesario actualizar los valores
               ; de la hora que tienen que mostrarse en los displays
;
; Se ha desbordado frac_sec y se han contado 244 "frac_sec", 1 segundo.
; Tarda en desbordarse 4.096 ciclos de reloj, 4,096 ms * 244 = 999,424 ms
; Al no consegirse exactamente 1 segundo sino 0,999424 s, luego se necesitan ajustes
   bsf   PORTB,0         ; Se activa separador horas-minutos
   movlw   FRAC_INI
   movwf   frac_sec      ; Restaura la variable frac_sec para la próxima vuelta
;
COMPROBAR_PUL   ; Comprueba variables pulsadores
   btfss   banderas,P_ON      ; Si no se ha pulsado nada, se pasa a INC_HORA
   goto   INC_HORA      ; Incrementa segundos, minutos y horas. Ajustes y ?CHG? a 1
   btfsc   banderas,PSEG      ; Comprobar si se ha pulsado PSEG (Pulsador segundos)
   goto   INC_HORA      ; Se ha pulsado PSEG, (Pul A) y se mostrarán
               ; los segundos en el display
;
PONER_RELOJ
   movlw   SEGS_INI      ; 196d
   movwf   segundos      ; Inicia los segundos cuando se pone el reloj en hora
;
PONER_MINUTOS
   btfss   banderas,PMIN      ; Comprobar si se ha pulsado PMIN (Pulsador minutos)
   goto   PONER_HORAS      ; No se ha pulsado PMIN, ir a comprobar estado de PHOR
   movlw   H'AF'         ; 175d
   movwf   frac_sec          ; Avance rápido del tiempo cuando se ajustan minutos frac_sec = 175
   incfsz   minutos,F      ; Incrementar los minutos
   goto   PONER_HORAS
   movlw   MINS_INI
   movwf   minutos         ; Iniciar minutos si al incrementar se han desbordado
;
PONER_HORAS
   btfss   banderas,PHOR      ; Comprobar si se ha pulsado PHOR (Pulsador horas)
   goto   OBTENER_H_M      ; No se ha pulsado PHOR, no se cambian las horas
   movlw   H'7F'         ; 127d
   movwf   frac_sec      ; Avance rápido del tiempo cuando se ajustan horas frac_sec = 127
   incfsz   horas,F         ; Incrementar la hora
   goto   OBTENER_H_M
   movlw   HORS_INI
   movwf   horas         ; Iniciar la hora si al incrementar se han desbordado
   goto   OBTENER_H_M
;
INC_HORA            ; Incrementar segundos, minutos y horas
               ; Ajustes cada minuto, hora y 12 horas
   bsf   banderas,CHG      ; Se especifica que se ha producido un cambio
;
   incfsz   segundos,F       ; Como ha pasado un segundo se incrementa "segundos"
   goto   COMPROBAR_CHG
   movlw   SEGS_INI         ; Se ha desbordado "segundos" y se reestablece el valor inicial
   movwf   segundos      ; de "segundos" para la próxima vuelta
;
   movlw   ADJMIN         ; Se resta 9 a "frac_sec" cada minuto para los ajustes de tiempo
   subwf   frac_sec,F       ; El minuto será 9 "frac_sec" más largo
;
   incfsz   minutos,F        ; Se añade 1 minuto
   goto   COMPROBAR_CHG
   movlw   MINS_INI      ; Se ha desbordado "minutos" y Se reestablece el valor inicial
   movwf   minutos           ; de "minutos" para la próxima vuelta
;
   movlw   ADJHOR         ; Se suma 34 a "frac_sec" cada hora para los ajustes de tiempo
   addwf   frac_sec,F      ; La hora será 34 "frac_sec" más corta
;
   incfsz   horas,F           ; Se añade 1 hora
   goto   COMPROBAR_CHG
   movlw   HORS_INI      ; Se ha desbordado "horas" y se reestablece el valor inicial
   movwf   horas           ; de "horas" para la próxima vuelta
   movlw   ADJDIA         ; Se resta 3 a "frac_sec" cada 12 horas para los ajustes de tiempo
   subwf   frac_sec,F       ; Cada 12 horas se añadirán 3 "frac_sec"
;
; Se comprueba el estado de ?CHG? por si se ha activado
; algún pulsador o es necesario actualizar los valores
; de la hora que tienen que mostrarse en los displays
; Se actualiza hora, displays y pulsadores cada 4,096 ms (244 veces por segundo)
COMPROBAR_CHG
   btfss   banderas,CHG      ; Si no se han activado pulsadores ni ha cambiado la hora
    goto   DISPLAY_PUL      ; se salta a DISPLAY_PUL, que principalmente refresca uno de los
               ; displays cada vez que se accede a ella y escanea pulsadores.
;
COMPROBAR_SEG            ;  Se comprueba si se activo el pulsador de segundos (Pul A)
               ; para mostrar los segundos en el display
   btfss   banderas,PSEG
   goto   OBTENER_H_M      ; No estaba pulsado PSEG
   movlw   H'00'         ; Se mostrarán los segundos en el display de minutos
   movwf   digito2         ; Variables "digito2" a 0
   movwf   digito3         ; Variables "digito3" a 0
   movwf   digito4         ; Variables "digito4" a 0
   movlw   SEGS_INI
   subwf   segundos,W
   movwf   digito1         ; Se guarda temporalmente el número de segundos en ?digito1?
   goto   DIV_DIGITOS
;
OBTENER_H_M
   movlw   HORS_12H
   subwf   horas,W
   movwf   digito3         ; La variable digito3 almacena temporalmente el valor para las horas
   movlw   MINS_INI
   subwf   minutos,W
   movwf   digito1         ; La variable digito1 almacena temporalmente el valor para los minutos
;
DIV_DIGITOS            ; Divide los segundos o los minutos y las horas en dígitos independientes
               ; ejemplo, [14] lo pasa a [1]-[4]
   movlw   H'00'
   movwf   digito4         ; Se ponen a cero las posiciones de las decenas
   movwf   digito2         ; para el caso de que no se incrementen
   movlw   H'02'
   movwf   conta1         ; Bucle para convertir cada número (segundos o minutos y horas)
   movlw   digito1         ; Dirección de digito1 en FSR para usar INDF
   movwf   FSR         ; La primera vez, FSR = digito1 (minutos o segundos) y la segunda vez FSR = digito3 (horas)
   goto   LOOP
;
LOOP2   ; Este LOOP se utiliza para las horas después de trabajar con los minutos o los segundos
   movlw   digito3
   movwf   FSR
;
LOOP   ; Este LOOP se utiliza primero para los minutos o los segundos y después para las horas
   movlw   D'10'         ; Averiguar cuantas "decenas" hay en el número
   subwf   INDF,F         ; En cada LOOP restar 10 al número
   btfsc   STATUS,C           ; Se comprueba "C", que se pone a 1 si en la resta no se ha
               ; producido llevada
   goto   INC_DECENAS         ; C = 1 por lo que se añade 1 a la posición de las decenas
   addwf   INDF,F         ; C = 0, no se incrementan las decenas y se suma 10 para restaurar
               ; las unidades
   goto   PROX_NUM
;
INC_DECENAS
   incf   FSR,F         ; El puntero apunta a la primera posición de las decenas
   incf   INDF,F         ; Se añade 1 a las decenas
   decf   FSR,F           ; Se restaura el valor de INDF para apuntar al número
   goto    LOOP         ; para la próxima resta hasta que se termine
               ; Con "goto LOOP" se vuelve a comprobar si es necesario
               ; sumar uno a la decena cada vez que esta se ha incrementado
;
PROX_NUM            ; Próximo número, primero ha sido segundos o minutos y luego horas
   decfsz   conta1,F
   goto   LOOP2
;
CONVER_COD_7S            ; Convierte cada dígito a código 7 segmentos para los displays
   movlw   digito1
   movwf   FSR         ; Coloca la dirección del primer digito (digito1) en FSR
   movlw   H'04'
   movwf   conta1         ; Prepara la variable conta1 para el bucle de los 4 displays
;
PROX_DIGITO
   movf   INDF,W         ; Obtener el valor de la variable "digito" actual
   call   CODIGO_7S      ; LLamar a la rutina de conversión a código 7 segmentos
   movwf   INDF         ; Colocar en la variable "digito" el código 7 segmentos devuelto
   incf   FSR,F         ; Incremente INDF para el próximo "digito"
   decfsz   conta1,F      ; Permitir que conta1 de sólo 4 vueltas
   goto   PROX_DIGITO
;
;BORRAR_CERO            ; Si hay un cero en el display de las decenas de hora
               ; no se muestra (borrado de los ceros a la izquierda)
;   movlw   CERO
;   subwf   digito4,W
;   btfss   STATUS,Z
;   goto   BORRAR_CERO_SEG
;   movlw   SEGM_OFF
;   movwf   digito4
;
BORRAR_CERO_SEG
   btfss   banderas,PSEG      ; Si está pulsado PSEG no se muestra nada en el display de la
   goto   DISPLAY_PUL      ; posición de la unidad de hora.
   movlw   SEGM_OFF      ; Contando con BORRAR_CERO, esto significa que sólo se
   movwf   digito3         ; mostrarán los segundos.
   movwf   digito4
;
DISPLAY_PUL            ; Se borran los bits de flag para actualizar su estado
               ; Escanea pulsadores, si alguno está pulsado se pone a 1
               ; el pulsador que le correspoda así como "P_ON" y "CHG"
               ; Muestra los dígitos correspondientes a los segundos o a
               ; los minutos y horas en el display que corresponda.
;
   movlw   B'00000000'
   movwf   banderas      ; Se borran los bits de flag para actualizar su estado
;
   ; Apagar los displays
   movlw   DSPOFF
   movwf   PORTA
;
   ; Apagar los segmentos respetando separador horas-minutos
   movlw   SEGM_OFF      ; Respeta valor RB0
   xorwf   PORTB, w
   andlw   B'11111110'      ;  Poner "1" el la posición del bit a copiar
   xorwf   PORTB, f
;
   ; Configurar los bits 1, 2 y 3 de PORTB como entrada
   bsf   STATUS,RP0      ; Activa el banco 1.
   movlw   PULSADOR
   movwf   TRISB         ; Se configuran los bits 1, 2 y 3 de PORTB como entrada
   bcf   STATUS,RP0      ; Activa el banco 0.
   nop            ; Las instrucciones "nop" pueden no ser necesarias.
   nop            ; En principio proporcionan el tiempo suficiente para que los
   nop            ; estados anteriores de las salidas se actualicen a través de
   nop            ; las resistencias de 10K (y de las de 820 ohm si está activado
   nop            ; algún pulsador) antes de leer las patillas del puerto.
;
COMPROBAR_PSEG   ; Se comprueba Pulsador PSEG
   btfss   PORTB,1
   goto   COMPROBAR_PMIN
   bsf   banderas,CHG
   bsf   banderas,PSEG
   bsf   banderas,P_ON
;
COMPROBAR_PMIN   ; Se comprueba Pulsador PMIN
   btfss   PORTB,2
   goto   COMPROBAR_PHOR
   bsf   banderas,CHG
   bsf   banderas,PMIN
   bsf   banderas,P_ON
;
COMPROBAR_PHOR   ; Se comprueba Pulsador PHOR
   btfss   PORTB,3
   goto   ACTIVAR_SEGM
   bsf   banderas,CHG
   bsf   banderas,PHOR
   bsf   banderas,P_ON
;
ACTIVAR_SEGM   ; Se coloca en PORTB el valor para los segmentos del display actual
   bsf   STATUS,RP0      ; Activa el banco 1.
   movlw   H'00'
   movwf   TRISB         ; Puerto B como salida
   bcf   STATUS,RP0      ; Activa el banco 0.
;
   ; Se determina que display debe actualizarse, es decir, que dato debe
   ; presentarse en el puerto B y se establece el siguiente display
   btfss   display,0      ; Si es el primer display (decena de hora) tomar digito4
   movf   digito4,W
   btfss   display,1      ; Si es el segundo display (unidad de hora) tomar valor digito3
   movf   digito3,W
   btfss   display,2      ; Si es el tercer display (decena de min/seg) tomar valor digito2
   movf   digito2,W
   btfss   display,3      ; Si es el cuarto display (unidad de min/seg) tomar valor digito1
   movf   digito1,W
;
   ; Entregar el valor en puerto B y respetar valor RB0
   xorwf   PORTB, w
   andlw   B'11111110'      ;  Poner "1" el la posición del bit a copiar
   xorwf   PORTB, f
;
   btfsc   frac_sec,7      ; Establecer el separador de horas y minutos a un 50%
   bcf   PORTB,0         ; del ciclo (1/2 segundo encendido, 1/2 segundo apagado)
;
   movf   display,W      ; Tomar el valor del display que debe habilitarse
   movwf   PORTA         ; Cada display se ?enciende? con una cadencia de 244 Hz / 4 = 61 Hz
   ; Cada display se ?enciende? con una cadencia de 244 Hz / 4 = 61 Hz
   ; En este momento están encendidos los segmentos correspondientes
;
   rlf   display,F      ; Rota display 1 bit a la próxima posición
   bsf   display,0      ; Asegura un 1 en la posición más baja de display (luego se hará 0 si es necesario)
   btfss   display,4      ; Comprueba si el último display fue actualizado
   bcf   display,0      ; Si lo fue, se vuelve a habilitar el primer display
               ; La variable display va cambiando:
               ;   1111 1101
               ;   1111 1011
               ;   1111 0111
               ;   1110 1110
               ;   1101 1101
               ;   1011 1011
               ;   0111 0111
               ;   1110 1110
               ; Sólo valen los 4 bits menos significativos
;
   goto    PRINCIPAL      ; Volver a realizar todo el proceso
;
    END

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Migrar reloj de PIC16F84a a PIC16f628a
« Respuesta #1 en: 18 de Junio de 2016, 16:36:46 »
Deberias cambiar las lineas de:

- la configuracion de los modulos, ya que tienen mas opciones
- La direccion de memoria de los registros que no recuerdo pero en el 16F84A creo que empienzan en 0x0C y en lso demas 0x20

Ademas podrias usar el .inc del PIC que ya tiene definido W, F, Z, PORTB, etc


 

anything