# PIC 16F877 timer

Status
Not open for further replies.

#### patricktran

##### New Member
Hi all,
My name is Patrick. This is my first time in this forum.
I ve just bought a PIC 16F877. Wow, so exciting, and I wanted to build my own first application. Well, I dont know if it is feasible or not, because I am a newbie in this field!

Ok, this is the specification:
This timer is for marital arts, which allows me to select number of rounds, duration of round, and break time. Current time will be shown on a LCD. So I reckond, the max period of time should be around 5 mins. There are 3 buttons, which are stop, reset and start.

1. There are many timers inside the chip such as TMR0,1,2,3 and even Watchdog timer. I dont know which one to use. If the max time is 5 mins, I think I can use Timer ) with 8 bit input.

2. I get an idea to use the crystal, but if so, I wont use teh CHIP I like make use of the chip.

3. How can I implement the button?

Thanks
Have a good day
Patrick

#### Nigel Goodwin

##### Super Moderator
Have a look at my tutorials, it should give you a few ideas.

Timer1 is probably the best for your purposes, you can easily use it to generate regular interrupts which you count for your basic clock - for example, generate 1mS interrupts and count 1000 of them to increment the seconds counter.

Interesting you are building a martial arts timer, which martial art do you do?, I'm a 2nd Dan in Ju Jitsu and a registered instructor and grading examiner.

#### kitedude

##### New Member
easiest way to program a pic i find is in c

you can download a trial version of the ccs compilier at www.ccsinfo.com

you dont have to worry about memory locations. the code is ineffficent but a hell of alot easier

#### patricktran

##### New Member
Hi, thanks for your replies. It will take me awhile to read the tutorials. But realy realy I found these tutorials so useful. Thanks again. :wink:
I am abit more confident in high level programming language. I think this timer can be done by using C language, but honestly, I want to take this as a chance to learn more about assembly language. :shock:
Well, I think this timer can be used in Karate, or Kick boxing. The max time would be 5 mins. It sounds so limitted, but I hope I can improve the timer when I get it done for basic functions.
I am on holidays now, so full time working for ...PIC16f877
Thanks

#### patricktran

##### New Member
Hi,
I understand prescale of a timer. say timer counts from 256 to 0. If the prescale is 1:16 then the timer will generate an interrupt after 256*16 counts.
How about postscale? is it important?
Thanks

thanks

#### Nigel Goodwin

##### Super Moderator
patricktran said:
Hi,
I understand prescale of a timer. say timer counts from 256 to 0. If the prescale is 1:16 then the timer will generate an interrupt after 256*16 counts.
How about postscale? is it important?
Thanks
It depends what you want to do, prescale divides the clock down before it enters the timer, postscale divides the output from the timer - so a postscale of 4 would generate an interrupt every 4 timer transitions.

#### patricktran

##### New Member
Thanks very much. Your site is so great.
So basically, they are quite similar? I reckon it it possible to write this program with only prescale. Is it right?

#### Nigel Goodwin

##### Super Moderator
patricktran said:
Thanks very much. Your site is so great.
So basically, they are quite similar? I reckon it it possible to write this program with only prescale. Is it right?
Yes, you only need to use one - personally I would suggest using Timer1 rather than Timer0, it's probably easier to generate regular interrupts with.

#### patricktran

##### New Member
Hi,
I left the Timer part for latter. I think it is easier to do the push button first.
Here is my code:
Code:
 title  "ledon - Turn on a LED when a Button is Pressed"

include "D:/p16F877.inc"
__config (_CP_OFF & _PWRTE_ON & _HS_OSC & _WDT_ON & _BODEN_ON & _LVP_OFF & _DEBUG_ON)
errorlevel -302

;;;;;;;;Vectors  ;;
org	H'000'
goto	MainLine
org	H'004'
goto	IntService
Stop
goto	Stop

;;;Interrupt Service;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

IntService
retfie
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;; Initial Subroutine;;;;
Initial

bcf		STATUS,RP0	;
bcf		STATUS, RP1	; Bank 0 selected
clrf	PORTC
clrf	PORTB
bsf		STATUS,RP0	; Bank 1 selected
movlw	H'00'		 ; All pins of PORTC outputs
movwf	TRISC
movlw	H'11'
movwf	TRISB		; All pins of PORTB inputs
bcf		STATUS,RP0	; Bank 0 selected
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MainLine
call 	Initial
MainLoop
btfsc   PORTB,0     ; check Button 1, if it is not pushed, skip the next step
goto    B1_routine
btfsc   PORTB,1     ; check Button 2, if it is not pushed, skip the next step
goto    B2_routine
goto    TurnOff		;  if bit 0 is 1, goto Turnoff
B1_routine
movlw   b'10101010'
movwf	PORTC
goto  	MainLoop
B2_routine
movlw   b'01010101'
movwf	PORTC
goto  	MainLoop
TurnOff
clrf		PORTC
goto  	MainLoop
end
Basically, I want 2 buttons, Button 1 at PB0, and Button 2 at PB1.
Button 1: shows 10101010 in port C
Button 2: shows 01010101 in port C
I wanted to test it in the MPLAB, but when I tried to force to change the PB0, PB1, the MPLab does not allow (test by stepping). Then I tried to change the config of portB, make them as outputs (I know, this is not correct, and the buttons are attached here!!!) (TRISB with all pins of 0), then MPLAB allows me to change its bits.
This is so strange!!!! Anyone please help me. I reckon we can force the bits of INPUT port when stepping in MPLAB(simulation).
Thanks

#### patricktran

##### New Member
One more thing, this program seems I am polling to check the buttons. Is it good? I reckon I should make the button to generate an interrupt by itself. Can you give me some hints of how to do it?
Thanks

#### falleafd

##### New Member
movlw H'00' ; All pins of PORTC outputs
movwf TRISC
movlw H'11'
movwf TRISB ; All pins of PORTB inputs
You cannot use all inputs of portb with this
Code:
movlw h'ff'
movwf trisb
If you move h'11' to trisb, trisb will be equal to b'00010001' that is only bit 0 and bit3 are inputs.

#### patricktran

##### New Member
Oh thanks, Now I know, we cant use all pins in port B for I/O prupose.
Thanks again

#### patricktran

##### New Member
Can someone give me some hints for phush button with interrupts? Not polling ...
Thanks

#### Nigel Goodwin

##### Super Moderator
patricktran said:
Can someone give me some hints for phush button with interrupts? Not polling ...
Thanks
Use PortB and the 'Interrupt on change' feature - there's an application note at MicroChip about using it.

#### patricktran

##### New Member
Hi, thanks for ur replies.
I rethink about the interrupt for buttons.
Basically, my project will have to do 2 things at the same time:
1. Count the TMR1 and update LCD
2. Check if a button is pressed. (pause)
I reckon the TMR1 that I use will generate interrupt defenitely. If I want the button to generate interrupt as well, they might colide!!!
With this complexity of this project, would you think I should pooling for the push button to be pressed, or make it interruptable. (the TMR1 no doubt will have interrupt when it overflows.)
Thanks

#### patricktran

##### New Member
Uh, I read some docs about the interrupt - on - change but I dont quite get it. :roll:
1.Is it only the interrupt generated when bit 4,5,6,7 in PORT B (Port B only!) is changed? (1 to 0 , or 0 to 1). Would it be different if the these pins are configured to be in/out ?

2. INTCON Reg: Bit 0 (RBIF - Port change interrupt flag bit) is used to check if the pins 7-4 of INTCON change their states.
Bit 7: GIE, bit6: PEIE, bit5: TOIE, bit4: INTE
Why do we need to check states of all these interrupt enable bits?
Thanks

#### Exo

##### Active Member
patricktran said:
Hi, thanks for ur replies.
I rethink about the interrupt for buttons.
Basically, my project will have to do 2 things at the same time:
1. Count the TMR1 and update LCD
2. Check if a button is pressed. (pause)
Scanning a few buttons and updating an LCD is child's play for a pic. No need to use interrupts. Just make a program like this:
-Scan buttons - and act when one is pressed - do nothing if nothing pressed
-Check for TMR1 overflow flag and if overflow, store it somewhere
-update the lcd

This shouldn't be any problem for a pic, especialy when you consider:
-you only want to update the lcd a few times per second, Makes no sense updating more then 20 times a second because your eyes cant see that
-You only want to scan the buttons a few times a second. If you scan them 10 times per second you won't be able to press them fast enough for the pic to miss a press...

what i'm saying is, you probabely even have to add delays :!: , so interrupts are not needed.

#### patricktran

##### New Member
thanks for your replies. Now it is clear to me that, I just need to scan the input pins which are connected to the buttons (polling), no need interrupt. I decided to scan it after few instruction cycles like below code:
Code:
title  "ledon - Turn on a LED when a Button is Pressed"

include "D:/p16F877.inc"
__config (_CP_OFF & _PWRTE_ON & _HS_OSC & _WDT_ON & _BODEN_ON & _LVP_OFF & _DEBUG_ON)
errorlevel -302

;;;;;;;;Vectors  ;;
org   H'000'
goto   MainLine
org   H'004'
goto   IntService
Stop
goto   Stop

;;;Interrupt Service;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

IntService
retfie
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;; Initial Subroutine;;;;
Initial

bcf      STATUS,RP0   ;
bcf      STATUS, RP1   ; Bank 0 selected
clrf   PORTC
clrf   PORTB
bsf      STATUS,RP0   ; Bank 1 selected
movlw   H'00'       ; All pins of PORTC outputs
movwf   TRISC
movlw   H'11'       ; b'00100001'
movwf   TRISB      ; pin 0 and 5 are inputs
bcf      STATUS,RP0   ; Bank 0 selected
return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MainLine
call    Initial
MainLoop
btfsc   PORTB,0     ; check Button 1, if it is not pushed, skip the next step
goto    B1_routine
btfsc   PORTB,1     ; check Button 2, if it is not pushed, skip the next step
goto    B2_routine
goto    TurnOff      ;  if bit 0 is 1, goto Turnoff
B1_response
movlw   b'10101010'
movwf   PORTC
goto     MainLoop
B2_response
movlw   b'01010101'
movwf   PORTC
goto     MainLoop
TurnOff
clrf      PORTC
goto     MainLoop
end
However, when I connect the pin 0 and 5 to the push buttons, nothing happens when I push them. :roll:
Can you please correct that code?
Thanks

Status
Not open for further replies.