Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Using Timer Function in PIC16F877A

Status
Not open for further replies.

sycluap

Newbie level 5
Joined
Dec 12, 2007
Messages
10
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,373
picbasic pro timer

I would like to ask, how to utilize the timer function in the microcontroller to get the difference between start time and stop time and then display it at LCD. E.g, switch pressed once to start timer, press again to stop timer, then the difference between start time and stop time is calculated and displayed on LCD. I am doing the programming using PicBasic Pro.

May I ask can this be done? I am a total newbie in using microcontroller, hope can help. Thanks in advance to all the experts.
 

timers in pic16f877a

Of course it can be done.
Depending on how much code you need to run, you can choose an interrupt approach or a polling approach.

For polling, you just monitor an input pin and when it changes state, you start the timer. Then monitor the pin again and stop the timer when the state of the pin changes back. The timer contents are the time you need.
Of course, with this approach you wil lose a few instruction cycles, but running at 20MHz your instruction cycle is 200ns. So if you lose 5 cycles, you lose only 1us.

If this is a problem, then you can try using the CCP in the PIC16F877A.
Set it up to capture every rising edge. So the contents of the timer will get latched when the rising edge occurs. At the same time, you get an interrupt and read the latched timer contents and save them. On the next edge the new timer contents will be latched and you get an interrupt. Subtract the two latched values and you get the exact time between the events, because all is now done in HW, you do not lose any cycles.
It all depends on your actual requirements.
 

pic 16f877a counter

Timing precision is very critical for my project, thus, I think the best method is the method that will not lose any cycles.

However, I will first start with polling method to get used to the codes as I am totally new. How to declare the timer function to be used and monitor the pin changes? How to stored the timing difference in a variable and the display it to the LCD? Can you please guide me further in this matter? I am coding using PicBasic Pro.

Very much thanks!
 

using pic16f877a timer

The most precise is indeed the one using the CCP, but even that has some limitations, in terms of resolution. I think the best resolution you can get is 0.2us, when the oscillator is running at 20MHz.
 

timer1 coding for pic16f877a

Hello,

If you goto www.picbasic.uk.co you will find many threads regarding the use of timers. Just about anything you could ask for including lots of example code. Also try www.melabs.com.

HTH,

BobK
 

pin functions of pic16f877a

Thank for the reply VVV and BobK. I have found an example project (Olympic Timer) which is very similar to what I need for me project in the forum suggested.

However, I am facing a problem which, I need the timer to count in the interval of 1ms. What I can obtain and learn is 10ms interval.

The expert in that forum suggested me to change the preset Timer1 register value to suit the 1ms interval. But I do not know how to get it, no matter what value I change, the timer gets even slower compare to 10ms interval. Can anyone teach me how to calculate the actual preset value for Timer1 register, so that I can get 1ms timer interval instead of 10ms? I am using 16F877A and 4Mhz clock, and I am coding in PicBasic Pro.

Please see here. https://www.picbasic.co.uk/forum/showthread.php?t=7729

Or is there any better solution to get 1ms timing interval?

1ms interval is very important for my project. Please help.
 

why tmr1 value change

I am sorry, I do not understand the requirements anymore: do you need a resolution of 1ms or do you need to measure time intervals in the 1ms range with the best possible resolution?

For 1ms resolution you can simply use polling, even at 4MHz.
If you need better resolution, then again I suggest you use the CCP, which will allow you to measure with a resolution of 1us at 4MHz.

I cannot help with PICBasic, I am an assembler guy.
 

pic16f877 timer calculation

I am sorry for making the requirement unclear. Actually, I need to timer to count in 1ms resolution. Meaning that, the timer will count in 1ms increment value and display in LCD. E.g. If I press start button, the timer will start counting in 1ms increment, until I press stop button, the counted value will be displayed on the LCD.

The TIMER1 function I know how to use, the problem is I do no know how to set the TIMER1 register value so that it can be in 1ms resolution and display it on the LCD.

Perhaps coding in assembly will help?
 

1us in seconds

OK, now I understand.

You can use TMR1 to generate interrupts every 1ms.
To do that, preload the timer with a qantity that will make it overflow in 1ms.
For example: assume the oscillator is 4MHz. Then the TMR1 clock is 1MHz. That means you need 1000 counts for 1ms. So preload the timer with 65536-1000=64536.

It will then generate an iterrupt every 1ms. In the ISR, increment a pair of registers (or more) which will be your ms counter. These registers get cleared when the first rising edge is detected and read on the second rising edge. That is the time in ms between the edges, which is what you need.

Note that you need to do the debouncing in hardware.


So the code might look like this:
Code:
#define    BUTTON   PORTB,0


	ORG 0x00			;reset vector

	goto	main			;



	ORG 0x04 			;Interrupt vector

	movwf	W_temp			;save W
	swapf	STATUS,W		;save status reg
	movwf	STATUS_temp		;
	clrf	STATUS			;make sure we are in bank 0, although we do not switch banks here

	bcf	PIR1, T1IF		;clear interrupt flag

	bcf	INTCON,T1ON		;stop the timer
	movlw	high (.65536-.1000)	;reload timer; the value may need to be adjusted slightly, to get exactly 1ms
	movwf	TMR1H			;
	movlw	low (.65536-.1000)	;
	movwf	TMR1L			;

	incfsz	Counter,F		;increment the 16 bit ms counter
	incf	Counter+1,F		;

	swapf	STATUS_temp,W		;restore registers
	movwf	STATUS			;
	swapf	W_temp,F		;
	swapf	W_temp,W		;
	retfie				;return



main:					;main code

	;put all your initializations here


	clrf	Counter			;clear the 16-bit counter
	clrf	Counter+1		;

	
	movlw	B'10000000'		;enable interrupts in general
	movwf	INTCON			;

Wait_h:	btfss	BUTTON			;wait here until button pressed
	goto	Wait_h			;

	movlw	high (.65536-.1000)	;preload timer; value can be changed, so the first interrupt occurs exactly after 1ms
	movwf	TMR1H			;
	movlw	low (.65536-.1000)	;
	movwf	TMR1L			;

	bsf	T1CON,TMR1ON		;turn on TMR1
	bcf	PIR1,T1IF		;clear TMR1 interrupt flag, just in case
	bsf	INTCON,PIEI		;enable peripherals interrupts (TMR1 is a peripheral)

Wait_l:	btfsc	BUTTON			;wait for button to be released
	goto	Wait_l			;

Wait_r:	btfss	BUTTON			;wait for the rising edge here
	goto	Wait_r			;

	bcf	T1CON			;stop TMR1
	bcf	INTCON,PIEI		;disable peripheral interrupts

	call	DISPLAY			;call the routine that displays the time on the LCD

	clrf	Counter			;clear the 16-bit counter
	clrf	Counter+1		;
	
Wait_f:	btfsc	BUTTON			;now wait here for a falling edge
	goto	Wait_f			;

	goto	Wait_h			;re-start the cycle
 

function of pic 16f877a

I refer to the Assembly Codes provided by Mr.VVV, I manage to get the clock to have in very near to 1ms interval. But, I the timer seems to be slightly out of the actual timing when I compare the timer to a watch.

e.g, watch seconds ticked 1.5x ~ 2x faster than the timer programmed in the uController.

I tried to change the value to load into the TIMER1 registers, even to Highbyte=$FF, LowByte=$FF, but it seems that still unable to get as accurate as in the watch, although it is very near to it.

And, my device cannot run when I change to 20MHz crystal. But it works just fine in 4Mhz, may I know what is wrong? Tried to change the configuration bits from XT to HS in MPLAB 8.00, but when I recompile, the bit change back to XT.

I attach the codes I wrote using PicBasic Pro, can any experts correct my mistakes to get the desired interval?

Help is very much appreciated.
 

fosc/4 pic 16f877a

Hints:
* Use a crystal that divides perfectly with binary into seconds
* Don't run the timers asynchronously (don't clear or set them let them free run)
* Use the CCP module (Compare mode)

For 1ms timing 1/100th of a second a 6.5536MHz crystal would be perfect.
 

pic16f877 timing

PICbasic probably is a lot harder to be achieved than assembly language.
 

assembly pic16f877a variable definition

IamnotJunk said:
PICbasic probably is a lot harder to be achieved than assembly language.

Very true. Who knows what sort of code the BASIC generates.
 

how to load value into timer1 of pic16f877

Thanks for the hints, I will try on it now. Still need to study how to use CCP first.:D

Added after 4 hours 14 minutes:

Ok. I redo the program to make the Timer1 free run timer. Before timer start, it is loaded with with 0000h in the timer1 register. The timer starts when I press START.

When I press stop, I get the value from TMR1H and TMR1L into 2 separate variables which I define as BYTE. After that, I get the actual result by:

RESULT=TMR1H*256+TMR1L

So, it that mean, the total RESULT * 1us = the total timing in seconds I obtained from the event? Not really sure about the calculation of the timer, but as far as I understand, using 4Mhz clock, it will be:

4Mhz/4 = 1Mhz (Fosc/4 from T1CON.1=0, internal clock)
T=1/1M=1us (per instruction cycle)
thus, Result*1us = total time in second.

Please correct me if I am wrong, really not very sure about the Timer1 calculation.

Thanks in advance!
 

timer example in pic16f877a

Yes, that is correct. With a prescaler of 1:1 the timer increments every 1us, so the result is in microseconds.
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top