PDA

View Full Version : counter/ internal clock



jimbobjones
- 29th April 2007, 00:11
i need to create a simple clock/counter that increments roughly every second. Accuracy is not very important so long as its approximatly 1sec. When the counter reaches a given value i'll use it to set a flag which i plan to use to drive another process.

i'm using pic16F876a

can anyone help, i'm still learning picbasic


many thanks

jim

Darrel Taylor
- 29th April 2007, 00:58
Here's a list of examples...

http://www.picbasic.co.uk/forum/showpost.php?p=36992&postcount=18

_

Melanie
- 29th April 2007, 02:46
> Accuracy is not very important so long as its approximatly 1sec.

Darrel - You forgot to list the obvious...

PAUSE 1000

Darrel Taylor
- 29th April 2007, 03:08
http://www.pbpgroup.com/files/ROFL.gif

So true.

_

jimbobjones
- 29th April 2007, 11:30
thanks for the replies

i cant use pause as i have other processes that need to be run..

jimbobjones
- 29th April 2007, 12:50
can anyone help with the following code as its not working

i'm trying to set the output to 100 if the timer is less than 5000 and 001 if its above....





device = 16F876a 'PIC device
CMCON = 7 'disable comparators
TRISB = %11111111 'Portb as inputs
TRISA = %00000000 'Porta as outputs
porta = %00000000 'Set all outputs low

T1CON.0=0 'stop the timer
TMR1H = 0 'Set the high part of the timer value to 0
TMR1L = 0 'Set the low part of the timer value to 0
T1CON.0=1 'start the timer

MyCount VAR WORD

Start:

MyCount.HighByte = TMR0H 'Get high byte of counter
MyCount.LowByte = TMR0L 'Get low byte of counter

IF MyCount > 5000 THEN 'if the timer value > than your number

porta = %00000001

gosub timer_reset

else

porta = %00000100

endif

Goto Start



timer_reset:

T1CON.0=0 'stop the timer
TMR1H = 0 'Set the high part of the timer value to 0
TMR1L = 0 'Set the low part of the timer value to 0
T1CON.0=1 'start the timer

return

mister_e
- 29th April 2007, 15:12
OK, i see you have disabled the analog comparator, but not the ADCs

ADCON1=7

And... seems to miss some TIMER setting, like clock source, prescaller, Prescaller assignment.

AND, maybe i'm wrong but TIMER0 on this one is a 8 bit counter....

and have a closer look to those


MyCount.HighByte = TMR0H 'Get high byte of counter
MyCount.LowByte = TMR0L 'Get low byte of counter

maybe it's a copy/paste mistake too :rolleyes:

jimbobjones
- 29th April 2007, 16:12
Thanks for the help

It seems I’m barking up the wrong tree then as I don't want to use an external clock source, and i can’t interrupt the program or pause it.


Is it possible simply to increment a variable every execution cycle?

i.e.

tick var byte
tick_flag var byte


start:

If tick > 99 then

Tick = 0
tick_flag = 1

Else

tick = tick + 1

End if

Goto start ‘ loop

But how can I approximate this to a time scale I can use. The datasheet state the execution cycle time as 1uS , forgive my ignorance but does that mean the above code will increment every 1uS ?

mister_e
- 29th April 2007, 16:35
Yes it could be 1uSec / clock cycle @4MHZ... but not in Basic code, even in assembler @ 4MHZ, you couldn't do it @ 4MHZ with a software loop, hence why TIMERs are built in.

NOW, select a 16Bit timer that can be set as counter BY using the internal FOsc (ticks) and read the according register once in a while or in a loop. With some human measurement, you should be able to have a accuracy of few uSec.

This will also require you configure the Timer prescaler and pre-load value accordingly. To help you to figure out their value, i suggest you download my PicMutiCalc

http://www.mister-e.org/pages/utilitiespag.html

EDIT: it's sunday and my brain need to understand better what you need to do... i'm lost in your explanation. Maybe you could translate it to Mister E's poor english level?

jimbobjones
- 30th April 2007, 12:51
Sorry for the poor explanation but I’m a little confused myself. ;)

From the proton geeks site I’ve modified the code snippet “How to build a simple and stupid small timer routine” by Olivier de Broqueville to achieve basically what I’m after.


device = 16F876a 'PIC device
CMCON = 7 'disable comparators
ADCON1 = 7 'disable ADCs
TRISB = %11111111 'Portb as inputs
TRISA = %00000000 'Porta as outputs
porta = %00000000 'Set all outputs low


ON_INTERRUPT Horloge

DECLARE XTAL=4


SYMBOL GIE = INTCON.7
SYMBOL T0IF = INTCON.2
SYMBOL T0IE = INTCON.5
SYMBOL PS0 = OPTION_REG.0
SYMBOL PS1 = OPTION_REG.1
SYMBOL PS2 = OPTION_REG.2
SYMBOL PSA = OPTION_REG.3
SYMBOL T0SE= OPTION_REG.4
SYMBOL T0CS= OPTION_REG.5

DIM mycounter as WORD ' This is the TIME variable used to count the interrupts
DIM mycounter_limit as WORD ' This is the limit to reach. Could have been a constant in the program
' to win some place (you would win 6 words)

DIM SECONDS as BYTE
GIE=0

GOTO INITIALISATION ' As always: place interrupt routine first and jump over...
' -----------------------------------------------------------------------------
' INTERRUPT ROUTINE
' -----------------------------------------------------------------------------
Horloge:
INC mycounter ' Increment the time variable at every interrupt
T0IF=0 ' Clear the interrupt flag
CONTEXT RESTORE


Initialisation:
T0SE =0 ' TIMER0 triggered by ascending edge
T0CS =0 ' TIMER0 using internal clock
PSA =0 ' Prescaler assigned to TIMER0
PS0 =1 ' Prescaler set at 1:256
PS1 =1
PS2 =1

mycounter_limit= 10
mycounter=0
SECONDS=0

TMR0=0 ' Reset TIMER0
T0IE=1 ' Autorisation of TIMER0 interrupt
GIE=1 ' Autorisation of all interrupts

MAIN:
WHILE 1=1 ' Do this forever
IF mycounter > mycounter_limit Then ' Are we above the TIME factor?
' As the test is ABOVE the clock runs a bit
' slow, which was the purpose
mycounter=0 ' Reset the 'interrupt' counter
SECONDS=SECONDS+1 ' Increment the seconds
IF SECONDS > 59 THEN ' If 59 sec,
SECONDS=0 ' and RESET seconds
ENDIF



ENDIF


if SECONDS > 5 then
porta =%00000001

else
porta =%00000100
'Stop for 5 sec and
'check PIR
end if
WEND ' And do it forever




END

But I don’t really understand how it works as I managed to get approximately the required time by setting “mycounter_limit= 10” (trail and error).

He gives an explanation here : linky (http://protongeeks.com/index.php?option=com_content&task=view&id=85&Itemid=27
)
but as I’m using 4mHz OSC the values are different. Can anyone help explain whats happening in the code as I never like to use something with out fully understanding it.


Thanks

Jim

BobK
- 30th April 2007, 13:28
Hi JimBob,

There are alot of examples of basic Timer usage on this forum. Nuts and Volts magazine (www.nutsvolts.com) did an article on using Timers last year. This is a topic that has been more than covered in the last couple of years. There are examples with explanations of using timers in, for example, Easy Clocks by Paul Borgmier and Ms. Melanies' Olympic Timer and her MN1302 Clock program. You can also get examples on the www.melabs.com website under sample programs. Mister E has provided you with an excellent program for determining what values you need to enter when setting up timers.

I am not trying to be critical but look around, this information you need to learn is out there and easy to find.

HTH,

BobK