COUNT TO 10,000,000
using 12 DIGIT RUNNING SIGN
 


Home

More PIC Projects
To order send an email to us and we will reply with the details.

Kit: $25.00 plus $6.50 postage

to:P1
 

This project automatically counts to 10,000,000 in one-second steps. It uses the 12 DIGIT RUNNING SIGN project.

To get into the area containing this feature; turn the project on, wait for the Attract message then push [   ]  key and 10,000,000 SECONdS  will appear. Then the display will show 00,000,000
All the "background routines" have been written to produce a scan routine and key-press routine.
All we have done is add the Count to 10,000,000 sub-routines.
The program is basically a 8-digit counter with automatic increment every second with a count stored in EEPROM every 50 seconds so you can turn the project off, then on again, get into the 10,000,000 Seconds count area, and continue the count. 
The display can be turned OFF by pressing the first button. This reduces the current from nearly 80mA to about 1mA. However the counting keeps advancing in the background and saved every 50 seconds.
You can turn the display ON by pressing the first button again. You cannot reset the 10 million count without re-burning the chip.

Some of the features of this program include using Timer1 to count in the background while the program is displaying digits on the screen. Timer1 is "two 8-bit counters" that count up and an 8-bit divider can be assigned to it, creating a total count of 256 x 256 x 256 = 16,777,216.
The program also uses EEPROM to store the value of the count at a regular interval. This value is recalled when the project is turned on again and added-to each second.

Here is the project at 1 Million !!

It will keep counting to 16, 777,215   another 78 days  . . . 

PROGRAMMING
The main reason for presenting these projects is to teach programming.
Once you have all the sub-routines in a program, you can use them to create new features.
There is still one more output pin on the micro that has not been used. It is RA7 (Pin16) and can used to drive a relay or any other device via a buffer transistor.
You can produce a count-down timer for rocket launching or similar activity.
The scope is endless and we will leave it up to you.
Go through each line of the program and see what each instruction does. This is a fairly advanced project however each sub-routine performs a very small operation and you need to see what is being carried out.
The only way you are going to fully understand a sub-routine is to build the project and change one of the values in a routine and see what happens. All the routines use very simple coding that can be aligned to "beginners coding." In many instances there is an "advanced" way to achieve the same result using Boolean instructions, but most of these will take you an hour or more to understand, so we have intentionally used instructions that you can easily follow.
There is only one "high level" sub-routine in the program. It is B2D (Binary To Decimal) Conversion.
This has been taken from a section on the web that covers all sorts of PIC programming routines. Simply search "PIC Programs - Tools etc" and you will find code that has been developed by brilliant programmers.
Most of these code snippets will take you hours to understand and all you can do is marvel at the brilliance of the web at being able to bring programmers together to share their capabilities. There are also PIC Forums where you can ask questions and get help on developing code  - so you have a "back-stop" for anything you want to do.
The main thing is to start programming. Once you start, you will be hooked. It is the most challenging activity you can do.
We have only just scratched the surface with the two applications for the display.
If you have any further ideas, let us know . . . .

Here are the files:
Count_to_10,000,000.asm
Count_to_10,000,000.txt
Count_to_10,000,000.hex

Count to 10,000,000 using 12DIGIT RUNNING SIGN

;****************************************************************
;* 12 Digit RUNNING SIGN    Started 23/11/2010			*
;* Counts to 10,000,000 Seconds = about 115 days        	*
;****************************************************************

	;list P = 16F628	;microcontroller 
	include 	;registers for F628

	errorlevel -302  ;remove message about using correct bank
	

	__Config 	_cp_off & _lvp_off & _pwrte_on & 
        _wdt_off & _intRC_osc_noclkout & _mclre_off
	
;code protection - off
;low-voltage programming - off
;power-up timer -  on
;watchdog timer - off
;use internal RC for 4MHz - all pins for in-out

	
;****************************************************************
; variables - names and files
;****************************************************************


		;Files for F628 start at 20h 
 
						 			
temp1		equ 20h	
temp2		equ 21h	
store		equ 22h	;for storing the data on first 10 digits in Sw3
timera		equ 23h	;
timerb		equ 24h	;
Sw_Flag		equ 25h	;
count		equ 26h	;loops of discharge time for 100n
flags		equ 27h	;used to store value in EEPROM in Sw4
Jump_1		equ 28h	;jump counter for table1
Run		equ 29h	;used in RUN (Sw5) routine		
temp_sw		equ 2Ah
ScanLoops	equ 2Bh

onesec_hi	equ 2Ch ;hi byte of 24bit variable
onesec_mid	equ 2Dh	;mid byte
onesec_lo	equ 2Eh ;lo byte
status_temp	equ 2Fh	;used for interrupt servicing
w_temp		equ 30h	;used for interrupt servicing

secs_low	equ 31h ;holds the number of seconds
secs_med        equ 32h ;holds the number of seconds
secs_hi         equ 33h ;holds the number of seconds

       ;35h - 6Fh used for showing values on display
       ;files 35h - 43h are also used for count-to-1-million 
       
res_u		equ 35h	;result - units
res_t		equ 36h	;result - tens
res_h		equ 37h	;result - hundreds
res_th		equ 38h	;result - thousands
res_tth		equ 39h	;result - ten of thousands
res_hth		equ 3Ah	;result - hundreds of thousands
res_m		equ 3Bh	;result - millions
res_tm		equ 3Ch	;result - tens of millions

temp            equ 3Dh
cycles		equ 3Eh
loops           equ 3Fh

bcd_u_t		equ 40h
bcd_h_th	equ 41h
bcd_tth_hth	equ 42h
bcd_m_tm        equ 43h

       
secs_lowtemp    equ 44h ;secs_lowtemp gets destroyed
secs_medtemp    equ 45h ;secs_medtemp gets destroyed
secs_hitemp     equ 46h ;secs_hitemp  gets destroyed      

isr_counter equ 47h ;counts 500mS

RunLoops	equ 70h 
Save		equ 71h	
Ghost		equ 72h
GhostTemp	equ 73h
Window   	equ 74h
WindowTemp	equ 75h
_12loops	equ 76h

;****************************************************************
;Equates
;****************************************************************
status		equ 0x03
cmcon		equ 0x1F
rp1		equ 0x06
rp0		equ 0x05
	      	

;****************************************************************
;Beginning of program
;****************************************************************
reset	org	00	;reset vector address	
	goto	SetUp

	org 0x004	; Interrupt Handler routine
		
		
	movwf 	w_temp	; save W & STATUS contents
	movf 	STATUS,w
	movwf 	status_temp				
	bsf	status,rp0 	;Bank 1				
	bsf	PIE1,0		;,0 1=enables TMR1 interrupt	
	bcf	status,rp0	;bank 0 		
	bcf	PIR1,0		;clear TMR1 overflow flag
	bsf	INTCON,7	;This instruction is needed HERE!!!	
	bsf	INTCON,6	;1=enable all peripheral interrupts
			
	decfsz	isr_counter,f	;counts 500mS		
		
			
	goto	_aaa		
		
	movlw	02
	movwf   isr_counter
	call	isr_delay
		
	incfsz	secs_low,1
	goto	_aa	
	incfsz	secs_med,1
	goto	_aa	
	incf	secs_hi,1			
		
		
_aa	btfsc	flags,0	;store value only once
	goto	_dd
	movlw	0	;stores value in EEPROM every 50 secs
	xorwf	res_t,w		
	btfsc	03,2	
	call	Store3	
	movlw	5	;stores value in EEPROM every 50 secs
	xorwf	res_t,w		
	btfsc	03,2	
	call	Store3			
		
		
_dd	movlw	01	;restore flag,0 when value 1 or 6
	xorwf	res_u,w		
	btfss	03,2
	goto	$+2
	bcf	flags,0		
	movlw	06
	xorwf	res_u,w		
	btfsc	03,2
	bcf	flags,0	


	movf 	status_temp,w
	movwf 	STATUS
	movf 	w_temp,w
	call	B2D
_aaa	movf 	status_temp,w
	movwf 	STATUS
	movf 	w_temp,w
		
	clrf	TMR1L	;clear the Timer1 low register
	movlw	.12	;TMR1H needs 244 to produce 499712uS
	movwf	TMR1H	;put into Timer1 high register
			;Timer0 is not used 		
			; will go to isr when overflow occurs in TMR1	
			;499712uS when prescaler=1:8 
		
	retfie



SetUp	bsf	status,rp0	
	movlw	b'00000000'	;A in/out
	movwf	05h			
	movlw	b'00000000'	;B output
	movwf	06h		
	movlw	b'10000000'	;Turn off T0CKI, prescale for TMR0 = 1		
	movwf	option_reg		
	clrf	eeadr	
	bcf	status,rp0	;select programming area - bank0 		
	movlw	07h		;turn comparators off and enable
	movwf	cmcon		;    pins for I/O functions	
	call	Clear						
	call	Attract 
	call	Clear
	goto 	Main	
	
		
;**************************
;* Tables		  *
;**************************
		
table1	
	addwf 	02h,1	;add W to program counter
	retlw 	3Fh  	;0
	retlw 	06h 	;1 
	retlw 	5Bh 	;2
	retlw 	4Fh 	;3
	retlw 	66h 	;4
	retlw 	6Dh 	;5
	retlw 	7Dh 	;6
	retlw 	07h 	;7
	retlw 	7Fh	;8
	retlw 	6Fh 	;9
	retlw 	3Fh  	;0			
	retlw 	77h	;A 
	retlw 	7Ch	;b  
	retlw 	39h	;C
	retlw 	5Eh	;d
	retlw 	79h	;E
	retlw 	71h	;F
	retlw 	6Fh	;g
	retlw 	76h	;H
	retlw 	06h	;I
	retlw 	1Eh	;J
	retlw 	38h	;L
	retlw 	37h	;N
	retlw 	3Fh	;O
	retlw 	73h	;P
	retlw 	67h	;q
	retlw 	50h	;r	
	retlw 	6Dh 	;S
	retlw 	78h	;t
	retlw 	3Eh	;U
	retlw 	6Eh	;y	
	retlw	80h	;dot
	retlw   0BFh    ;0.
	retlw   86h     ;1.
	retlw	40	;-
	retlw	08h	;_space
	retlw	1	;line on top
	retlw	48h	;equals  . . . . . .24h chars
	retlw	0ffh	;end of table	
	
table2	
	addwf 	02h,1	;add W to program counter
	retlw 	0BFh    ;0.
	retlw 	86h     ;1. 
	retlw 	0DBh 	;2.
	retlw 	0CFh 	;3.
	retlw 	0E6h 	;4.
	retlw 	0EDh 	;5.
	retlw 	0FDh 	;6.
	retlw 	87h 	;7.
	retlw 	0FFh	;8.
	retlw 	0EFh 	;9.
		
		
		
;****************************************
;* Delay sub-routines  			*
;****************************************

			
	;Delay  10uS
			
_10uS	nop		
	nop
	nop			 
	nop
	nop			 
	nop			 	
	retlw	00	
		
		
				
_500uS	decfsz 	temp1,f
	goto 	$-1
	retlw 	00
		
		
	
_1mS	nop
	decfsz 	temp1,f
	goto 	_1mS
	retlw 	00
		
_4mS	movlw	04h
	movwf	temp2
_b	nop
	decfsz 	temp1,f
	goto 	_b
	decfsz 	temp2,f
	goto 	_b	
	retlw 	00			

_10mS	movlw	0Ah
	movwf	temp2
_c	nop
	decfsz 	temp1,f
	goto 	_c
	decfsz 	temp2,f
	goto 	_c	
	retlw 	00	
		
	;288 x 2 uS  to produce 1 second
		
isr_delay
	movlw	.190 
	movwf	temp1
	decfsz  temp1,1
	goto	$-1
	retlw	00
		
			

Delay1	movlw	1
	movwf	timerb
Del_a	decfsz 	timera,1
	goto 	Del_a
	decfsz 	timerb,1
	goto 	Del_a	
	retlw 	00
		
	
Delay2	decfsz 	timera,1
	goto 	Delay2
	decfsz 	timerb,1
	goto 	Delay2
	retlw 	00	
		
		
_250mS	movlw	0FFh
	movwf	temp2
_ee	nop
	decfsz 	temp1,f
	goto 	_ee
	decfsz 	temp2,f
	goto 	_ee	
	retlw 	00			
		
		
		
;*********************
;* sub-routines  				
;*
;*********************	

	;Run: "10,000,000 SECONdS" across display
		
_10million
    	movlw	06h     ;1
	movwf	40h
	movlw	0BFh    ;0.
	movwf	41h
	movlw	3Fh	;0
	movwf	42h	
	movlw	3Fh	;0
	movwf	43h	
	movlw	0BFh    ;0.
	movwf	44h
	movlw	3Fh	;0
	movwf	45h
	movlw	3Fh	;0
	movwf	46h
	movlw	3Fh	;0
	movwf	47h
	movlw	08h	;_ 
	movwf	48h
	movlw	6Dh	;S
	movwf	49h
	movlw	79h	;E
	movwf	4Ah
	movlw	39h	;C
	movwf	4Bh
	movlw	3Fh	;O
	movwf	4Ch
	movlw	37h	;N
	movwf	4Dh
	movlw	5Eh	;d
	movwf	4Eh
	movlw	6Dh	;S
	movwf	4Fh
	movlw	08h	;
	movwf	50h
	movlw	08h	;
	movwf	51h
	movlw	08h ;
	movwf	52h
	movlw	08h	;
	movwf	53h
	movlw	08h	;
	movwf	54h
		
	call	Set4017
	call	Transfer
	call	sw5					
	retlw	00	
		
			
		;12DIGIT_RUNNING_SIGN_BY_TE
		;Attract calls Sw5 RUN sub-routine (Sw_Flag is empty)
		
Attract	movlw	06h     ;1
	movwf	40h
	movlw	5Bh     ;2
	movwf	41h
	movlw	40h     ;-
	movwf	42h	
	movlw	5Eh     ;d
	movwf	43h
	movlw	06h	;I
	movwf	44h
	movlw	6Fh	;g
	movwf	45h
	movlw	06h	;I
	movwf	46h
	movlw	78h	;t
	movwf	47h
	movlw	08h	;_
	movwf	48h
	movlw	50h	;r
	movwf	49h
	movlw	3Eh	;U
	movwf	4Ah
	movlw	37h	;N
	movwf	4Bh
	movlw	37h	;N
	movwf	4Ch
	movlw	06h	;I
	movwf	4Dh
	movlw	37h	;N
	movwf	4Eh
	movlw	6Fh	;g
	movwf	4Fh
	movlw	08h	;_
	movwf	50h
	movlw	6Dh     ;S
	movwf	51h
	movlw	06h	;I
	movwf	52h
	movlw	6Fh	;g
	movwf	53h
	movlw	37h	;N
	movwf	54h
	movlw	08h	;_
	movwf	55h		
	movlw	7Ch	;b 
	movwf	56h
	movlw	6Eh	;y	
	movwf	57h
	movlw	08h     ;_
	movwf	58h	
	movlw	78h	;t
	movwf	59h
	movlw	79h	;E
	movwf	5Ah		
	call	Set4017
	call	Transfer
	call	sw5		
	retlw	00
				
								
	;Convert 24-bit binary number in secs_low, secs_med, secs_hi 
	;(found in interrupt handler) into a bcd number
	;bcd_u_t, bcd_h_th, bcd_tth_hth, bcd_m_tm.  
	;values are transferred via the CARRY!
			

B2D		
				
	movf	secs_low,w	;save file to secs_lowtemp
	movwf	secs_lowtemp	; as original files get destroyed	
	movf	secs_med,w 
	movwf	secs_medtemp   
	movf	secs_hi,w  
	movwf   secs_hitemp

		
		
		
b2bcd   bcf	status,0	;clear the carry bit	
	movlw   .24			;for 24-bits
        movwf   cycles		;cycle counter

        clrf    bcd_u_t		; clear result area
        clrf    bcd_h_th
        clrf    bcd_tth_hth
        clrf    bcd_m_tm
        
b2bcd2  movlw   bcd_u_t 	;make pointer
        movwf   FSR
        movlw   .4
        movwf   loops


b2bcd3  movlw   0x33            
        addwf   INDF,f          ;add to both nibbles
        btfsc   INDF,3          ;test if low result > 7
        andlw   0xf0            ;low result >7 so take the 3 out
        btfsc   INDF,7          ;test if high result > 7
        andlw   0x0f            ;high result > 7 so ok
        subwf   INDF,f          ;any results <= 7, subtract back
        incf    FSR,f           ;point to next
        decfsz  loops,f
        goto    b2bcd3
        
        rlf     secs_lowtemp,f		;get another bit
        rlf     secs_medtemp,f
        rlf     secs_hitemp,f

        rlf     bcd_u_t,f        ;put it into bcd
        rlf     bcd_h_th,f
        rlf     bcd_tth_hth,f
        rlf     bcd_m_tm,f

        decfsz  cycles,f         ; all done?
        goto    b2bcd2        	 ; no, loop
        
        ;convert the BCD numbers in bcd_u_t etc  
         ;to decimal in: res_u, res_t, res_h etc
        
        
        	
	movf	bcd_u_t,0		;
	movwf	temp	
	andlw	0Fh		;remove upper nibble	
		
		
	movwf	res_u
	movf	temp,0		;move temp to w
	andlw	0F0h		;remove lower nibble	
	movwf	res_t
	swapf	res_t,1
		
	movf	bcd_h_th,0		;
	movwf	temp	
	andlw	0Fh		;remove upper nibble	
	movwf	res_h
	movf	temp,0		;move temp to w
	andlw	0F0h		;remove lower nibble	
	movwf	res_th
	swapf	res_th,1		
		
	movf	bcd_tth_hth,0		;
	movwf	temp	
	andlw	0Fh			;remove upper nibble	
	movwf	res_tth
	movf	temp,0			;move temp to w
	andlw	0F0h			;remove lower nibble	
	movwf	res_hth
	swapf	res_hth,1		
				
				
	movf	bcd_m_tm,0		;
	movwf	temp	
	andlw	0Fh			;remove upper nibble	
	movwf	res_m
	movf	temp,0			;move temp to w
	andlw	0F0h			;remove lower nibble	
	movwf	res_tm
	swapf	res_tm,1						
		
	retlw	00				
				
				
		
Clear		
		;all files from 21h to 6Fh are cleared
	movlw	4Fh	;number of files to be cleared =loops
	movwf	temp1		;		
	movlw	21h
	movwf	fsr		
	movlw	0
	movwf	00h
	incf	fsr,1
	decfsz	temp1,1
	goto	$-4			
	retlw	00
		
		
	;Clock the 4017
		
		
clock	bsf	05h,4	;clock the 4017 via RA4 
	call	_10uS			
	bcf	05h,4					
	call	_10uS	
	retlw	00
	

	;The 12 digits are scanned by making first output of 4017 HIGH 
	;and making appropriate digits LOW via PIC chip.
	;Data is taken from files 60h - 6Bh. 
	;"1" in bit0 becomes segmentA etc.    "1" in bit7=dot.
	;move the 12 files to the right and use bit0 again. Repeat 8 times.
		
		
	;Reads 6 values from EEPROM into files 31h-33h	
	;secs_low  secs_med   secs_hi		
		
Read	movlw	.3
	movwf	temp1
	movlw	30h
	movwf	fsr
	bsf	status,rp0	;select bank1	
	clrf	eeadr	
	bsf	status,rp0	;select bank1 - this instruction for loops
	bsf	EECON1,0	;starts EEPROM read operation, result in EEDATA
	movf	EEDATA,w	;move read data into w	
	incf	eeadr,1					
	bcf	status,rp0	;select bank0		
	incf	fsr,f		;fsr starts at file 31h 
	movwf	indf		;put data into file 31h
	decfsz	temp1,f
	goto	$-8
	retlw	00		
		
		
Scan	movlw	08	
	movwf	ScanLoops		
	clrf	portA
	decf	portA,1   ;make bits 0 to 3 HIGH to turn off segments
	clrf	portB
	decf	portB,1	  ;make bits 0 to 7 HIGH to turn off segments
	btfsc	60h,0
	bcf	portA,0
	btfsc	61h,0
	bcf	portA,1
	btfsc	62h,0
	bcf	portA,2
	btfsc	63h,0
	bcf	portA,3		
	btfsc	64h,0
	bcf	portB,0
	btfsc	65h,0
	bcf	portB,1
	btfsc	66h,0
	bcf	portB,2
	btfsc	67h,0
	bcf	portB,3
	btfsc	68h,0
	bcf	portB,4
	btfsc	69h,0
	bcf	portB,5
	btfsc	6Ah,0
	bcf	portB,6
	btfsc	6Bh,0
	bcf	portB,7
	call	clock		;to advance 4017 to output "0"	
	call	_500uS
	rrf	60h,1
	rrf	61h,1
	rrf	62h,1
	rrf	63h,1
	rrf	64h,1
	rrf	65h,1
	rrf	66h,1
	rrf	67h,1
	rrf	68h,1
	rrf	69h,1
	rrf	6Ah,1
	rrf	6Bh,1
	decfsz	ScanLoops,1
	goto	Scan+2
	movlw	0ffh
	movwf	PortA	;prevents bright dot
	movwf	PortB	;prevents bright dot
	retlw	00
		
			
Set4017	bsf	status,rp0
	movlw 	b'00100000'	;Set TRISA in for RA5   
	movwf	05h					
	bcf	status,rp0
	call	clock
	btfss	05h,5		;see if 4017 is at 9th output 
	goto	$-2
	call	clock		
	retlw	00	;output "10" on 4017 HIGH = before start of scan
			;to prevent anything appearing on screen
							
							
	
	;Store   Stores the seconds values 
	;secs_low  secs_med   secs_hi in EEPROM
	;stores every 500 seconds - using fsr did not work! 	
		
Store3	bsf     flags,0		;store value only once
	bsf	status,rp0	;select bank1	
	clrf	eeadr						
	bcf	status,rp0	;select bank0	
	movf	31h,w
	bsf	status,rp0	;select bank1	
	movwf	eedata		; 
	bcf	status,rp0	;select bank0
	call 	write    
	bsf	status,rp0	;select bank1	
	incf	eeadr,1						
	bcf	status,rp0	;select bank0		
	movf	32h,w
	bsf	status,rp0	;select bank1	
	movwf	eedata		; 
	bcf	status,rp0	;select bank0
	call 	write    
	bsf		status,rp0	;select bank1	
	incf	eeadr,1						
	bcf		status,rp0	;select bank0		
	movf	33h,w
	bsf		status,rp0	;select bank1	
	movwf	eedata		; 
	bcf		status,rp0	;select bank0
	call 	write    
	retlw	00
		
			
				
	
	;detect switches & generates bit 1,2,3,4,5 in Sw_Flag file
		
Sw	bsf	status,rp0			
	bcf	trisA,6		;Make bit 6 output
	bcf	status,rp0
	bsf	portA,6		;make bit 6 HIGH	
	call	_1mS		;create delay to charge 100n
	bsf	status,rp0			
	bsf	trisA,6		;Make bit 6 input
	bcf	status,rp0		
	call	_10mS
	call	_1mS
	btfss	portA,6		;if set, no sw pushed	
	goto	$+3		;sw pushed
	clrf	Sw_Flag		;no sw pressed			
	retlw	00				;
	btfsc	Sw_Flag,0	;test "first-pass" sw flag
	retlw	00						
	clrf	count
	bsf	status,rp0			
	bcf	trisA,6		;Make bit 3 output
	bcf	status,rp0
	bsf	portA,6		;make bit 3 HIGH	
	call	_1mS		;create delay to charge 100n	
	bsf	status,rp0			
	bsf	trisA,6		;Make bit 3 input
	bcf	status,rp0					
	call	_1mS		;count until cap discharged
	call	_1mS		
	incf	count,f
	btfsc	portA,6		;is input HIGH?				
	goto	$-4		;count exits with 1-5	
	decfsz	count,f			
	goto	$+3
	bsf	Sw_Flag,1	;set a flag-bit for first sw
	retlw	00		
	decfsz	count,f
	goto	$+3
	bsf	Sw_Flag,2	;set a flag-bit for second sw
	retlw	00		
	decfsz	count,f
	goto	$+3
	bsf	Sw_Flag,3	;set a flag-bit for third sw
	retlw	00		
	decfsz	count,f
	goto	$+3
	bsf	Sw_Flag,4	;set a flag-bit for fourth sw
	retlw	00		
	bsf	Sw_Flag,5	;set a flag-bit for fifth sw
	retlw	00			
		
		;Sw1 increments data on display12 


sw1	btfsc	Sw_Flag,0	;first pass? If no, return	
	retlw	00
	bsf	Sw_Flag,0	;set sw flag (clr in Sw routine)
	incf	Jump_1,1	;incr jump value 		
	movf	Jump_1,0	;set-up jump value for table 1
	call	table1		;get display data		
	movwf	5Bh		;display-12 holds the image to be incremented
	xorlw	0FFh		;see if end of table 1              
	btfss	03,2		;
	retlw	00
	clrf	5Bh
	clrf	Jump_1
	goto	sw1+3	
		
		
	;Sw2 decrements data on display12


sw2	btfsc	Sw_Flag,0	;first pass? If no, return	
	retlw	00
	bsf	Sw_Flag,0	;set sw flag (clr in Sw routine)
	movf	Jump_1,0
	xorlw	1		;see if start of table1 is reached            
	btfss	03,2
	goto	$+4
	movlw	24h		;number of values in table1	
	movwf	Jump_1
	goto	sw2	
	decf	Jump_1,1	;decr jump value 
	movf	Jump_1,0	;set-up jump value for table 1
	call	table1		;get display data
	movwf	5Bh		;display-12 holds the image to be incremented
	retlw	00	
		
		
	;sw3 store

sw3	btfsc	Sw_Flag,0	;first pass? If no, return	
	retlw	00
	bsf	Sw_Flag,0	;set sw flag (clr in Sw routine)
	movlw	0Ah
	movwf	store	;.10 loops
	movlw	50h	;start of display
	movwf	04h	;load FSR
	movf	00h,0	;move value looked at by FSR into W
	xorlw	00h	;see if display is empty              
	btfsc	03,2
	goto	$+5	;display empty			
	incf	04h,1	;display not empty	
	decfsz	store,1
	goto	$-6
	goto	$+5		;go to section that moves display left 
	movf	Jump_1,0
	call	table1
	movwf	00h
	retlw	00
	movf	40h,0	;look at file 40h 
	xorlw	00h	;see if it is empty              
	btfss	03,2
	retlw	00
	movlw	1Ah
	movwf	store	;1Ah loops
	movlw	40h	;start of block move
	movwf	04h	;load FSR
	movf	00h,0	;move value looked at by FSR into W
	decf	04h,1	;decr fsr to 2Fh
	movwf	00h	;put value into 2Fh
	incf	04h,1
	incf	04h,1
	decfsz	store,1
	goto 	$-6
	movf	5Bh,0	;move character from 12th to 10th display
	movwf	59h	;put value into 10th display		
	retlw	00
		
	;Switch4  =  [   ]   advances through extra features
	;Feature1 = Count to 10,000,000 seconds
		
		
		
sw4	clrf	Sw_Flag     ;needed to get back to Sw4 from Sw5! (RUN)
	call	_10million	;show 10,000,000 SECONdS on display
	call    Clear	
			
			
;****************************************************************
;* Start Timer1 to count 1 second in the background		*
;****************************************************************
		
	bsf	status,rp0 	;Bank 1			
	movlw	b'10000000'	; 
	movwf	OPTION_REG	; x000 0000 x=1= weak pull-ups disabled	
	bcf	status,rp0	;bank 0 		
		
	movlw	b'11000000'	;b'11000000'
	movwf 	INTCON		;,0  1=RB port change interrupt flag
				;,1  1=RB0 interrupt occurred
	;bcf	INTCON,2	;1=TMR0 overflowed. Clear overflow flag 
	;bcf	INTCON,3	;1=enable RB port change interrupt
	;bcf	INTCON,4	;1=enable RB external interrupt	
	;bsf	INTCON,5	;1=enable TMR0 overflow (interrupt)
	;bcf	INTCON,6	;1=enable all peripheral interrupts
	;bsf	INTCON,7	;1=enable all unmasked interrupts
				
	movlw	b'00110101'	;b'00110001'			
	movwf	T1CON		;,7  not used
				;,6 0=Timer1 is ON
				;,5,4  11=8 prescale (max) 01=1:2
				;,3 bit ignored
				;,2 This MUST BE SET!!!!!!
				;,1 0=int clock 
				;,0 1=enable timer1 
							
		
	bcf	PIR1,0		;clear TMR1 overflow flag
		
	clrf	TMR1L		;clear the Timer1 low register
	movlw	.12		;TMR1H needs 244 to produce 499712uS
	movwf	TMR1H		;put into Timer1 high register
				;Timer0 is not used 		
				; will go to isr when overflow occurs in TMR1	
				;499712uS when prescaler=1:8 		
		
	bsf	status,rp0 	;Bank 1	(Must use Bank1)	
	bsf	PIE1,0		;,0 1=enables TMR1 interrupt	
	bcf	status,rp0	;bank 0 
		
	call    Clear
			
	call	Read
	call	B2D	;produce values for res_u,res_t,res_h,res_th,res_tth 
			;res_hth,res_m,res_tm from secs_low, secs_med, secs_hi
							
	movlw   02
	movwf   isr_counter 
			
sw4a	
	clrf	60h
	clrf	61h
	clrf	62h
	clrf	63h
	movf	res_tm,w	;start at high end to blank the zero's		
	call	table1
	movwf	w		;if w is zero, blank the display
	btfss	status,z					
	movwf	64h		;show value in 5th display 	
	movf	res_m,w					
	call	table2	
	movwf	w		;if w is zero, blank the display
	btfss	status,z				
	movwf	65h		;show value in 6th display 
	movf	res_hth,w					
	call	table1
	movwf	w		;if w is zero, blank the display
	btfss	status,z					
	movwf	66h		;show value in 7th display 
	movf	res_tth,w					
	call	table1	
	movwf	w		;if w is zero, blank the display
	btfss	status,z				
	movwf	67h		;show value in 8th display 
	movf	res_th,w					
	call	table2	
	movwf	w		;if w is zero, blank the display
	btfss	status,z				
	movwf	68h		;show value in 9th display 
	movf	res_h,w					
	call	table1	
	movwf	w		;if w is zero, blank the display
	btfss	status,z				
	movwf	69h		;show value in 10th display 	
	movf	res_t,w					
	call	table1	
	movwf	w		;if w is zero, blank the display
	btfss	status,z				
	movwf	6Ah		;show value in 11th display 	
	movf	res_u,w					
	call	table1					
	movwf	6Bh		;show value in 12th display 
		
		
				
	call	Sw      	;see if first button has been pressed
	btfss	Sw_Flag,1 	;push first button to turn OFF display
	goto	_bb
		
	bcf	Sw_Flag,1	
	call	Sw     	;see if first button has been released
	btfsc	Sw_Flag,1 	
	goto	$-3			;
	bcf	Sw_Flag,1
	call	_250mS	
	call	_250mS

_bb	call	Set4017
	call	Scan			
	goto	sw4a


	;Sw5 is "RUN"     Runs characters across display
	;files 60h-6Fh get destroyed after SCAN, so
	;a 12-file wide window looks at 35h to 40h 
	;and transfers to 60h-6Bh for scan routine.
			
sw5	clrf	3Fh	;remove unwanted shifted data 	
	clrf	5Bh	;remove unwanted data		
	movlw	35h	;start of Ghost files   
	movwf	Ghost	
	movlw	60h	;window 60h-6Bh		
	movwf	Window			
	movlw	20h	;creates shift timing 
	movwf	RunLoops	;loops of scan 		
	movf	Ghost,0
	movwf	GhostTemp	;for incrementing
	movf	Window,0
	movwf	WindowTemp	;for incrementing		
	movlw	0Ch		;shift 12 bits of data  
	movwf	_12loops	;12 loops		
	movf	GhostTemp,0	;look at first Ghost file        
	movwf	fsr	
	movf	00h,0		;move value looked at by FSR into W
	movwf	Save		;save it		
	movf	WindowTemp,0	;load first window file
	movwf	fsr		;put into pointer
	movf	Save,0
	movwf	00h		;put value into 60h		
	incf	GhostTemp,1
	incf	WindowTemp,1
	decfsz	_12loops,1
	goto	$-.11			
	call	Set4017
	call	Scan
	decfsz	RunLoops,1
	goto	Sw5+8
	incf	Ghost,1	
	movf	Ghost,0
	xorlw	54h		;end of Ghost files? + spaces         
	btfss	03,2	
	goto	Sw5+6	
	movf	Sw_Flag,1	
	btfss	03,2		
	goto	Sw5+2		
	retlw	00		
			
	;Transfer the data in files 50h - 5Bh to 60h - 6Bh
		
Transfer		
	movlw	0Ch
	movwf	temp1	;no of loops
	movlw	50h	;start of 1st block
	movwf	04h	;load FSR
	movf	00h,0	;move value looked at by FSR into W
	bcf	04h,4
	bsf	04h,5	;turns FSR 50h to 60h
	movwf	00h
	bsf	04h,4
	bcf	04h,5	;turns FSR 60h to 50h
	incf	04h,1
	decfsz	temp1,1
	goto	$-8
	retlw	00		
		
		
write	bsf	status,rp0	;select bank1	
	bsf	eecon1,wren	;enable write		
	movlw	55h 		;unlock codes
	movwf	eecon2
	movlw	0aah
	movwf	eecon2
	bsf	eecon1,wr	;write begins
	bcf	status,rp0	;select bank0		
writeA	btfss	pir1,eeif	;wait for write to complete
	goto	writeA
	bcf	pir1,eeif
	bsf	status,rp0	;select bank1
	bcf	eecon1,wren	;disable other writes
	bcf	status,rp0	;select bank0	
	retlw	00					
					
		
					
						

;************************************
;* Main 				*
;************************************

Main	call	Set4017
	call	Transfer
	call	Scan
	call	Sw      ;see if a button has been pressed
	movf	Sw_Flag,1
	btfsc	03,2	;see if Sw_Flag is clear
	goto	Main
	btfss	Sw_Flag,1
	goto	$+3			
	call	sw1	;increment data for display12.
	goto	Main
	btfss	Sw_Flag,2
	goto	$+3
	call	sw2	;decrement data for display12.
	goto	Main
	btfss	Sw_Flag,3
	goto	$+3
	call	sw3	;store
	goto	Main		
	btfss	Sw_Flag,4
	goto	$+3
	call	sw4	;got to extra features
	goto	Main
	btfsc	Sw_Flag,5				
	goto	sw5	;RUN
	goto	Main
		
		
;********************************
;*EEPROM     Values in EEPROM	*
;********************************
								
	org	2100h	;locations 00 to 03		
	de	00h, 00h, 00h			
		
			
	END

GOING FURTHER
You can add further features to the project via the [  ] button.

If you have any other questions, contact Colin Mitchell via email.

P1
 


  1/1/2011