• 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.

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.

I have few questions about this application. Could you please help me out?
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
Most Helpful Member
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 :D
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
 

Nigel Goodwin

Super Moderator
Most Helpful Member
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
Most Helpful Member
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
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
-back to top

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.

Latest threads

EE World Online Articles

Loading
Top