Autor Tema: El siguiente programa temporiza correctamente  (Leído 1308 veces)

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

Desconectado eldruida

  • PIC10
  • *
  • Mensajes: 1
El siguiente programa temporiza correctamente
« en: 26 de Febrero de 2005, 04:00:00 »
Primero de todo buenas.

He he escrito el siguiente programilla, el qual es medio reloj:

///////////////////
list P=16f84
#INCLUDE p16f84.inc
__CONFIG _CP_OFF & _PWRTE_OFF & _WDT_OFF & _XT_OSC

CBLOCK 0x0C
ENDC

ORG 0
goto START
ORG 4
goto INTERRUPCIO_TIMER

SEGONS EQU 0x0F
MINUTS EQU 0x10
HORES EQU 0x11
INICI EQU 0x15
PARADA EQU 0x16
INICI_VAR EQU 0x18
PARADA_VAR EQU 0x19
VARI EQU 0x17
RETARD_POLSADOR EQU 0x20
SUB_RETARD EQU 0x21
MOSTRA_DISPLAY EQU 0x22



START

bsf 0x03,5
;entrem a el banc 1
clrf 0x05 ;Activem els bits del port a com entrada

;el port a com a sortida
movlw 0x03
movwf PORTB

movlw 0x17 ;assigna el prescaler i altres opcions en
movwf 0x81 ;en el registre option

bcf 0x03,5 ;es passa al bank 0

movlw d"61" ;Envia un valor definit per crear 50ms en el registre TM
movwf 0x01 ;R0 per tal de la interrupcio es faci cada 50ms

movlw 0xA0 ;activem els bits de intcon per poder usar la
movwf 0x0B ;interrupció del timer

movlw 0x0A ;Es guarda .10 per tal de crear un bucle
movwf 0x0D ;

movlw 0x04 ;Per defecte es guarda 4 hores per a partir de les quals
movwf INICI ;es donarà senyal al rele
movwf INICI_VAR

movlw 0x01 ;Per defecte el rele es desactiva al cap d"una hora dese
movwf PARADA ;que es va activar el rele
movwf PARADA_VAR

movlw 0x14 ;Byte de memoria per que es s"augmenti un segon cada vin
movwf 0x0E ;t interrupcions de timer.

movlw d"61" ;Tornem a reposar el timer
movwf 0x01

movlw 0x03
movwf RETARD_POLSADOR

movlw 0x8
movwf SUB_RETARD

;;;;;;FI DE VARIABLES


;;;EL COS DEL PROGRAMA
MAIN


btfss PORTB,0 ;Mira si s"ha apretat el polsador 1
goto PULS_1

btfss PORTB,1 ;Mira si s"ha apretat el polsador 2
goto PULS_2


btfsc VARI,3
call ENVIA_UNITATS
call ENVIA_DESENES

btfsc VARI,4
goto ACTIVA_RELE
goto DESACTIVA_RELE

goto MAIN
;;;;;;FI MAIN



;;;;A PARTIR D"AQUI FUNCIONS
ENVIA_UNITATS
bcf VARI,3
movf INICI_VAR,0
btfsc VARI,5 ;Si VARI 5 està en 1 s"envia les hores de per parar als displays
movf PARADA_VAR,0
CALL BINARY_TO_BCD
movf UNITATS,0
movwf 0x05
bcf 0x06,7
bsf 0x06,6
return
ENVIA_DESENES
bsf VARI,3
movf INICI_VAR,0
btfsc VARI,5 ;Si el bit 5 de VARI està en 1 no s"envia les hores de INICI als displays
movf PARADA_VAR,0
call BINARY_TO_BCD
movf DESENES,0
movwf 0x05
bcf 0x06,6
bsf 0x06,7
return
PULS_1
call BUCLE_REBOTS
bcf VARI,5 ;Si s"estava mostrant les hores de parada, al apretar el pulsador es torenen a mostrar les hores de inici
movlw 0x18 ;Mira si que INICI No sigui major que 24 hores
subwf INICI,0

btfsc STATUS,Z
goto RESET_INICI

incf INICI,1 ;Incrementa INICI cada vegada que s"apreta boto

movf INICI,0 ;Copia el contingut en INICI_VAR
movwf INICI_VAR
goto MAIN

RESET_INICI
movlw 0x04 ;Com que la variable INICI ha arribat a 24 es posa a 4
movwf INICI
movwf INICI_VAR ; Es fa copia de INICI
goto MAIN

;Quan s"apreta el pulsador dos
PULS_2
CALL BUCLE_REBOTS
bsf VARI,5 ;Bit que fa que es mostri en els displays els numeros de parada
movlw 0x03 ;resta 3 a PARADA perque parada no sigui major a 3
subwf PARADA,0

btfsc STATUS,Z
goto RESET_PARADA

incf PARADA,1
movf PARADA,0
movwf PARADA_VAR
goto MAIN

RESET_PARADA

movlw 0x01
movwf PARADA
movwf PARADA_VAR
goto MAIN
;Fi funció pulsador dos

ACTIVA_RELE
bsf PORTB,2
goto MAIN

DESACTIVA_RELE
bcf PORTB,2
goto MAIN

;MOSTRA_DISPLAY_INICI
; movlw INICI
; CALL BINARY_TO_BCD
; return






;;;;CALL DEL TIMER
INTERRUPCIO_TIMER

call RETARD
call MINI_RETARD
nop
nop
nop


movlw d"63"
movwf 0x01
movlw d"14"
;Mirem si ha passat un segon

decfsz 0x0E,1
goto FI_INTERRUPCIO ;acaba la interrupció perque encara no s"ha gen
;erat la interrupciói


movlw 0x14 ;Recarreguem el byte de memòria 0x0E per que sols pugui
movwf 0x0E ;venir aquí quan han passat 20 timers
nop


incf SEGONS,1 ;Incrementem el byte de mèmoria per contar els segons.

btfss VARI,5 ;Si VARI 5 està en 0 s"en va directament a BUCLE_segons
goto BUCLE_segons
incf MOSTRA_DISPLAY,1
movlw 0x0A
subwf MOSTRA_DISPLAY,0
btfss STATUS,2
goto BUCLE_segons
bcf VARI,5
clrf MOSTRA_DISPLAY

;Rutina per mirar si tenim un minut
BUCLE_segons
movlw 0x3C ;Resta 60 a SEGONS, per saber si dona 0
subwf SEGONS,0

btfss 0x03,0
goto FI_INTERRUPCIO

incf MINUTS,1 ;Augmenta els minuts passats
clrf SEGONS ;Posa a 0 els segons
bcf 0x03,0 ;Posa a 0 el bit de Z


;Rutina per mirar si ha passat una hora
movlw 0x3C ;Resta 60 a MINUTS, per saber si dona 0
subwf MINUTS,0

btfss 0x03,0
goto FI_INTERRUPCIO

incf HORES,1
clrf MINUTS
bcf 0x03,0

decf INICI_VAR,1

btfsc STATUS,2 ;Si han passat les hores establertes en INICI, s"activa el bit 4 de Vari
bsf VARI,4 ;per tal de activar el relé

btfsc VARI,4 ;Decrementa PARADA_VAR per saber si ha arribat a 0
decf PARADA_VAR,1

btfsc STATUS,2 ;Si arriba a 0 desactiva la variable VARI, per saber que es te que parar el relé
bcf VARI,4

;;mira si han passat 12 hores
movlw 0x0C
subwf HORES,0

btfss 0x03,0
goto FI_INTERRUPCIO
bcf 0x03,0 ;Posa a 0 el bit Z
clrf SEGONS
clrf MINUTS
clrf HORES

FI_INTERRUPCIO
bcf 0x0B,2
retfie

;;;;FINAL INTERRUPCIÓ TIMER







RETARD
;Retard per fer el els 50ms exactes

movlw 0x04
movwf 0x0D
BUCLE
movlw 0x29
movwf 0x0C

SUB_BUCLE
decfsz 0x0C,1
goto SUB_BUCLE

decfsz 0x0D,1
goto BUCLE
return
;Fi de retard

MINI_RETARD

movlw 0x15
movwf 0x24
BUCLE_MINI_RETARD
decfsz 0x24,1
goto BUCLE_MINI_RETARD
return




;Rutina per passar de binari a bcd
BINARY_TO_BCD
clrf UNITATS
clrf DESENES
UNITATS EQU 0x12
DESENES EQU 0x13
CENTENES EQU 0x14

movwf UNITATS ;Guardem el número a convertir en les UNITATS

BUCLE_BCD
movlw 0x0A
subwf UNITATS,1 ;Resta .10 a les UNITATS

btfss STATUS,C ;Comprova si les unitats són més petites que 10
goto FI_BIN_BCD ;Com que es més petit s"acaba
addwf UNITATS,1 ;Recupera els .10 restats en principi

subwf UNITATS,1 ;Resta .10 a les UNITATS
incfsz DESENES,1
goto BUCLE_BCD

incf CENTENES,1
clrf DESENES
goto BUCLE_BCD


FI_BIN_BCD
movlw 0x0A ;Recupera els .10 restats per comprovar si es més gran
addwf UNITATS,1
return
;;;FI RUTINA PER PASSAR DE BINARY A BCD


BUCLE_REBOTS

movlw 0xC3
movwf RETARD_POLSADOR
movlw 0xC3
movwf SUB_RETARD

B_REBOTS
decfsz RETARD_POLSADOR,1
goto SUB_REB
goto FI_RETARD

SUB_REB
decfsz SUB_RETARD,1
goto SUB_REB
goto B_REBOTS

FI_RETARD
RETURN


end

////////////////

Por ahora lo uso como temporizador i prácticamente funciona todo. El problema está en que cada hora saca por el PORTA las horas que quedan para activar un relé en BCD. En el simulador usando el STOPWATCH le quedan microSegundos para que la hora sea exacta. Pero si lo ejecuto realmente en el circuito se atrasa un minuto y no le encuentro la solución.
El circuito usa un Cristal de 4Mhz i oscila a 4,0001 Mhz.

Con todo esto no se que puede pasar??? Helado


 

anything