__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _RC_OSC & _WRT_OFF & _LVP_ON & _CPD_OFF
list p= 16F877A
include "P16F877A.INC"
;**********************************************************************
;***** VARIABLE DEFINITIONS
w_temp EQU 0x71 ; variable used for context saving
status_temp EQU 0x72 ; variable used for context saving
pclath_temp EQU 0x73 ; variable used for context saving
N EQU 0X00
PDel0 EQU 0X20
PDel1 EQU 0x21
PDel2 EQU 0x22
NUMERO EQU 0X23
;**********************************************************************
ORG 0x000 ; processor reset vector
nop ; nop required for icd
goto start ; go to beginning of program
ORG 0x004 ; interrupt vector location
movwf w_temp ; save off current W register contents
movf STATUS,w ; move status register into W register
movwf status_temp ; save off contents of STATUS register
movf PCLATH,w ; move pclath register into w register
movwf pclath_temp ; save off contents of PCLATH register
pagesel man_inter
goto man_inter
restaurar_estado
movf pclath_temp,w ; retrieve copy of PCLATH register
movwf PCLATH ; restore pre-isr PCLATH register contents
movf status_temp,w ; retrieve copy of STATUS register
movwf STATUS ; restore pre-isr STATUS register contents
swapf w_temp,f
swapf w_temp,w ; restore pre-isr W register contents
retfie ; return from interrupt
start:
BANKSEL ADCON1 ;OPERACIONES EN BANCO 1
MOVLW 0x06
MOVWF ADCON1 ;APAGAR A2D
MOVLW 0 ;set PORTC todas salidas
MOVWF TRISC
MOVLW 0xF1 ;RB0 INT PARA PULSADOR, RB1-4 ENTRADAS PARA RECIBIR DE PINGUINO
MOVWF TRISB
BANKSEL PORTC ;OPERACIONES EN BANCO 0
CLRF NUMERO
MOVLW 141
MOVWF PR2
MOVF CCP1CON,W ;modo PWM
ANDLW 0xF0
IORLW 0x0C
MOVWF CCP1CON
MOVF T2CON,W ;prescaler = 16
ANDLW 0xF8
IORLW 0x02
MOVWF T2CON
CLRF CCPR1L ;PWM en blanco
BCF PORTC,0 ;INICIALIZAR SENTIDO DE GIRO NULO (MOTOR APAGAU)
BCF PORTC,3
BSF INTCON,INTE ;ACTIVAR RB0 COMO INTERRUPCIÓN
BSF INTCON,RBIE ;ACTIVAR RB4-7 COMO INTERRUPCIONES
BSF INTCON,GIE
BSF T2CON, TMR2ON ;iniciar el timer y el pwm
;-----------
principal
;-----------
nop
goto principal
AVANCE:
BTFSS PORTC,0
CALL DEMORA5SEG
BANKSEL CCPR1L
MOVLW H'F3'
MOVWF CCPR1L
BCF PORTC,3
BSF PORTC,0
goto clrflags
RETROCESO
CALL DEMORA5SEG
BANKSEL CCPR1L
MOVLW H'19'
MOVWF CCPR1L
BCF PORTC,0
BSF PORTC,3
goto clrflags
MEDIAMAQUINA
BTFSS PORTC,0
CALL DEMORA5SEG
BANKSEL CCPR1L
MOVLW H'80'
MOVWF CCPR1L
BCF PORTC,3
BSF PORTC,0
goto clrflags
LENTO
BTFSS PORTC,0
CALL DEMORA5SEG
BANKSEL CCPR1L
MOVLW H'19'
MOVWF CCPR1L
BCF PORTC,3
BSF PORTC,0
goto clrflags
STOP
BCF PORTC,3
BCF PORTC,0
CLRF CCPR1L
;TODO: UN BREVE BACK para frenar en lugar de poner a cero el duty, o pr2?
goto clrflags
man_inter
pagesel DEMORA
call DEMORA ;20ms
BTFSC INTCON,INTF ;Se supone que el delay permitió que rb0 se estabilice
GOTO INCRPULSA
BTFSC INTCON,RBIF ;Se supone que el delay permitió que rb4 A 7 se estabiliceN
GOTO DECODENT
INCRPULSA INCF NUMERO ;Sumo 1, y si llegué a 5 vuelvo a cero
MOVFW NUMERO
XORLW 5
BTFSC STATUS,Z
CLRF NUMERO
MOVFW NUMERO
GOTO CAMBIAMODO
DECODENT ;Se toma el modo del msb=1 de RB4-RB7
BTFSC PORTB,7
GOTO DECOAVANCE
BTFSC PORTB,6
GOTO DECOMEDIAMAQ
BTFSC PORTB,5
GOTO DECOLENTO
BTFSC PORTB,4
GOTO DECORETROCESO
GOTO DECOSTOP
DECOAVANCE MOVLW 1
GOTO PRECARGAMODO
DECOMEDIAMAQ MOVLW 2
GOTO PRECARGAMODO
DECOLENTO MOVLW 3
GOTO PRECARGAMODO
DECORETROCESO MOVLW 4
GOTO PRECARGAMODO
DECOSTOP CLRW
GOTO PRECARGAMODO
PRECARGAMODO MOVWF NUMERO
CAMBIAMODO MOVFW NUMERO ;W tiene los 3 lsb marcando 1 de los 5 estados, guardar en NUMERO
XORLW 1
BTFSC STATUS,Z
goto AVANCE
MOVFW NUMERO
XORLW 2
BTFSC STATUS,Z
goto MEDIAMAQUINA
MOVFW NUMERO
XORLW 3
BTFSC STATUS,Z
goto LENTO
MOVFW NUMERO
XORLW 4
BTFSC STATUS,Z
goto RETROCESO
goto STOP
clrflags
BCF INTCON,INTF
BCF INTCON,RBIF
goto restaurar_estado
;Demora 20 ms
DEMORA movlw .8 ; 1 set numero de repeticion (B)
movwf PDel0 ; 1 |
PLoop120 movlw .249 ; 1 set numero de repeticion (A)
movwf PDel1 ; 1 |
PLoop220 clrwdt ; 1 clear watchdog
clrwdt ; 1 ciclo delay
decfsz PDel1, 1 ; 1 + (1) es el tiempo 0 ? (A)
goto PLoop220 ; 2 no, loop
decfsz PDel0, 1 ; 1 + (1) es el tiempo 0 ? (B)
goto PLoop120 ; 2 no, loop
PDelL120 goto PDelL220 ; 2 ciclos delay
PDelL220 clrwdt ; 1 ciclo delay
return ; 2+2 Fin.
;-------------------------------------------------------------
;-------------------------------------------------------------
DEMORA5SEG movlw .22 ; 1 set numero de repeticion (C)
movwf PDel0 ; 1 |
PLoop0 movlw .134 ; 1 set numero de repeticion (B)
movwf PDel1 ; 1 |
PLoop1 movlw .211 ; 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