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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; Program: Binary to 7 Segment Decoder ;
; Author: Jake Sutherland ;
; Date: Monday 19th April 2010 ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
list p=pic16f628a
include "P16F628A.INC"
__config _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BODEN_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
errorlevel -302 ;Eliminate bank warning
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; PIC16F628A Microcontroller ;
; ____ ____ ;
; Binary input Bit 2 VREF/AN2/RA2 -| 1 - 18 |- RA1/AN1 Binary input Bit 1 ;
; Binary input Bit 3 LED - CPM1/AN3/RA3 -| 2 17 |- RA0/AN0 Binary input Bit 0 ;
; Latch Enable CMP2/T0CKI/RA4 -| 3 16 |- RA7/OSC1/CLKIN Ripple Blanking Output ;
; Test Lamp Enable VPP/MCLR/RA5 -| 4 15 |- RA6/OSC2/CLKOUT Ripple Blanking Input ;
; VSS -| 5 14 |- VDD ;
; Common Anode/Common Cathode INT/RB0 -| 6 13 |- RB7/T1OSC1/ICSPDAT Segment B ;
; Segment C DT/RX/RB1 -| 7 12 |- RB6/T1OSCO/T1CLKI/ICSPCLK Segment A ;
; Segment D CK/TX/RB2 -| 8 11 |- RB5 Segment F ;
; Segment E CCP1/RB3 -|_9____10_|- RB4/PGM Segment G ;
; ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CBLOCK H'20'
W_TEMP ; GPR used for context saving
STATUS_TEMP ; GPRCused for context saving
BINARYNUM ; GPR used for storing Binary Input Digit
DISPLAY_STORE ; GPR used for Display Store
ENDC
ORG 0x000 ; Processor reset vector location. On power up, the program jumps here
GOTO SETUP ;
ORG 0x004 ; Interrupt vector location. When an Interupt occurs, the program jumps here
MOVWF W_TEMP ; Save current W register contents
MOVF STATUS, W ; Move STATUS register into W register
MOVWF STATUS_TEMP ; Save contents of STATUS register in temporary register
; Interrupt Service Routine goes here. If no interrupts are enabled and triggered during the program, this section can be ignored
MOVF STATUS_TEMP, W ; Retrieve saved status of STATUS register
MOVWF STATUS ; Restore pre-ISR STATUS register contents
SWAPF W_TEMP, F ; Restore pre-ISR W register contents
SWAPF W_TEMP, W ; (a MOVF W_TEMP, W would acheive the same result but this affects the STATUS register, therefore 2 SWAPF instructions are used)
RETFIE ; Return From Interrupt
BCD7SEG_COMMON_K ; This routine assigns on/off arrangement to the 7 Segment Display depending on the number
ADDWF PCL, F
;BAFGEDCx
RETLW B'11101110' ;0
RETLW B'10000010' ;1
RETLW B'11011100' ;2
RETLW B'11010110' ;3
RETLW B'10110010' ;4
RETLW B'01110110' ;5
RETLW B'01111110' ;6
RETLW B'11000010' ;7
RETLW B'11111110' ;8
RETLW B'11110110' ;9
RETLW B'11111010' ;A
RETLW B'00111110' ;B
RETLW B'01101100' ;C
RETLW B'10011110' ;D
RETLW B'01111100' ;E
RETLW B'01111000' ;F
RETURN
BCD7SEG_COMMON_A ; This routine assigns on/off arrangement to the 7 Segment Display depending on the number
ADDWF PCL, F
;BAFGEDCx
RETLW B'00010000' ;0
RETLW B'01111100' ;1
RETLW B'00100010' ;2
RETLW B'00101000' ;3
RETLW B'01001100' ;4
RETLW B'10001000' ;5
RETLW B'10000000' ;6
RETLW B'00111100' ;7
RETLW B'00000000' ;8
RETLW B'00001000' ;9
RETLW B'00000100' ;A
RETLW B'11000000' ;B
RETLW B'10010010' ;C
RETLW B'01100000' ;D
RETLW B'10000010' ;E
RETLW B'10000110' ;F
RETURN
SETUP ; This rountine sets up the chips Inputs and Outputs
CLRF PORTA ; Initialise PORT A by setting ouput data latches
MOVLW H'07' ; Turn Comparators off and enable pins for I/O functions
MOVWF CMCON ;
BCF STATUS, RP1 ; Bank 1
BSF STATUS, RP0 ; Bank 1
MOVLW B'01111111' ; RA<7> Output, RA<6:0> Inputs.
MOVWF TRISA ;
MOVLW B'00000001' ; RB<7:1> Outputs, RB<0> Input.
MOVWF TRISB ;
BCF STATUS, RP1 ; Bank 0
BCF STATUS, RP0 ; Bank 0
GETNUM ; This rountine is to obtain the binary number from PORTA and store it in a general purpose register (temporary register)
MOVF PORTA, W ; Move PORTA to W
ANDLW H'0F' ; Mask the upper nibble. This ensures upper nibble is always 0
MOVWF BINARYNUM ; Move the value to a general purpose register (temporary register)
TEST_DISP_SELECT ; This routine tests the Display Type Input pin (Common Cathode or Common Anode)
BTFSC PORTB, 0 ; Test 'Display Type Input'
GOTO COMMON_K ; If set, we are using a Common Cathode Display, therefore we CALL 'BCD7SEG_COMMON_K' to load appropiate segments of the display according to the value of PORT A
CALL BCD7SEG_COMMON_A ; If clear, we are using a Common Anode Display, therefore we CALL 'BCD7SEG_COMMON_A' to load appropiate segments of the display according to the value of PORT A
MOVWF DISPLAY_STORE ; This instruction loads appropiate segments as determined by the tables above to a general purpose register (temporary register) for use later
GOTO TEST_FOR_0 ; Then we go to the TEST_FOR_0 routine
COMMON_K ; This routine is called if the 'Display Type Input' pin is set. If it is clear, this routine is skipped
CALL BCD7SEG_COMMON_K ; Call rountine to load appropiate segments of the display according to the value of PORT A
MOVWF DISPLAY_STORE ; This instruction loads appropiate segments as determined by the tables above to a general purpose register (temporary register) for use later
GOTO TEST_FOR_0 ; Then we go to the TEST_FOR_0 routine
TEST_FOR_0 ; This routine is to determine if a zero is displayed
MOVF BINARYNUM, W ; Move the Binary Number to the working register
XORLW B'00000000' ; Binary 00000000 is the number for '0'. By XOR'ing '00000000' with 'BINARYNUM', we can determine if 'BINARYNUM' is equal to zero by testing the 'zero' bit of the STATUS register
BTFSC STATUS, Z ; Test 'zero' bit of STATUS register
GOTO CHECK_BLANKING ; Binary number in BINARYNUM is '0', so we GOTO 'CHECK_BLANKING' to determine whether the Ripple Blanking Input (PORTA,6) is high or low, which will determine whether we display '0' or not
GOTO NOT_ZERO ; Binary number in BINARYNUM is NOT '0', so we GOTO 'NOT_ZERO' and display the number, as well as setting the Ripple Blanking Output (PORTA,7)
NOT_ZERO ; If the inputs are found to NOT = '0', this routine displays the number. This routine is skipped if it IS '0'
MOVF DISPLAY_STORE, W ; Move the segment arragement to the working register
MOVWF PORTB ; Move the W register to PORTB
BSF PORTA, 7 ; Set the 'Ripple Blanking Output'
GOTO LATCH ; Test if Latch enabled
CHECK_BLANKING ; If the input IS found to = '0', this routine checks the Ripple Blanking Input to determine whether to display the '0' or not (if not, it will clear the display)
BTFSC PORTA, 6 ; Test the 'Ripple Blanking Input'. Skip GOTO if clear
GOTO NO_BLANK ; Ripple Blanking Input set so dont blank the number '0'
BTFSC PORTB, 0 ; Test 'Display Type Input'. If CC, execute next instruction. If CA skip next instruction
MOVLW H'00' ; 0x00 is to clear the display if a CC display is used
BTFSS PORTB, 0 ; ( Two 'BTFSC PORTB,0' statements prevents having to create another subroutine just to load 1 value with 1 instruction. It can be done like this)
MOVLW H'FF' ; 0xFF is to clear the display if a CA display is used
MOVWF PORTB ; 7 Segment display is connected to PORTB
BCF PORTA, 7 ; Clear Ripple Blanking Output
GOTO LATCH ; Test if Latch enabled
NO_BLANK ; This rountine is exectuced if the RBI is HIGH, therefore '0' is displayed
MOVF DISPLAY_STORE, W ; Move the segment arragement to the working register
MOVWF PORTB ; Move the W register to PORTB
BSF PORTA, 7 ; Set the Ripple Blanking Output
GOTO LATCH ; Test if Latch enabled
LATCH ; This routine checks the LATCH. Active Low
BTFSS PORTA, 4 ; Test LATCH
BSF PORTA, 7 ; If LATCH enabled, set the Ripple Blanking Output. If LATCH disabled, skip
BTFSS PORTA, 4 ; Test LATCH
GOTO LATCH ; If LATCH enabled, GOTO LATCH and test again. If LATCH disabled, skip
TEST_LAMP ; This routine checks the TEST LAMP input
BTFSC PORTA, 5 ; Test input pin
GOTO GETNUM ; If set, Start again, test for Binary Number on PORTA
MOVLW H'08' ; If input clear, set all segments on LED display
MOVWF BINARYNUM ; Move 11111111 to PORTB
GOTO TEST_DISP_SELECT ; GOTO TEST_LAMP to check if pin state changed
END
|