Continue to Site

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.

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

reseting tmro

Status
Not open for further replies.

tama182

New Member
Is there anyway of reseting TMR0 in mplab sim, because i am using a program by where TMR0 is prescaled by 256, so then every time 256 instructions pass, TMR0 goes up by one, and then when TMR0 reaches 30, 1 gets subracted from 80 in a different register, so that when 30 more is reached, 1 gets subracted again from 80,

and when 30 is reached 80 times, it counts for my one second,

anyway, when i run the program first time it works, but im not able to start the program from scratch again, because even if i press reset, tmro stays the same number as it got up to the last time i animated it, everything resets but not tmr0

any ideas
 
tama182 said:
... so then every time 256 instructions pass, TMR0 goes up by one, and then when TMR0 reaches 30, 1 gets subracted from 80 in a different register, so that when 30 more is reached, 1 gets subracted again from 80, and when 30 is reached 80 times, it counts for my one second,

Interesting. When value 30 is reached in TMR0, do you reset/clear TMR0 or you just let it countinue counting?
 
Jay.slovak said:
I don't think this RTC will be very acure, especialy if you use Internal oscilator...

But if you use an external xtal, the accuracy will be that of the xtal - assuming the program is written correctly?.

However, TMR0 isn't a very good choice, modern PIC's have much better timers - with TMR0 you have to correct for it's limitations.
 
Jay.slovak said:
I don't think this RTC will be very acure, especialy if you use Internal oscilator...

The OP did not say internal oscillator so I think he is using the system clock counting through the pre-scaler.

I have looked at how the TMR0 works in the past and come to know(also from other postings in forums) that to have maximum timing accurcy, one must not do anything to the TMR0 register. Even reading it would cause the timing to go off. This statement refers to the wrong timer. See note in edited.

So it is a bit tricky to use TMR0 for a realtime clock. TMR1 & TMR2 are better choices.

Edited: The timer mentioned above that stop incrementing when it is read is TMR1.
3. Module: TMR1
When operating in external clock mode (TMR1CS
is set), reading either of the timer 1 registers
(TMR1H or TMR1L) may cause the timer not to
increment as expected. This occurs for both synchronous
and asynchronous inputs.
The scenarios which display this are:
a) When a read operation of the TMR1H register
occurs, the TMR1L register may not
increment.
b) When a read operation of the TMR1L register
occurs, the TMR1H register may not
increment. This improper operation is only
an issue when the TMR1L register increments
from FFh to 00h (FFh ® 00H) during
the read of the TMR1L register.

Work Around
Do not read either the TMR1H or the TMR1L registers
when operating in external clock mode
(TMR1CS is set). If the application needs to read
the 16-bit counter, evaluate if this function can be
moved to the TMR0 or one of the other timer
resources on the device.
 
Checking T0IF shouldn't be a problem.
But I thought he wanted to run in a loop, until TMR0 has 30, then clear TMR0 and increment other register. This would be very stupid IMHO.
 
But I thought he wanted to run in a loop, until TMR0 has 30, then clear TMR0 and increment other register. This would be very stupid IMHO.

No !, TMR0 is never cleared, because when TMR0 has reached 30, anthother register is decreased by one, but then instead of tmr0 being cleared, the program is coded so that another 30 is added to the number that tmr0 is being compared against,

well anyway heres the code, ive change it a little though, and its not one that ive made up, its from a book i have, and all his programs are at this website, under pic book, example programs

www.to-pic.com

Code:
;************************************
; written by :	John Morton			*
; date : 26/07/97				*
; version : 1.0					*
; file saved as : Timing			*
; for PIC16F54				*
; clock frequency : 2.4576 MHz		*
;************************************

; PROGRAM FUNCTION : The state of an LED is toggled every second 


 		list 	     	P=16F54
		include	"c:\pic\p16c5x.inc"

		__config	H'0FFD' & H'0FFB' & H'0FFF'

;============
; Declarations :  


		
Mark30		equ		08
Post80		equ		09
_5Second	equ		0A

		org		1FF
		goto		Start
		org		0

;===========
; Subroutines : 

Init	clrf		TMR0
		clrf		PORTB			;
	
		movlw		b'00000000' 	; RB0 : buzzer, RB1-7 : not connected
		tris		PORTB

		movlw		b'00000111'		; sets up timing register
		option

		movlw		d'30'			; sets up marker
		movwf		Mark30			;

		movlw		d'80'			; sets up first postscaler
		movwf		Post80			;
	
		movlw		d'5'			; sets up five second counter
		movwf		_5Second		;
	
		retlw		0

;=============
; Program Start : 

Start	call		Init		

Main	movfw		Mark30			; takes the number out of Mark30
		subwf		TMR0, w			; subtracts this number from the number 
									;  in TMR0, leaving the result in the							;  working register (and leaving TMR0 							;  unchanged)
		btfss		STATUS, Z		; tests the Zero Flag - skip if set, i.e. if the							;  result is zero it will skip the next 								;  instruction
		goto		Main			; if the result isn't zero, it loops back to 							;  'Loop'
		
		movlw		d'30'			; moves the decimal number 30 into the 
		addwf		Mark30, f		;  w. reg. and then adds it to 'Mark30'

		decfsz		Post80, f		; decrements 'Post80', and skips the next 							;  instruction if the result is zero
		goto		Main			; if the result isn't zero, it loops back to 							;  'Loop'
						
									; one second has now passed

		movlw		d'80'			; resets postscaler
		movwf		Post80			;

		comf		PORTB, f		; toggles LED state
		

		decfsz		_5Second, f		; has five seconds passed?
		goto		Main			; no, loop back

	
		 
		movlw		d'5'			; resets 5 second counter
		movwf		_5Second		;

		goto		Main			; loops back to start
			
		END
 
sorry i dont know why its such a mess, ive copied it straight from mplab, and its tidy there, and ive used the code tool :roll:
 
tama182 said:
No !, TMR0 is never cleared, because when TMR0 has reached 30, anthother register is decreased by one, but then instead of tmr0 being cleared, the program is coded so that another 30 is added to the number that tmr0 is being compared against,

Nice. Compare for equality with ever increasing goalpost. A very clever and simple technique without the need of clearing the timer.

The code formatting messed up because of the use of tab. I also found this occuring when I copied the code in MPLAB, which looks nicely formatted into another text processor.
 
The reason the author does not want to reset TMR0 is that writing to TMR0 also clears the prescale registers. These prescale registers increment as fast as the program counter. Depending on the exact instant you clear TMR0, this will introduce an error into TMR0's counting. It is best to just read off of TMR0 not harming it in any way or your "1 second" delay will be off a few milliseconds. This error will quickly accumulate.

======================================


ive change it a little though

Yeah, right.

Author's code in the website:

Code:
	__config	_XT_OSC & _WDT_OFF & _CP_OFF

Your code:

Code:
      __config   H'0FFD' & H'0FFB' & H'0FFF'

I strongly advice you to avoid using fixed numbers embedded in you code. Your code is not self documenting. It makes it harder to debug by yourself and others wishing to help. You will also have trouble migrating to newer PIC devices.

I also understand the author's code included the line:

Code:
      include   "c:\pic\p16c5x.inc"

Your PC might have a different MPLAB directory installation. You should have corrected that line of code instead.
 
when i said ive changed it, i didn't mean make it better, i meant change it for my board, i haven't got a buzzer, so i removed that part of the code,

and i changed the configuration bits to

__config H'0FFD' & H'0FFB' & H'0FFF'

because i couldn't get them to work as

__config _XT_OSC & _WDT_OFF & _CP_OFF

but then i noticed that they weren't in capitals.,

I also understand the author's code included the line:

Code:
include "c:\pic\p16c5x.inc"


Your PC might have a different MPLAB directory installation. You should have corrected that line of code instead.

nope.....i made sure that it links, and i also had to change the line to

include "c:\pic\p16f5x.inc" ,

now heres my next query,

the program only seems to work if i have the _HS_OSC set to either HS or RC, it wont work with XT, which is what the author has the code set at,

any ideas why?

i have looked at the 16f54 manual it says,

RC: Low-cost RC oscillator
- XT: Standard crystal/resonator
- HS: High-speed crystal/resonator
- LP: Power-saving, low-frequency crystal

and my picdem has a 4mhz crystal onboard,
 
Hello,

Just 1 little comment, yours to ignore if you want ;)

In your code you read and compare TMR0 to a register and then check to see if the result is Zero.

If at some stage, you want your code to do more than sit in this checking loop then you may "miss" the period when the values are identical and the result will not be Zero.

If you test for "Carry" (and make the initial value 29 not 30) then even if you miss the "Zero" state, the "Carry" flag will still be set and you will not screw up the timing.

Just a thought ;)
 
Matt(Pic progger) said:
Hello,

Just 1 little comment, yours to ignore if you want ;)

In your code you read and compare TMR0 to a register and then check to see if the result is Zero.

If at some stage, you want your code to do more than sit in this checking loop then you may "miss" the period when the values are identical and the result will not be Zero.

If you test for "Carry" (and make the initial value 29 not 30) then even if you miss the "Zero" state, the "Carry" flag will still be set and you will not screw up the timing.

Just a thought ;)

When 30 is added to Mark30 and overflows and wraps around zero, Mark30 becomes less than tmr0. Therefore the test will fail:

Code:
Main   movfw      Mark30
      subwf      TMR0, w 
      btfss      STATUS, C
      goto      Main

Not to worry, the program loop can be up to 7680 instruction steps long before tmr0 needs to be tested. That's longer than the program space of the PIC16F54.
 
motion said:
Matt(Pic progger) said:
Hello,

Just 1 little comment, yours to ignore if you want ;)

In your code you read and compare TMR0 to a register and then check to see if the result is Zero.

If at some stage, you want your code to do more than sit in this checking loop then you may "miss" the period when the values are identical and the result will not be Zero.

If you test for "Carry" (and make the initial value 29 not 30) then even if you miss the "Zero" state, the "Carry" flag will still be set and you will not screw up the timing.

Just a thought ;)

When 30 is added to Mark30 and overflows and wraps around zero, Mark30 becomes less than tmr0. Therefore the test will fail:

Code:
Main   movfw      Mark30
      subwf      TMR0, w 
      btfss      STATUS, C
      goto      Main

Not to worry, the program loop can be up to 7680 instruction steps long before tmr0 needs to be tested. That's longer than the program space of the PIC16F54.

I have used this technique (I learnt from the same book) but did not have any problem. However, I used the xorwf instruction to compare TMR0 and Mark30 rather than subwf.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top