1 | TITLE ''
|
2 | LIST P=16F877A
|
3 | __config H'F7BA'
|
4 |
|
5 |
|
6 | ;******************************************************************
|
7 | ;* CONSTANT DECLARATIONS *
|
8 | ;******************************************************************
|
9 |
|
10 | TMR0 EQU 1 ;Timer 0 is register 1 (Bank 0)
|
11 | STATUS EQU 3 ;Status register is register 3
|
12 | RP0 EQU 5 ;Bit 5 of Status (Bank Select Bit)
|
13 | PORTA EQU 5 ;Port A is register 5 (Bank 0)
|
14 | PORTB EQU 6 ;Port B is register 6 (Bank 0)
|
15 | PORTC EQU 7
|
16 | PORTD EQU 8
|
17 | PORTE EQU 9 ;Port E is register 9 (Bank 0)
|
18 | OPTION_REG EQU 81 ;is register 81 (Bank 1)
|
19 | TRISA EQU 85 ;TRIS A is register 85 (Bank 1)
|
20 | TRISB EQU 86 ;TRIS B is register 86 (Bank 1)
|
21 | TRISC EQU 87
|
22 | TRISD EQU 88
|
23 | TRISE EQU 89 ;TRIS E is register 89 (Bank 1)
|
24 | ADCON0 EQU 1F ;ADCON0 is register 1F (Bank 0) analog to digital converter
|
25 | ADCON1 EQU 9F ;ADCON1 is register 9F (Bank 1) analog to digital converter
|
26 | ADRESH EQU 1E ;ADRESH is register 1E (Bank 0) storage register of result of A/D converting
|
27 | PC EQU 2 ;PCL is register 2 (Bank 0)
|
28 | T2CON EQU 12
|
29 | CCP1CON EQU 17
|
30 | PR2 EQU 92
|
31 | CCPR1L EQU 15
|
32 | ADVAL EQU 20 ;ADVAL is register 20 (Bank 0)for AD value
|
33 | HUNDR EQU 21 ;register for value of the hundreds
|
34 | TENS EQU 22 ;register for value of the tens
|
35 | UNITS EQU 23 ;register for value of the units
|
36 | TRANS EQU 24
|
37 | ;******************************************************************
|
38 | ;* RESET VECTOR DEFINITION *
|
39 | ;******************************************************************
|
40 |
|
41 | ORG 0x00
|
42 | GOTO CFIG ;Set the reset vector
|
43 | ORG 0x06 ;Jump over interrupt vector
|
44 |
|
45 | ;******************************************************************
|
46 | ;* INITIALISATION *
|
47 | ;******************************************************************
|
48 |
|
49 | CFIG
|
50 | BSF STATUS,RP0 ;Jump to Bank 1
|
51 | MOVLW B'11111111' ;Load value in W
|
52 | MOVWF TRISA ;with content of W configure all bits of PortA as input with content of W
|
53 | ;default setting are input only for make sure
|
54 | CLRF TRISB ;Configure all bits of PORTB as OUTPUT
|
55 | CLRF TRISC ;Configure all bits of PORTC as OUTPUT
|
56 | CLRF TRISD ;Configure all bits of PORTD as OUTPUT
|
57 | CLRF TRISE ;Configure all bits of PORTE as OUTPUT
|
58 |
|
59 | MOVLW B'00000010' ;Load value in W
|
60 | MOVWF ADCON1 ;Set RE0-2 as digital OUTPUT RA0-4 as analog INPUT and VDD as Vref+ and ADRESH use
|
61 | MOVLW B'00000111' ;Load value in W
|
62 | MOVWF OPTION_REG ;Increment TMR0 based on internal instr. cycle clock (Bit 5),
|
63 | ;prescale TMR0 (Bit 3) at 256:1 (Bit 0-2)
|
64 | BCF STATUS,RP0 ;Jump back to Bank 0
|
65 | MOVLW 0xc1
|
66 | MOVWF ADCON0
|
67 |
|
68 | MOVLW B'00000100'
|
69 | MOVWF T2CON
|
70 | BSF STATUS,RP0
|
71 | MOVLW d'254'
|
72 | MOVWF PR2
|
73 | BCF STATUS,RP0
|
74 | MOVLW d'255'
|
75 | MOVWF CCPR1L
|
76 | CLRF CCP1CON
|
77 | BSF CCP1CON,3
|
78 | BSF CCP1CON,2
|
79 | ;******************************************************************
|
80 | ;* MAIN BODY *
|
81 | ;******************************************************************
|
82 | START
|
83 | CLRF HUNDR ;Clear storage register of hundreds
|
84 | CLRF TENS ;Clear storage register of tens
|
85 | CLRF UNITS ;Clear storage register of units
|
86 |
|
87 | ;MOVLW B'11000001' ;Load value in W
|
88 | ;MOVWF ADCON0 ;set internal Clock (Bit 6,7) read RA0 (Bit 3,4,5)(and A/D-converter ON (Bit 0
|
89 |
|
90 | BSF ADCON0,2 ;Start of A/D converting
|
91 | ADLOOP_RA0
|
92 | BTFSC ADCON0,2 ;Test if A/D converting was succsessfull, if YES (Bit2="0")overjump next
|
93 | GOTO ADLOOP_RA0 ;Jump back to ADLOOP if A/D converting was not succsessfull (Bit2="1")
|
94 | MOVF ADRESH,W ;MOVE Result of A/D converting from ADRESH to Working register
|
95 | MOVWF ADVAL ;MOVE result from W to ADVAL register 20 (Bank 0)
|
96 | MOVWF PORTD
|
97 | CALL DMTime
|
98 | CLRF ADRESH
|
99 | MOVLW B'11001001' ;Load value in W
|
100 | MOVWF ADCON0 ;set internal Clock (Bit 6,7) read RA1 (Bit 3,4,5)(and A/D-converter ON (Bit 0
|
101 | BSF ADCON0,2 ;Start of A/D converting
|
102 | ADLOOP_RA1
|
103 | BTFSC ADCON0,2 ;Test if A/D converting was succsessfull, if YES (Bit2="0")overjump next
|
104 | GOTO ADLOOP_RA1 ;Jump back to ADLOOP if A/D converting was not succsessfull (Bit2="1")
|
105 | MOVF ADRESH,W ;MOVE Result of A/D converting from ADRESH to Working register
|
106 | MOVWF TRANS ;MOVE result from W to ADVAL register 20 (Bank 0)
|
107 | MOVF TRANS,W
|
108 | MOVWF CCPR1L
|
109 |
|
110 | CALL DMTime
|
111 | GOTO START ;Jump back to START for a new program cycle
|
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 | ; ---- HUNDREDS CALCULATION ----
|
118 | MOVLW .100 ;load the decimal value 100 into W
|
119 | H_sub
|
120 | SUBWF ADVAL,1 ;subtract the 100 from ADVAL
|
121 | BTFSS STATUS,0 ;test status bit 0 (carry), if it is set the result of subtraction was pos.
|
122 | ;then skip next instruction
|
123 | GOTO CALC_T
|
124 | INCF HUNDR,1 ;last subtraction was successful (positive)
|
125 | ;Hundreds value of ADVAL is bigger than 100 increase Hundreds
|
126 | GOTO H_sub ;jump back to H_sub loop
|
127 | ; ---- TENS CALCULATION ----
|
128 | CALC_T
|
129 | ADDWF ADVAL,1 ;add 100 back to the negative result of last H_sub to get a positive value
|
130 | MOVLW .10 ;load the decimal value 10 into W
|
131 | T_sub
|
132 | SUBWF ADVAL,1 ;subtract the 10 from ADVAL
|
133 | BTFSS STATUS,0 ;test status bit 0 (carry), if it is set the result of subtraction was pos.
|
134 | ;then skip next instruction
|
135 | GOTO CALC_U
|
136 | INCF TENS,1 ;last subtraction was successful (positive)
|
137 | ;Tens value of ADVAL is bigger than 10 increase Tens
|
138 | GOTO T_sub ;jump back to T_sub loop
|
139 | ; ---- UNITS CALCULATION ----
|
140 | CALC_U
|
141 | ADDWF ADVAL,1 ;add 10 back to the negative result of last T_sub to get a positive value
|
142 | MOVLW .1 ;load the decimal value 1 into W
|
143 | U_sub
|
144 | SUBWF ADVAL,1 ;subtract the 1 from ADVAL
|
145 | BTFSS STATUS,0 ;test status bit 0 (carry), if it is set the result of subtraction was pos.
|
146 | ;then skip next instruction
|
147 | GOTO DISPL ;back to MAIN PROGRAM
|
148 | INCF UNITS,1 ;last subtraction was successful (positive)
|
149 | ;Units value of ADVAL is bigger than 1 increase Tens
|
150 | GOTO U_sub ;jump back to U_sub loop
|
151 |
|
152 | ; ---- Lighting the 3 Digits of 7 Segment Display ----
|
153 | DISPL
|
154 | MOVF HUNDR,0 ;Load value of hundreds into W
|
155 | CALL LOOKUP ;take 7 segment code from out of the lookup table
|
156 | MOVWF PORTB ;move 7 segment code to Port B
|
157 | BSF PORTE,2 ;Switch ON bit 2 of Port E for digit hundreds
|
158 | CALL DMTime ;call multiplexing Timer and wait as long as reached setted value
|
159 | BCF PORTE,2 ;Switch OFF bit 2 of Port E for digit hundreds
|
160 | MOVF TENS,0 ;Load value of tens into W
|
161 | CALL LOOKUP ;take 7 segment code from out of the lookup table
|
162 | MOVWF PORTB ;move 7 segment code to Port B
|
163 | BSF PORTE,1 ;Switch ON bit 1 of Port E for digit tens
|
164 | CALL DMTime ;call multiplexing Timer and wait as long as reached setted value
|
165 | BCF PORTE,1 ;Switch OFF bit 2 of Port E for digit tens
|
166 | MOVF UNITS,0 ;Load value of units into W
|
167 | CALL LOOKUP ;take 7 segment code from out of the lookup table
|
168 | MOVWF PORTB ;move 7 segment code to Port B
|
169 | BSF PORTE,0 ;Switch ON bit 0 of Port E for digit units
|
170 | CALL DMTime ;call multiplexing Timer and wait as long as reached setted value
|
171 | BCF PORTE,0 ;Switch OFF bit 2 of Port E for digit units
|
172 |
|
173 | ;******************************************************************
|
174 | ;* Subroutines *
|
175 | ;******************************************************************
|
176 |
|
177 | ;***** LOOKUP TABLE *****
|
178 | LOOKUP
|
179 | ADDWF PC,1 ;add content of W to program counter
|
180 | ; DPgfedcba
|
181 | RETLW B'00111111' ;return with BCD-Code for 7 Segm.Display "0"
|
182 | RETLW B'00000110' ;return with BCD-Code for 7 Segm.Display "1"
|
183 | RETLW B'01011011' ;return with BCD-Code for 7 Segm.Display "2"
|
184 | RETLW B'01001111' ;return with BCD-Code for 7 Segm.Display "3"
|
185 | RETLW B'01100110' ;return with BCD-Code for 7 Segm.Display "4"
|
186 | RETLW B'01101101' ;return with BCD-Code for 7 Segm.Display "5"
|
187 | RETLW B'01111101' ;return with BCD-Code for 7 Segm.Display "6"
|
188 | RETLW B'00000111' ;return with BCD-Code for 7 Segm.Display "7"
|
189 | RETLW B'01111111' ;return with BCD-Code for 7 Segm.Display "8"
|
190 | RETLW B'01101111' ;return with BCD-Code for 7 Segm.Display "9"
|
191 |
|
192 | ;***** Display Multiplexing Time *****
|
193 | DMTime
|
194 | MOVLW .25 ;load the decimal value 25 into W
|
195 | MOVWF TMR0 ; preadjust timer with 25 (content of W)
|
196 | DMT_Loop
|
197 | BTFSS TMR0,6 ;test bit 6 (dec value 64)of timer TMR0 if it is set, skip next instruction
|
198 | GOTO DMT_Loop ;jump back to the Loop
|
199 | RETURN ;jump back to main program
|
200 |
|
201 |
|
202 |
|
203 | END
|