Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

1 Hour Timer PIC 16F628A (Set Button)

Status
Not open for further replies.

Suraj143

Active Member
Hi I’m doing a small project using PIC16F628A.It’s a one hour timer.
It’s having two digits & it’s having only two buttons,

RA2 - count up button
RA3 – set button
RB7 – output LED

I wrote a program listed below. The counting part works very well. Every time when I press the count up button it counts to 0 to 59 at each press. It works well.
Code:
	 LIST	p=16F628A		
	 include "P16F628A.inc"		

 	 cblock	0x20
	 DIGIT1	 
	 DIGIT2	 
	 d1	 
	 d2	 
	 d3	 
	 d4
	 Flag	 
	 endc

PC	 EQU 	02H
STATUS   EQU 	03H
PORTA	 EQU 	05H
PORTB	 EQU 	06H
TRISA	 EQU 	85H
TRISB	 EQU 	86H
CMCON	 EQU	1FH

	 org	0x00

	 movlw	0x07
	 movwf	CMCON		;turn comparators off

	 bsf 	STATUS,5
	 movlw 	b'01100'	;RA2,RA3 inputs
	 movwf 	TRISA
	 movlw 	b'00000000'	;portB all outputs
	 movwf 	TRISB
	 bcf 	STATUS,5
	 clrf	Flag
	
	 goto 	START

	
TABLE 	 addwf	PC,1
	 retlw 	b'00111111'	;0
	 retlw	b'00000110'	;1
	 retlw	b'01011011'	;2
	 retlw	b'01001111'	;3
	 retlw	b'01100110'	;4
	 retlw	b'01101101'	;5
	 retlw	b'01111101'	;6
	 retlw	b'00000111'	;7
	 retlw	b'01111111'	;8
	 retlw	b'01101111'	;9
	 
START	 clrf 	DIGIT1	
	 clrf	DIGIT2	

;***********display the digit1***************

STAY	 bcf	Flag,0		;clear the button press flag
LOOP	 bcf	PORTA,0		;disable digit2
	 movf	DIGIT1,0
	 call	TABLE
	 movwf	PORTB
	 bsf	PORTA,1		;enable digit1
	 call	Delay
	

;***********display the digit2***************

	 bcf 	PORTA,1		;disable digit1
	 movf 	DIGIT2,0
	 call 	TABLE
	 movwf 	PORTB
	 bsf 	PORTA,0		;enable digit2
	 call 	Delay

;**********check the button is pressed*******


MAIN	 btfsc 	PORTA,2		;test the button on portA
	 goto 	STAY
	 call 	DELAY1		;debounce delay
	 btfsc 	PORTA,2
	 goto 	STAY
	 btfsc 	Flag,0		;button pressed first time(calling a flag)
	 goto 	LOOP
	 goto 	COUNTUP

	
;**********update digit1 & digit2************


COUNTUP  incf 	DIGIT1,1	;increase digit1
	 movlw 	0AH		;load with ten
	 xorwf 	DIGIT1,0	;compare
	 btfss 	STATUS,2
	 goto 	LOOP1
	 clrf 	DIGIT1
	 incf 	DIGIT2,1	;increase digit2
	 movlw 	06H		;load with six
	 xorwf 	DIGIT2,0	;compare
	 btfsc 	STATUS,2
	 clrf 	DIGIT2
LOOP1	 bsf 	Flag,0		;set button press flag
	 goto 	LOOP

;-------------display delay 10ms------------------------

Delay  	 movlw	0xcF	;10ms
	 movwf	d3
	 movlw	0x08
	 movwf	d4
Delay_1
	 decfsz	d3, f
	 goto	$+2
	 decfsz	d4, f
	 goto	Delay_1
	 goto	$+1
         RETURN
	
;--------button debounce delay 0.0009S------------------

DELAY1	 movlw	0xB3
	 movwf	d1
	 movlw	0x01
	 movwf	d2
Delay_0
	 decfsz	d1, f
	 goto	$+2
	 decfsz	d2, f
	 goto	Delay_0
	 goto	$+1
	 RETURN

         end
Now I want to use the other button (set button).If you count up 5 & press the set button it must give a 5 minutes delay. If you count up 10 & press the set button it must give 10 minutes delay etc…

Calculating delays of course ok. But I don’t know how to detect the value at present.
What’s the coding do I have to write? Where is the best place to keep the set button coding?

But I tried something like this to detect the value at present. I don’t know whether its right please helps me.
Code:
btfsc	PORTA,3		;test the SET button RA3
	goto	
	call	DELAY1		;debounce delay
	btfsc	PORTA,3
	goto
	btfsc	Flag,0
	goto
	goto	Detect1

Detect1	movlw	01H		;Detects number 1
	xorwf	DIGIT1,0
	btfss	STATUS,2
	goto	Detect2		;its not 1 then goto next
	goto	Delay1min	;call 1minute delay

Detect2 movlw	02H		;Detects number 2
	xorwf	DIGIT1,0
	btfss	STATUS,2
	goto	Detect3		;its not 2 then goto next
	goto	Delay2min	;call 2minutes delay

Detect3	----
	----

Thanks
 
Your code will have a lot of overhead as the 10mS delay is just that - a 10mS delay, and your performing other tasks in between = drift

Interrupts and a higher language would make this program pie. This is a generic counter that uses interrupts instead of crude delays.
It will be by far more accurate, and might open a whole new area in PIC programming you have though of before :eek:
Code:
Device = 16F628A
Xtal = 4
   
Dim uS as Word
Dim mS as Word
Dim S as Byte	
Dim M as Byte
Dim H as Word

Symbol GIE = INTCON.7				' Global Interrupt Enable Bit
Symbol TMR0_uS = 256		  		' Set time interval of TMR0
Symbol TMR0_Enable = INTCON.5			' This option enables TMR0 interrupts
Symbol TMR0_Overflow = INTCON.2			' This is the TMR0 overflow flag

Symbol Snap_Shot = PORTA.0

ON_INTERRUPT Int_Sub

Goto Initialization			
			
Int_Sub:
	
	If TMR0_Overflow = 1 And TMR0_Enable = 1 Then
	   TMR0_Overflow = 0
	   uS = uS + TMR0_uS
	   If uS >= 1000 Then
	   	  uS = uS - 1000
	  	  mS = mS + 1
		  If mS >= 1000 Then 
		  	 mS = 0
			 S = S + 1
                         If S >= 60 Then 
                             S = S - 60
                             M = M + 1
             	             If M >= 60 Then 
                                   M = M - 60
                                   H = H + 1 	
			     EndIf			
			 EndIf			 
		  EndIf
	   EndIf
	EndIf
	
	GIE = 1
	
	Context Restore                          ' Restore settings and return to main program.
	
Initialization:

	ALL_DIGITAL = True
	
	Input Snap_Shot	  			 ' Make PORTA.0 (defined earlier as snapshot) an input
	
	TMR0_Enable = 0	   	   	 	 ' Disable TMR0 interrupts
	
	uS = 0		  			 ' Clear timer registers
	mS = 0					 ' 
	S = 0					 '

	OPTION_REG.0 = 0   			 '000	-	1 : 2
	OPTION_REG.1 = 0			 '
	OPTION_REG.2 = 0			 '
	OPTION_REG.5 = 0			 ' Select Internal Clock Source

	TMR0 = 0	   			 ' Clear the TMR0 register
	
	uS = 0                                   ' Reset all Counters
	mS = 0
	S = 0
	M = 0
	H = 0	
	
	TMR0_Enable = 1				' Enable TMR0 Interrupts
	
	GIE = 1		  			' Enable Global Interrupts
		
Main:

	Print At 1, 1, DEC2 H, ":", DEC2 M, ":", DEC2 S 
	
	If Snap_Shot = 1 Then
	   	Print At 2, 1, DEC2 H, ":", DEC2 M, ":", DEC2 S, ":", DEC3 mS 
	EndIf
	
	Goto Main				' Loop for ever

Watch the Program/Circuit in action here.

Click on the above link to watch the program work

:)
 
Last edited:
I'm a new comer to this PIC world.I cannot understand any programming language other than Assembly.Thanks gramo for your help

A little more about the operation of this circuit

when I press the countup button (RA2) the two segments won't counts up automatically to 60. It counts up
one by one at each press.ex:if I press count up button it will display 1.And again if I press count up button it will display 2. etc....

upto this stage its working fine.Now I want to add the other button (RA3).

For example if I count up to number 3 ( three presses) and press the set button (RA3) it must call the 3 minutes delay.
or if I count up to number 10 (ten presses) and press the set button (RA3) it must call the 10 minutes delay...like that same like a timer.

Now my problem is how the set button (RA3) detects the value that I count ( I already counts up & in the segments now its showing the value) the value must detect the set button how to detect that? I have posted a code please see I need help.

Actually I want this to do without interupts,using delay routines....

thank a lot.
 
Last edited:
Why don't you count down in your main loop. Use a bit in your Flag variable to indicate whether the clock is running or not and count the number of times through the loop. You can then count seconds and decrement your digit variables. This will have the added advantage that the digits will count down.

Something like,
Code:
STAY	 bcf	Flag,0		;clear the button press flag
LOOP	 bcf	PORTA,0		;disable digit2
	 movf	DIGIT1,0
	 call	TABLE
	 movwf	PORTB
	 bsf	PORTA,1		;enable digit1
	 call	Delay
	
;***********display the digit2***************

	 bcf 	PORTA,1		;disable digit1
	 movf 	DIGIT2,0
	 call 	TABLE
	 movwf 	PORTB
	 bsf 	PORTA,0		;enable digit2
	 call 	Delay

	btfsc	Flag,1		;is time running
	goto	MAIN		; no, do other stuff
	decfsz	LoopCount,F	;count 50 times round loop
	goto	LOOP		;50*20mS = 1 second
	movlw	.50
	movwf	LoopCount
	incf	Seconds,F	;count seconds
	movlw	.60		;reached 60
	xorwf	Seconds,W
	btfss	STATUS,Z
	goto	LOOP		;no, loop around
	decf	DIGIT1,F	;yes, decrement digit 1
	btfss	DIGIT1,7	;gone negative?
	goto	LOOP
	clrf	DIGIT1
	decf	DIGIT2,F	; do second digit
	btfss	DIGIT2,7
	goto	LOOP
	clrf	DIGIT2
	bcf	Flag,1		;both are zero so stop counter

;**********check the button is pressed*******
MAIN	 btfsc 	PORTA,2		;test the button on portA

HTH

Mike.
 
Hi mike thanks for your usefull input.really a nice method.you have save an input button also, so I need only the countup button.

I gathered your codings and made the full code as below.

But the output is always displaying "00" when I press RA2 it wont increment.all the time its showing "00"

Code:
	  LIST	  p=16F628A		
	  include "P16F628A.inc"		

 	  cblock 0x20
	  DIGIT1	 
	  DIGIT2	 
	  d1	 
	  d2	 
	  d3	 
	  d4
	  Flag
	  LoopCount
	  Seconds
	  endc

PC	  EQU	02H
STATUS    EQU 	03H
PORTA	  EQU 	05H
PORTB	  EQU 	06H
TRISA	  EQU 	85H
TRISB	  EQU 	86H
CMCON	  EQU	1FH


	  org	0x00

	  movlw	0x07
	  movwf	CMCON		;turn comparators off

	  bsf 	STATUS,5
	  movlw b'01100'	;RA2,RA3 inputs
	  movwf TRISA
	  movlw b'00000000'	;portB all outputs
	  movwf TRISB
	  bcf 	STATUS,5
	  	
	  goto 	START

	
TABLE 	  addwf	PC,1
	  retlw b'00111111'	;0
	  retlw	b'00000110'	;1
	  retlw	b'01011011'	;2
	  retlw	b'01001111'	;3
	  retlw	b'01100110'	;4
	  retlw	b'01101101'	;5
	  retlw	b'01111101'	;6
	  retlw	b'00000111'	;7
	  retlw	b'01111111'	;8
	  retlw	b'01101111'	;9
	 
START	  clrf	Flag
	  clrf 	DIGIT1	
	  clrf	DIGIT2	
	  clrf 	LoopCount
	  clrf	Seconds
	
;***********display the digit1***************

STAY	  bcf	Flag,0		;clear the button press flag
LOOP	  bcf	PORTA,0		;disable digit2
	  movf	DIGIT1,0
	  call	TABLE
	  movwf	PORTB
	  bsf	PORTA,1		;enable digit1
	  call	Delay
	

;***********display the digit2***************

	  bcf 	PORTA,1		;disable digit1
	  movf 	DIGIT2,0
	  call 	TABLE
	  movwf PORTB
	  bsf 	PORTA,0		;enable digit2
	  call 	Delay

;******************Mikes Codings*******************

	  btfsc	 Flag,1		;is time running
	  goto	 MAIN		;no, do other stuff
	  decfsz LoopCount,1	;count 50 times round loop
	  goto	 LOOP		;50*20mS = 1 second
	  movlw	 32H
	  movwf	 LoopCount
	  incf	 Seconds,1	;count seconds
	  movlw	 3CH		;reached 60
	  xorwf	 Seconds,0
	  btfss	 STATUS,2
	  goto	 LOOP		;no, loop around
	  decf	 DIGIT1,1	;yes, decrement digit 1
	  btfss	 DIGIT1,7	;gone negative?
	  goto	 LOOP
	  clrf	 DIGIT1
	  decf	 DIGIT2,1	; do second digit
	  btfss	 DIGIT2,7
	  goto	 LOOP
	  clrf	 DIGIT2
	  bcf	 Flag,1		;both are zero so stop counter


;**********check the button is pressed**************


MAIN	 btfsc 	PORTA,2		;test the button on portA
	 goto 	STAY
	 call 	DELAY1		;debounce delay
	 btfsc 	PORTA,2
	 goto 	STAY
	 btfsc 	Flag,0		;button pressed first time(calling a flag)
	 goto 	LOOP
	 goto 	COUNTUP

	
;**********update digit1 & digit2************


COUNTUP  incf 	DIGIT1,1	;increase digit1
	 movlw 	0AH		;load with ten
	 xorwf 	DIGIT1,0	;compare
	 btfss 	STATUS,2
	 goto 	LOOP1
	 clrf 	DIGIT1
	 incf 	DIGIT2,1	;increase digit2
	 movlw 	06H		;load with six
	 xorwf 	DIGIT2,0	;compare
	 btfsc 	STATUS,2
	 clrf 	DIGIT2
LOOP1	 bsf 	Flag,0		;set button press flag
	 goto 	LOOP


;-------------display delay 10ms------------------------

Delay  	 movlw	0xcF	;10ms
	 movwf	d3
	 movlw	0x08
	 movwf	d4
Delay_1
	 decfsz	d3, f
	 goto	$+2
	 decfsz	d4, f
	 goto	Delay_1
	 goto	$+1
         RETURN
	
;--------button debounce delay 0.0009S------------------

DELAY1	 movlw	0xB3
	 movwf	d1
	 movlw	0x01
	 movwf	d2
Delay_0
	 decfsz	d1, f
	 goto	$+2
	 decfsz	d2, f
	 goto	Delay_0
	 goto	$+1
	 RETURN

         end
I made some experiments by adding this line

Code:
bsf	 Flag,1	;after stoping the counters again set the flag bit
in various places, after its starts to increment but the count down timer is not working.

what will be the problem?

Thanks alot.
 
Woops,
Code:
;******************Mikes Codings*******************

	  btfs[COLOR="Red"]s[/COLOR]	 Flag,1		;is time running
	  goto	 MAIN		;no, do other stuff
	  decfsz LoopCount,1	;count 50 times round loop

That's what happens when you write untested code.

You should also test your other button and do a bsf Flag,1 to start the count down.

Mike.
 
Hi Mike the problem was that line now I can count up.But,

Without bsf Flag,1 the program counts well when I press count up button at each press.But after adding bsf Flag,1 code I cannot count up over the value "01" .That means when I press count up button the two segments its showing "01" cannot count any more but after 1 minute its decrement.After reaching to zero again after very long time I can count up.Again its counts to value "01" only when I press.

I think the problem with the bsf Flag,1 I put this line to many places & check but cannot count up more than "01" I dont know where
is the best place this line......

Code:
	  LIST	  p=16F628A		
	  include "P16F628A.inc"		

 	  cblock 0x20
	  DIGIT1	 
	  DIGIT2	 
	  d1	 
	  d2	 
	  d3	 
	  d4
	  Flag
	  LoopCount
	  Seconds
	  endc

PC	  EQU	02H
STATUS    EQU 	03H
PORTA	  EQU 	05H
PORTB	  EQU 	06H
TRISA	  EQU 	85H
TRISB	  EQU 	86H
CMCON	  EQU	1FH


	  org	0x00

	  movlw	0x07
	  movwf	CMCON		;turn comparators off

	  bsf 	STATUS,5
	  movlw b'01100'	;RA2,RA3 inputs
	  movwf TRISA
	  movlw b'00000000'	;portB all outputs
	  movwf TRISB
	  bcf 	STATUS,5
	  	
	  goto 	START

	
TABLE 	  addwf	PC,1
	  retlw b'00111111'	;0
	  retlw	b'00000110'	;1
	  retlw	b'01011011'	;2
	  retlw	b'01001111'	;3
	  retlw	b'01100110'	;4
	  retlw	b'01101101'	;5
	  retlw	b'01111101'	;6
	  retlw	b'00000111'	;7
	  retlw	b'01111111'	;8
	  retlw	b'01101111'	;9
	 
START	  clrf	Flag
	  clrf 	DIGIT1	
	  clrf	DIGIT2	
	  clrf 	LoopCount
	  clrf	Seconds
	  [COLOR="Red"][B]movlw	32H
	  movwf LoopCount[/B][/COLOR]
	 
	
;***********display the digit1***************

STAY	  bcf	Flag,0		;clear the button press flag
LOOP	  bcf	PORTA,0		;disable digit2
	  movf	DIGIT1,0
	  call	TABLE
	  movwf	PORTB
	  bsf	PORTA,1		;enable digit1
	  call	Delay
	

;***********display the digit2***************

	  bcf 	PORTA,1		;disable digit1
	  movf 	DIGIT2,0
	  call 	TABLE
	  movwf PORTB
	  bsf 	PORTA,0		;enable digit2
	  call 	Delay

;******************Mikes Codings*******************

	  btfss	 Flag,1		;is time running
	  goto	 MAIN		;no, do other stuff
	  decfsz LoopCount,1	;count 50 times round loop
	  goto	 LOOP		;50*20mS = 1 second
	  movlw	 32H
	  movwf	 LoopCount
	  incf	 Seconds,1	;count seconds
	  movlw	 3CH		;reached 60
	  xorwf	 Seconds,0
	  btfss	 STATUS,2
	  goto	 LOOP		;no, loop around
	  decf	 DIGIT1,1	;yes, decrement digit 1
	  btfss	 DIGIT1,7	;gone negative?
	  goto	 LOOP
	  clrf	 DIGIT1
	  decf	 DIGIT2,1	; do second digit
	  btfss	 DIGIT2,7
	  goto	 LOOP
	  clrf	 DIGIT2
	  bcf	 Flag,1		;both are zero so stop counter
	
	  
;**********check the button is pressed**************


MAIN	 btfsc 	PORTA,2		;test the button on portA
	 goto 	STAY
	 call 	DELAY1		;debounce delay
	 btfsc 	PORTA,2
	 goto 	STAY
	 btfsc 	Flag,0		;button pressed first time(calling a flag)
	 goto 	LOOP
	 goto 	COUNTUP

	
;**********update digit1 & digit2************

COUNTUP  [COLOR="Red"][B]bsf	Flag,1		;enable counter[/B][/COLOR]
	 incf 	DIGIT1,1	;increase digit1
	 movlw 	0AH		;load with ten
	 xorwf 	DIGIT1,0	;compare
	 btfss 	STATUS,2
	 goto 	LOOP1
	 clrf 	DIGIT1
	 incf 	DIGIT2,1	;increase digit2
	 movlw 	06H		;load with six
	 xorwf 	DIGIT2,0	;compare
	 btfsc 	STATUS,2
	 clrf 	DIGIT2
LOOP1	 bsf 	Flag,0		;set button press flag
	 goto 	LOOP


;-------------display delay 10ms------------------------

Delay  	 movlw	0xcF	;10ms
	 movwf	d3
	 movlw	0x08
	 movwf	d4
Delay_1
	 decfsz	d3, f
	 goto	$+2
	 decfsz	d4, f
	 goto	Delay_1
	 goto	$+1
         RETURN
	
;--------button debounce delay 0.0009S------------------

DELAY1	 movlw	0xB3
	 movwf	d1
	 movlw	0x01
	 movwf	d2
Delay_0
	 decfsz	d1, f
	 goto	$+2
	 decfsz	d2, f
	 goto	Delay_0
	 goto	$+1
	 RETURN

         end
 
You should use a button on RA3 to set Flag,1 and start the timer.

Try,
Code:
MAIN	btfsc	PORTA,3		;test start button
	goto	NotA3
	call	DELAY1
	btfsc	PORTA,3
	goto	NotA3
	bsf	Flag,1		;start counter
NotA3    btfsc 	PORTA,2		;test the button on portA
	 goto 	STAY
	 call 	DELAY1		;debounce delay
	 btfsc 	PORTA,2
	 goto 	STAY
	 btfsc 	Flag,0		;button pressed first time(calling a flag)
	 goto 	LOOP
	 goto 	COUNTUP

	
;**********update digit1 & digit2************

COUNTUP  incf 	DIGIT1,1	;increase digit1

You obviously understand how the code works as you worked out that you needed to initialise LoopCount. It Looks like you are a fast learner.

When you get it working, there is a much better way to do your delays.

HTH

Mike.
 
Hi mike,there was a small mistake in my codings,earlier I haven't add the other button (RA3) codings.
also I haven't clear the Seconds.now the count down is working.

I want to change the number patern when count down.
That means if I select the number "21" and set the timer the display pattern must countdown like this
21,20,19,18,17,16.........0 minutes.
The problem is when the first digit comes to "0" it wont show "9" after a minute.
This means after "21" its showing "20" after that it should show "19" but now its showing "20"

The first digits "0" it wont detect.after detecting it must show the "9" after a minute.also it must decrement
the digit2.

I made some experiments like this.but cant rescue the problem.
any ideas?

Code:
;******************Mikes Codings*******************

	  btfss	 Flag,1		;is time running
	  goto	 MAIN		;no, do other stuff
	  decfsz LoopCount,1	;count 50 times round loop
	  goto	 LOOP		;50*20mS = 1 second
	  movlw	 32H
	  movwf	 LoopCount
	  incf	 Seconds,1	;count seconds
	  movlw	 3CH		;reached 60
	  xorwf	 Seconds,0
	  btfss	 STATUS,2
	  goto	 LOOP		;no, loop around

	  decf	 DIGIT1,1	;yes, decrement digit 1
	 [B] movlw  00H		;load with Zero
	  xorwf  DIGIT1,0	;compare whether is it zero
	  btfss  STATUS,2
	  goto	 LOOP2		;no its not zero
	  
	  ????????????		;yes its not zero[/B]
	  
	  decf	 DIGIT2,1	;do second digit
	  movlw  00H		;load with zero
	  xorwf  DIGIT2,0	;compare whether is it zero
	  btfss  STATUS,2
	  goto	 LOOP2		;no its not zero
	  clrf	 DIGIT2

	  bcf	 Flag,1		;both are zero so stop counter
	  goto	 START
	  

LOOP2	  clrf	 Seconds
	  goto	 LOOP
 
I see what you are trying to do now. Whenever the button is pressed it should increment the count AND start the timer. To do this you need to initialise things when the button is pressed and check the button all the time.

Try this,
Code:
START	  clrf	Flag
	  clrf 	DIGIT1	
	  clrf	DIGIT2	
	 	
;***********display the digit1***************

STAY	  bcf	Flag,0		;clear the button press flag
LOOP	  bcf	PORTA,0		;disable digit2
	  movf	DIGIT1,0
	  call	TABLE
	  movwf	PORTB
	  bsf	PORTA,1		;enable digit1
	  call	Delay
	
;***********display the digit2***************

	  bcf 	PORTA,1		;disable digit1
	  movf 	DIGIT2,0
	  call 	TABLE
	  movwf PORTB
	  bsf 	PORTA,0		;enable digit2
	  call 	Delay

;******************Mikes Codings*******************

	  btfss	 Flag,1		;is time running
	  goto	 MAIN		;no, do other stuff
	  decfsz LoopCount,1	;count 50 times round loop
	  goto	 [COLOR="Red"]MAIN[/COLOR]		;50*20mS = 1 second
	  movlw	 32H
	  movwf	 LoopCount
	  incf	 Seconds,1	;count seconds
	  movlw	 3CH		;reached 60
	  xorwf	 Seconds,0
	  btfss	 STATUS,2
	  goto	 [COLOR="Red"]MAIN[/COLOR]		;no, loop around
	  decf	 DIGIT1,1	;yes, decrement digit 1
	  btfss	 DIGIT1,7	;gone negative?
	  goto	 [COLOR="Red"]MAIN
	  movlw  9		;Set digit 1 to 9
	  movwf	 DIGIT1[/COLOR]
	  decf	 DIGIT2,1	; do second digit
	  btfss	 DIGIT2,7
	  goto	 [COLOR="Red"]MAIN[/COLOR]
	  clrf	 DIGIT2
	  [COLOR="Red"]clrf	 DIGIT1[/COLOR]
	  bcf	 Flag,1		;both are zero so stop counter
	
	  
;**********check the button is pressed**************


MAIN	 btfsc 	PORTA,2		;test the button on portA
	 goto 	STAY
	 call 	DELAY1		;debounce delay
	 btfsc 	PORTA,2
	 goto 	STAY
	 btfsc 	Flag,0		;button pressed first time(calling a flag)
	 goto 	LOOP
	 goto 	COUNTUP

	
;**********update digit1 & digit2************

COUNTUP  bsf	Flag,1		;enable counter
	[COLOR="Red"]clrf 	Seconds	    ;<------------moved from above
	movlw	32H
	movwf LoopCount[/color]
	 incf 	DIGIT1,1	;increase digit1
	 movlw 	0AH		;load with ten
	 xorwf 	DIGIT1,0	;compare
	 btfss 	STATUS,2
	 goto 	LOOP1
	 clrf 	DIGIT1
	 incf 	DIGIT2,1	;increase digit2
	 movlw 	06H		;load with six
	 xorwf 	DIGIT2,0	;compare
	 btfsc 	STATUS,2
	 clrf 	DIGIT2
LOOP1	 bsf 	Flag,0		;set button press flag
	 goto 	LOOP

I'd also did the decrement wrong. It now sets it to 9 after it decrements past zero.

Mike.
 
Last edited:
Hi Mike your earlier code worked well.no need to check the button always.Now almost 95% ok.can countup & count down.The code should be Like this. I added the RA3 (set button) to the codes.Accuracy is perfect.

Code:
;******************Mikes Codings*******************

	  btfss	 Flag,1		;is time running
	  goto	 MAIN		;no, do other stuff
	  decfsz LoopCount,1	;count 50 times round loop
	  goto	 [COLOR="Red"]LOOP	[/COLOR]	;50*20mS = 1 second
	  movlw	 32H
	  movwf	 LoopCount
	  incf	 Seconds,1	;count seconds
	  movlw	 3CH		;reached 60
	  xorwf	 Seconds,0
	  btfss	 STATUS,2
	  goto	 [COLOR="Red"]LOOP	[/COLOR]	;no, loop around
	  decf	 DIGIT1,1	;yes, decrement digit 1
	  btfss	 DIGIT1,7	;gone negative?
	  [COLOR="Red"]goto	 LOOP2[/COLOR]
	  movlw  09H		;Set digit 1 to 9
	  movwf	 DIGIT1
	  decf	 DIGIT2,1	;do second digit
	  btfss	 DIGIT2,7	;gone negative?
	  [COLOR="Red"]goto	 LOOP2[/COLOR]
	  clrf	 DIGIT2
	  clrf	 DIGIT1
	  bcf	 Flag,1		;both are zero so stop counter
	  [COLOR="Blue"][B]bsf	 PORTA,4	;turn on the output[/B][/COLOR]
	  goto	 START
	 	  	  
[COLOR="Blue"][COLOR="Red"][B]LOOP2	  clrf	 Seconds
	  goto	 LOOP[/B][/COLOR][/COLOR]

;**********check the button is pressed**************


MAIN	 [COLOR="Red"][B] btfsc PORTA,3		;test the set button on portA
	  goto	MAIN1
	  call 	DELAY1		;debounce delay
	  bsf	Flag,1[/B][/COLOR]

MAIN1	  btfsc PORTA,2		;test the count up button on portA
	  goto 	STAY
	  call 	DELAY1		;debounce delay
	  btfsc PORTA,2
	  goto 	STAY
	  btfsc Flag,0		;button pressed first time(calling a flag)
	  goto 	LOOP
	  goto 	COUNTUP
A small problem occures after reaches to "00" both digits.

I added an extra output after the both digits reaches to zero.But the output goes high after
increasing another extra minute.
That means if I set "10" minutes it counts down nicely.after reaches to "00" (zero) the both digits,
its counting another extra minute & turns on the output(but the both digits showing "00").I dont know why is this?
 
Hi now everything is working fine I made some changes in the coding.

Code:
;******************Mikes Codings*******************

	  btfss	 Flag,1		;is time running
	  goto	 MAIN		;no, do other stuff
	  decfsz LoopCount,1	;count 50 times round loop
	  goto	 LOOP		;50*20mS = 1 second
	  movlw	 32H
	  movwf	 LoopCount
	  incf	 Seconds,1	;count seconds
	  movlw	 3CH		;reached 60
	  xorwf	 Seconds,0
	  btfss	 STATUS,2
	  goto	 LOOP		;no, loop around
	  decf	 DIGIT1,1	;yes, decrement digit 1
	  [COLOR="Red"][B]movlw	 00H
	  xorwf	 DIGIT1,0
	  btfss	 STATUS,2
	  goto	 CDOWN
	  movlw	 00H
	  xorwf  DIGIT2,0
	  btfss	 STATUS,2
	  goto	 CDOWN
	  goto	 OUTPUT[/B][/COLOR]
	  
CDOWN	  btfss	 DIGIT1,7	;gone negative?
	  goto	 LOOP2
	  movlw  09H		;Set digit 1 to 9
	  movwf	 DIGIT1
	  decf	 DIGIT2,1	;do second digit
	  btfss	 DIGIT2,7	;gone negative?
	  goto	 LOOP2
OUTPUT	  clrf	 DIGIT2
	  clrf	 DIGIT1
	  bcf	 Flag,1		;both are zero so stop counter
	  bsf	 PORTA,4	;turn on the output
	  goto	 START
	 	  	  
LOOP2	  clrf	 Seconds
	  goto	 LOOP

;**********check the button is pressed**************


MAIN	  btfsc PORTA,3		;test the set button on portA
	  goto	MAIN1
	  call 	DELAY1		;debounce delay
	  bsf	Flag,1

MAIN1	  btfsc PORTA,2		;test the count up button on portA
	  goto 	STAY
	  call 	DELAY1		;debounce delay
	  btfsc PORTA,2
	  goto 	STAY
	  btfsc Flag,0		;button pressed first time(calling a flag)
	  goto 	LOOP
	  goto 	COUNTUP

Thanks a lot Mike.You have helped me a lot...
 
Status
Not open for further replies.

Latest threads

Back
Top