-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrec.asm
More file actions
137 lines (110 loc) · 5.08 KB
/
rec.asm
File metadata and controls
137 lines (110 loc) · 5.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
list P=18F8722
#include <p18f8722.inc>
config OSC = HSPLL, FCMEN = OFF, IESO = OFF, PWRT = OFF, BOREN = OFF, WDT = OFF, MCLRE = ON, LPT1OSC = OFF, LVP = OFF, XINST = OFF, DEBUG = OFF
state udata 0x21
state
counter udata 0x22
counter
w_temp udata 0x23
w_temp
status_temp udata 0x24
status_temp
pclath_temp udata 0x25
pclath_temp
portb_var udata 0x26
portb_var
org 0x00
goto init
org 0x08
goto isr ;go to interrupt service routine
init:
;Disable interrupts
clrf INTCON
clrf INTCON2
;Configure Output Ports
clrf LATF ; clear LATF
clrf TRISF ; use LATF as output
;Configure Input/Interrupt Ports
movlw b'00010000' ; w_reg = b'00010000'
movwf TRISB ; TRISB = =w_reg = b'00010000'
bcf INTCON2, 7 ;Pull-ups are enabled - clear INTCON2<7>
clrf PORTB
;Initialize Timer0
movlw b'01000111' ;Disable Timer0 by setting TMR0ON to 0 (for now)
;Configure Timer0 as an 8-bit timer/counter by setting T08BIT to 1
;Timer0 increment from internal clock with a prescaler of 1:256.
movwf T0CON ; T0CON = b'01000111'
;Enable interrupts
movlw b'11101000' ;Enable Global, peripheral, Timer0 and RB interrupts by setting GIE, PEIE, TMR0IE and RBIE bits to 1
movwf INTCON
bsf T0CON, 7 ;Enable Timer0 by setting TMR0ON to 1
main:
btfsc state,0 ; Is state 0?
bsf PORTF,0 ; No, then turn on LED0
btfss state,0 ; Is state 1?
bcf PORTF,0 ; No, then turn off LED0
goto main
isr:
call save_registers ;Save current content of STATUS and PCLATH registers to be able to restore them later
btfss INTCON, 2 ;Is this a timer interrupt?
goto rb_interrupt ;No. Goto PORTB on change interrupt handler part
goto timer_interrupt ;Yes. Goto timer interrupt handler part
;;;;;;;;;;;;;;;;;;;;;;;; Timer interrupt handler part ;;;;;;;;;;;;;;;;;;;;;;;;;;
timer_interrupt:
incf counter, f ;Timer interrupt handler part begins here by incrementing count variable
movf counter, w ;Move count to Working register
sublw d'5' ;Decrement 5 from Working register
btfss STATUS, Z ;Is the result Zero?
goto timer_interrupt_exit ;No, then exit from interrupt service routine
clrf counter ;Yes, then clear count variable
comf state, f ;Complement our state variable which controls on/off state of LED0
timer_interrupt_exit:
bcf INTCON, 2 ;Clear TMROIF
movlw d'61' ;256-61=195; 195*256*5 = 249600 instruction cycle;
movwf dTMR0
call restore_registers ;Restore STATUS and PCLATH registers to their state before interrupt occurs
retfie
;;;;;;;;;;;;;;;;;;; PORTB on change interrupt handler part ;;;;;;;;;;;;;;;;;;;;;
rb_interrupt:
btfss INTCON, 0 ;Is this PORTB on change interrupt
goto rb_interrupt_exit0 ;No, then exit from interrupt service routine
movf PORTB, w ;Read PORTB to working register
movwf portb_var ;Save it to shadow register
btfsc portb_var, 4 ;Test its 4th bit whether it is cleared
goto rb_interrupt_exit2 ; RB4 is 1
bsf PORTF, 7 ; RB4 is 0, Button is pressed, so turn on LED7
rb_interrupt_exit1:
movf portb_var, w ;Put shadow register to W
movwf PORTB ;Write content of W to actual PORTB, so that we will be able to clear RBIF
bcf INTCON, 0 ;Clear PORTB on change FLAG
call restore_registers ;Restore STATUS and PCLATH registers to their state before interrupt occurs
retfie
rb_interrupt_exit2:
bcf PORTF, 7 ;Button is released, so turn off LED7
movf portb_var, w ;Put shadow register to W
movwf PORTB ;Write content of W to actual PORTB, so that we will be able to clear RBIF
bcf INTCON, 0 ;Clear PORTB on change FLAG
call restore_registers ;Restore STATUS and PCLATH registers to their state before interrupt occurs
retfie
rb_interrupt_exit0:
call restore_registers ;Restore STATUS and PCLATH registers to their state before interrupt occurs
retfie
;;;;;;;;;;;; Register handling for proper operation of main program ;;;;;;;;;;;;
save_registers:
movwf w_temp ;Copy W to TEMP register
swapf STATUS, w ;Swap status to be saved into W
clrf STATUS ;bank 0, regardless of current bank, Clears IRP,RP1,RP0
movwf status_temp ;Save status to bank zero STATUS_TEMP register
movf PCLATH, w ;Only required if using pages 1, 2 and/or 3
movwf pclath_temp ;Save PCLATH into W
clrf PCLATH ;Page zero, regardless of current page
return
restore_registers:
movf pclath_temp, w ;Restore PCLATH
movwf PCLATH ;Move W into PCLATH
swapf status_temp, w ;Swap STATUS_TEMP register into W
movwf STATUS ;Move W into STATUS register
swapf w_temp, f ;Swap W_TEMP
swapf w_temp, w ;Swap W_TEMP into W
return
end