PDA

View Full Version : 16F877A timer to capture in microseconds



sycluap
- 16th December 2007, 12:57
I tried on the OLYMPIC TIMER project provided by Melanie in the Sample Code Section, and that is indeed a good one. But, I am currently working on a project which requires me to capture the time in microseconds. While OLYMPIC TIMER project is able to display 1/100 seconds and with 4Mhz clock it will be 1 microsecond ticking.

I would like to know if there is any possibilities that I can utilize that 1us ticking to capture the time difference in microseconds and display it on LCD?

Can any experts guide me in this problem? Thanks in advance!

sycluap
- 18th December 2007, 07:54
Perhaps capture the time in microseconds is impossible to do so since no reply from anyone. Anyhow, from the Olympic Timer and Automatic Clock provided by Melanie and Darren, both of the project display the fastest time count of 10ms on LCD.

Is there any possibility that to display 1ms timer counts on LCD? Meaning that the Stop Watch Timer can capture up to 1ms instead of 10ms.

Please help me on this matter, urgent. Anyone?

Melanie
- 18th December 2007, 08:23
Three things...

1. Try it. Build the circuit and change the pre-load value for the Timer for 1mS instead of 10mS and change the display to show the additional digit.

2. If it is too slow, try (a) connecting the LCD in 8-bit rather than 4-bit mode to reduce the display time, (b) use a 18F part at 40MHz instead of a 16F part at 4MHz, (c) The danger is you may throw data at the LCD too fast and it won't love you, so try displaying the data only every tenth count, or just at the end with the final result.

3. Consider using the CCP Module of the PIC. You will be able to capture events into the uS range with that. Datasheet of your chosen PIC will explain how to use the CCPM - naturally chose a PIC that has it!

sycluap
- 19th December 2007, 06:31
Method 1 is sufficient to complete my project, as it is possible to capture display the time in milliseconds.

I am facing a problem here of which, I do not know how to calculate the require timer pre-load value in order for to timer to count on 1 millisecond basis. I tried to apply the value $FC38 which I calculated based on my understanding from $D910 as in the sample codes, but it appears to that the timer counts become slower. I tried with other values such as $FFFE, $03C7, all seems to make the timer count really slow.

Can anyone guide/teach me in how to calculate the actual pre-load value which I can get 1 millisecond timer and display it on LCD? I am using 16F877A with 4Mhz crystal.

Sorry for all the question, I am really new to this, hope can help me. Very much thanks.

Melanie
- 19th December 2007, 16:18
And you changed the TickCount Interrupt Handler to account for the fact that Hundredths are now Thousandths and changed the variable from a byte to a word and ensured everything is ticking in 1mS steps? Or have you just changed the pre-load valve and hoped everything would work?

sycluap
- 20th December 2007, 02:54
I only made changes to the pre-load value, LCDOUT command to display up to 3 digits and the tickcount interrupt handler, where I put in the new:

Tickcount changes:
If RunningFlag=1 then
Thousandths=Thousandths+1

If Thousandths>9 then
Thousandths=0
Hundredths=Hundredths+1

etc....

LCDOUT Changes:
LCDOUT $FE, $C0, DEC3 Thousandths, " Thousandths"

It doesn't seems right. What went wrong? Did I miss out anything? Getting 1ms counts is very critical for my project, but I just couldn't figure it out. :(

sycluap
- 22nd December 2007, 06:36
Anyone can help me on this?

sycluap
- 10th January 2008, 05:24
Is there anyway to add assembly language to the codes in PicBasic Pro? Can anyone guide me to do polling using timer 1 in 1ms interval?

mister_e
- 10th January 2008, 05:37
Yes it's possible to mix assembler. you just need to use ASM/ENDASM


ASM
' your asm code goes here
ENDASM


Unless you define your variable as SYSTEM var, your PBP variable must have an underscore before them


YourVar VAR BYTE

ASM
' your asm code goes here
CLRF _YourVar
ENDASM

And PBP don't appreciate BANKSEL. you must use CHK?RP instead

sycluap
- 10th January 2008, 08:14
thanks mister_e, this will help me in experimenting the 1ms interval polling. Is there anyone can help me on how to get 1ms interval by polling method for timer1?

sycluap
- 12th January 2008, 07:02
I modified the Olympic Timer program, by replacing the:
TMR1RunOn.HighByte= $FC
TMR1RunOn.LowByte=$18

and deleted the TMR1RunOn=TMR1Preset+TMR1RunOn, to directly load the TIMER1 preset value into the timer1 register.

This make the timer by the program runs faster than used to. Until I change the value to $FF,$FE, the timer can have the timing interval very close to 1ms, but still slightly delayed, as I compare the timing (seconds) with a watch. The watch is about 2x faster than the timing by the timer.

Attached is the code I wrote by referring to the Olympic Timer by Melanie. Is there any problem with the code? Any solution for that? Thanks in advance.

sycluap
- 13th January 2008, 08:35
I rewrite a new program to activate Timer1 as free-running timer. I take the TMR1L and TMR1H value directly, and obtain a new result by:
Result = TMR1H*256+TMR1L

May I know, is the RESULT I get is in microsecond? As far as I understand, 4Mhz clock will result in 1us per cycle. Thus, is the value obtained in RESULT is in microsecond? Please correct me if I am wrong, I would like to have the result 1 milliseconds. Below is my code, hope some one can correct my mistake.

ResetTimer:
GoSub SetRe

skimask
- 13th January 2008, 08:44
StartTimer:
LCDOUT $Fe, 1
LCDOUT $FE, $80, "Calculating..."
T1CON.0=1

Start the timer before doing anything with the LCD. The LCD commands take time. It'll skew the result quite a bit.



GetValue:
Timer1H=TMR1H
Timer1L=TMR1L

When stopping the timer, you'll also have to account for the extra cycles taken during the GOSUBs and other code to get there...if you want a really accurate result.

And T1 is going to overflow every 65.536us, slightly more than 15 times per second.
If you press the button at 70,000us, you'll get a result of 4,464, not the result you want.
How you plan on accounting for the rollover?

sycluap
- 13th January 2008, 08:50
Ok, I will change to Start the timer before doing anything on the LCD. I see, from the explanation, may I know the timer rolloever every 65536 microsecond or 65.536 microsecond? Let's say is it as what Mr.Skimask says, now I understand that the timer will rollover every 65.536 microseconds. May I know how to account the rollover in order to get the incrementing time, instead of keep on doing from 0 to 65.536 microseconds? Is it possible to do something like,

if Result > 65536 then
A=A+1

if A > 65536 then
B=B+1

and so on..... I assume that timer1 from 0 to 65536 then rollover to 0 again, and so on. So, when timer1 reach 65536, then A increment by 1, and timer rollover back to start from 0 again. Then, when the 2nd time timer1 reach 65536, A will increment again, and so on. Is this possible? Let A keep on incrementing until I can trace the reading of the timer back in milliseconds? Or is there any better solution? Thanks in advance.

MarioC
- 14th January 2008, 03:02
I think you could use the Timer 1 interrupt for that.

But as Miss Melanie says:
Use the CCP.


Been on vacation (looooooooooooong vacation ), now I'm back (not that I'm very useful to the forum, I just ask a lot).