Help with 08M2 Code

Climoni

New Member
Hello all - another newbie here. I am having difficulty with this TIMER1 code developed by Jeremy and Hippy - thanks much, guys. I am attempting to adapt this code to an 08M2 but can't seem to get Timer1 to start properly - I keep getting 0 values after attempting to time a pause. Any help would be greatly appreciated. It's probably something simple but the solution escapes me.
Thanks,
Bob D


Code:
'08M2 chip running at 8 mhz
'This module enables you to time events in milliseconds using Timer1. 

'RAM Addresses:
Symbol RAM_PIR1 = $11
Symbol RAM_T1CON = $18
Symbol RAM_TMR1 = $16

'PIR1:
Symbol ADIF_BIT = bit6
Symbol RCIF_BIT = bit5
Symbol TXIF_BIT = bit4
Symbol SSPIF_BIT = bit3
Symbol CCP1IF_BIT = bit2
Symbol TMR2IF_BIT = bit1
Symbol TMR1IF_BIT = bit0

'T1CON:
Symbol TMRCS1_Bit=bit7
Symbol T1RUN_BIT = bit6		'TMRCS
Symbol T1CKPS1_BIT = bit5	'
Symbol T1CKPS0_BIT = bit4
Symbol T1OSCEN_BIT = bit3
Symbol NOT_T1SYNC_BIT = bit2
Symbol T1INSYNC_BIT = bit2
Symbol TMR1CS_BIT = bit1
Symbol TMR1ON_BIT = bit0

'General Timer1 variable
Symbol Timer1ValueW = w5
Symbol T1CON = b0
Symbol PIR1 = b0

setfreq m8

'InitialiseTimer1:
'Sets the T1CON control register. Only needs to be called once, before
'using Timer1.
TMRCS1_Bit=0	'
T1RUN_BIT =1	'01 =Timer1 clock source is system clock (FOSC)
T1CKPS1_BIT = 1'Divide by 8 Pre-Scaler
T1CKPS0_BIT = 1'Divide by 8 Pre-Scaler
T1OSCEN_BIT = 0'External LP Oscillator Not Enabled
NOT_T1SYNC_BIT = 0'Ignored if Internal Clock
TMR1CS_BIT = 0'Unimplemented
TMR1ON_BIT = 1'Timer 1 Enabled

Poke RAM_T1CON,T1CON 'Set T1CON
'Return

'ResetAndStartTimer1:
'Clear Timer1 and the interrupt(overflow) flag. Start Timer1.

'Set both LSB and MSB of Timer1 to 0
Poke RAM_TMR1,0,0

'Clear Timer1 Interrupt
Peek RAM_PIR1,PIR1
TMR1IF_BIT = 0
Poke RAM_PIR1,PIR1

'Start Timer1
Peek RAM_T1CON,T1CON
TMR1ON_BIT = 1 
Poke RAM_T1CON,T1CON
'Return
pause 2000			'pause 1 sec
'GetTime:
'Stop Timer1, Load the result into Timer1ValueW and convert it 
'to milliseconds (Assumes an 8MHz clock)

'Stop Timer1
Peek RAM_T1CON,T1CON
TMR1ON_BIT = 0 
Poke RAM_T1CON,T1CON

'Load result
Peek RAM_TMR1,Word Timer1ValueW 
'sertxd(#Timer1ValueW," = Timer Value",cr,lf)
'Convert result to milliseconds.
'With a 8MHz clock, and a pre-scaler of 1:1, Timer1 increments every 0.5uS.
'With a pre-scaler of 1:8 it increments every 4uS. So the time in uS = 
'4 * Timer1ValueW. So the time in mS = 4 * Time1ValueW / 1000 = 
'Timer1ValueW / 250. 
Timer1ValueW = Timer1ValueW / 250 

'Check for Timer1 overflow and if it has overflowed add on another 262ms
'onto Timer1ValueW

Peek RAM_PIR1,PIR1
If TMR1IF_BIT = 1 Then
	Timer1ValueW = Timer1ValueW + 262
	sertxd(#Timer1ValueW," = Timer Overflow Value",cr,lf)
Endif
sertxd(#Timer1ValueW," = Timer Value",cr,lf)
'Return
 

hippy

Ex-Staff (retired)
The original code was for an 18X and the 08M2 has a somewhat different internal structure, in particular PEEK and POKE have become PEEKSFR and POKESFR for accessing the internal SFR registers, and it is possible that some of the address and bit definitions for each SFR have changed.
 

Climoni

New Member
Hippy....thanks for the response. I did change the T1CON, PIR1, and TMR1L addresses to match the 08M2 datasheet. I tried PEEKSFR/POKESFR originally but still didn't work but maybe I had something else messed up. Will go back and try again. Thanks
 

Climoni

New Member
The PEEKSFR/POKESFR change worked! I can't believe I messed that up! This was my first attempt at using peek/poke/memory maps, etc. and I guess I was juggling too many variables at once.
Thanks Hippy for the words of wisdom.
 

Climoni

New Member
For everyone's benefit, can you share your timer code for the 08M2?
Code is below, however..... still needs work. By changing the peek/poke the counter started but the PIR1 overflow flag isn't setting or I'm not reading it properly. See chart.08M2 Timer1.jpg



Code:
#rem
################################################## #######
# TIMER1 TEST CODE  for 08M2# adapted from code posted on Picaxe Forum
#by Jeremy Leach and Hippy 
################################################## #######
#endrem

Symbol TimePeriod = w2
Symbol TempW = w3
Symbol Timer1ValueW = w5
'RAM Addresses:
Symbol RAM_PIR1 = $11
Symbol RAM_T1CON = $18
Symbol RAM_TMR1 = $16

'PIR1:
Symbol ADIF_BIT = bit6
Symbol RCIF_BIT = bit5
Symbol TXIF_BIT = bit4
Symbol SSPIF_BIT = bit3
Symbol CCP1IF_BIT = bit2
Symbol TMR2IF_BIT = bit1
Symbol TMR1IF_BIT = bit0

'T1CON:
Symbol T1RUN_BIT = bit6
Symbol T1CKPS1_BIT = bit5
Symbol T1CKPS0_BIT = bit4
Symbol T1OSCEN_BIT = bit3
Symbol NOT_T1SYNC_BIT = bit2
Symbol T1INSYNC_BIT = bit2
Symbol TMR1CS_BIT = bit1
Symbol TMR1ON_BIT = bit0



Symbol T1CON = b0
Symbol PIR1 = b0

Initialise:
	SetFreq M8
	Gosub InitialiseTimer1

Main:
	For TimePeriod = 0 To 520 Step 10 'in milliseconds
		'Because using M8 need to double for Pause command
		TempW = TimePeriod * 2

		'Reset Timer1
		Gosub ResetAndStartTimer1

		'Simulate a delay dues to a block of code executing...
		Pause TempW

		'Get the elspased time
		Gosub GetTime

		'Transmit the results
		SerTxd ("Paused = ",#TimePeriod," ms. Measured = ",#Timer1ValueW," ms",CR,LF)
	Next
Goto Main

#Rem
################################################## #######
# TIMER1 'MODULE'. J.Leach December 2006 #
################################################## #######

This module enables you to time events in milliseconds using Timer1.

At 8MHz clock the maximum time that can be measured is 524ms

These routines have been written following discovery of the detail
by the Happy Hippy.

#endrem


'------------------------------------------------------------------------------------------
InitialiseTimer1:
	'Sets the T1CON control register. Only needs to be called once, before
	'using Timer1.

	T1CKPS1_BIT = 1'Divide by 8 Pre-Scaler
	T1CKPS0_BIT = 1'Divide by 8 Pre-Scaler
	T1OSCEN_BIT = 0'External LP Oscillator Not Enabled
	NOT_T1SYNC_BIT = 0'Ignored if Internal Clock
	TMR1CS_BIT = 0'Internal Clock
	TMR1ON_BIT = 0'Timer 1 Disabled

	Pokesfr RAM_T1CON,T1CON 'Set T1CON
Return
'-----------------------------------------------------------------------------------------
ResetAndStartTimer1:
	'Clear Timer1 and the interrupt(overflow) flag. Start Timer1.

	'Set both LSB and MSB of Timer1 to 0
	Pokesfr RAM_TMR1,0,0

	'Clear Timer1 Interrupt
	Peeksfr RAM_PIR1,PIR1
	TMR1IF_BIT = 0
	Pokesfr RAM_PIR1,PIR1

	'Start Timer1
	Peeksfr RAM_T1CON,T1CON
	TMR1ON_BIT = 1
	Pokesfr RAM_T1CON,T1CON
Return
'-----------------------------------------------------------------------------------------
GetTime:
	'Stop Timer1, Load the result into Timer1ValueW and convert it
	'to milliseconds (Assumes an 8MHz clock)

	'Stop Timer1
	Peeksfr RAM_T1CON,T1CON
	TMR1ON_BIT = 0
	Pokesfr RAM_T1CON,T1CON

	'Load result
	Peeksfr RAM_TMR1,Word Timer1ValueW
	'sertxd(#Timer1ValueW," = timer value",cr,lf)
	'Convert result to milliseconds.
	'With a 8MHz clock, and a pre-scaler of 1:1, Timer1 increments every 0.5uS.
	'With a pre-scaler of 1:8 it increments every 4uS. So the time in uS =
	'4 * Timer1ValueW. So the time in mS = 4 * Time1ValueW / 1000 =
	'Timer1ValueW / 250.
	Timer1ValueW = Timer1ValueW / 250

	'Check for Timer1 overflow and if it has overflowed add on another 262ms
	'onto Timer1ValueW

	Peeksfr RAM_PIR1,PIR1
	If TMR1IF_BIT = 1 Then
		'Timer1ValueW = Timer1ValueW + 262
		sertxd("     Timer1 Overflow ",cr,lf)
	Endif

Return
 

hippy

Ex-Staff (retired)
the PIR1 overflow flag isn't setting or I'm not reading it properly.
It might be that the internal 'time' handling is using Timer 1 and swallowing the overflow. Try adding ...

Symbol PIE1 = $31 ' $091
Symbol TMR1IE_BIT = bit0

DisableTime
PeekSfr PIE1, b0
TMR1IE_BIT = 0
PokeSfr PIE1, b0
 

Climoni

New Member
OKKKAAAYYY...... Thanks, Hippy. You were correct as usual. I actually looked at PIE1 but decided it shouldn't have an effect - wrong again. Also changed the internal clock to Fosc/4. Code seems to work properly (see below). 08M2 Timer1.jpg

Once again, thanks to everyone. This has been a true learning experience for me and I appreciate the help.
Bob D

Code:
#rem
################################################## #######
# TIMER1 TEST CODE  for 08M2 by Bob D
#adapted from code posted on Picaxe Forum
#by Jeremy Leach and Hippy 
#Program compares delay commanded by PAUSE with measured delay
#using TIMER1 
################################################## #######
#endrem


Symbol PIE1 = $31 		' $091 PIE1 memory location	
Symbol TMR1IE_BIT = bit0	'controls the TIMER1 overflow interrupt


Symbol TimePeriod = w2
Symbol TempW = w3
Symbol Timer1ValueW = w5
'RAM Addresses:
Symbol RAM_PIR1 = $11
Symbol RAM_T1CON = $18
Symbol RAM_TMR1 = $16

'PIR1:
Symbol TMR1GF_BIT = bit7	'Timer1 Gate Interrupt Flag bit
Symbol ADIF_BIT = bit6		'A/D Converter Interrupt Flag bit
Symbol RCIF_BIT = bit5		'USART Receive Interrupt Flag bit
Symbol TXIF_BIT = bit4		'USART Transmit Interrupt Flag bit
Symbol SSPIF_BIT = bit3		'Synchronous Serial Port (MSSP) Interrupt Flag bit
Symbol CCP1IF_BIT = bit2	'CCP1 Interrupt Flag bit
Symbol TMR2IF_BIT = bit1	'Timer2 to PR2 Interrupt Flag bit
Symbol TMR1IF_BIT = bit0	'Timer1 Overflow Interrupt Flag bit

'T1CON:
Symbol TMR1CSH_Bit = bit7	'Timer1 Clock Source Select bits
Symbol TMR1CSL_Bit = bit6	'Timer1 Clock Source Select bits
Symbol T1CKPS1_BIT = bit5	'Timer1 Input Clock Prescale Select bits
Symbol T1CKPS0_BIT = bit4	'Timer1 Input Clock Prescale Select bits
Symbol T1OSCEN_BIT = bit3	'LP Oscillator Enable Control bit
Symbol T1SYNC_BIT = bit2	'Timer1 External Clock Input Synchronization Control bit
Symbol Unimplemented_BIT = bit1
Symbol TMR1ON_BIT = bit0	'Timer1 On bit;1 = Enables Timer1;0 = Stops Timer1 Clears Timer1 Gate flip-flop



Symbol T1CON = b0
Symbol PIR1 = b0

Initialise:
	SetFreq M8
	Gosub InitialiseTimer1

Main:
	For TimePeriod = 0 To 520 Step 10 'in milliseconds
		'Because using M8 need to double for Pause command
		TempW = TimePeriod * 2

		'Reset Timer1
		Gosub ResetAndStartTimer1

		'Simulate a delay dues to a block of code executing...
		Pause TempW

		'Get the elspased time
		Gosub GetTime

		'Transmit the results
		SerTxd ("Commanded Pause = ",#TimePeriod," ms. Measured = ",#Timer1ValueW," ms",CR,LF)
	Next
Goto Main


'------------------------------------------------------------------------------------------
InitialiseTimer1:
	'Sets the T1CON control register. Only needs to be called once, before
	'using Timer1.
	
	'DisableTime	
	PeekSfr PIE1, b0	
	TMR1IE_BIT = 0	
	PokeSfr PIE1, b0
	
	
	Peeksfr RAM_PIR1,PIR1
	
	TMR1GF_BIT = 0	'Timer1 Gate Interrupt Flag bit
 	ADIF_BIT = 0	'A/D Converter Interrupt Flag bit
 	RCIF_BIT = 0	'USART Receive Interrupt Flag bit
 	TXIF_BIT = 0	'USART Transmit Interrupt Flag bit
 	SSPIF_BIT = 0	'Synchronous Serial Port (MSSP) Interrupt Flag bit
 	CCP1IF_BIT = 0	'CCP1 Interrupt Flag bit
	TMR2IF_BIT = 0	'Timer2 to PR2 Interrupt Flag bit
	TMR1IF_BIT = 0
	
	Pokesfr RAM_PIR1,PIR1
	
	Peeksfr RAM_T1CON,T1CON
	
	TMR1CSH_Bit =0	'Timer1 clock source is system clock (FOSC)
	TMR1CSL_BIT = 0	'Timer1 clock source is system clock (FOSC/4)
	T1CKPS1_BIT = 1	'Divide by 8 Pre-Scaler
	T1CKPS0_BIT = 1	'Divide by 8 Pre-Scaler
	T1OSCEN_BIT = 0	'Dedicated Timer1 oscillator circuit disabled
	T1SYNC_BIT = 0	'Ignored if Internal Clock
	Unimplemented_BIT =0
	TMR1ON_BIT = 0	'Timer 1 Disabled

	Pokesfr RAM_T1CON,T1CON 'Set T1CON
Return
'-----------------------------------------------------------------------------------------
ResetAndStartTimer1:
	'Clear Timer1 and the interrupt(overflow) flag. Start Timer1.
			
	'Set both LSB and MSB of Timer1 to 0
	Pokesfr RAM_TMR1,0,0
	
	'Disable TIMER1 Overflow Interrupt
	'PeekSfr PIE1, b0
	'TMR1IE_BIT = 0
	'PokeSfr PIE1, b0

	'Clear Timer1 Interrupt Overflow Flag
	Peeksfr RAM_PIR1,PIR1
	TMR1IF_BIT = 0		'Interrupt is not pending	
	Pokesfr RAM_PIR1,PIR1

	'Start Timer1
	Peeksfr RAM_T1CON,T1CON
	TMR1ON_BIT = 1		'Enables Timer1
	Pokesfr RAM_T1CON,T1CON
Return
'-----------------------------------------------------------------------------------------
GetTime:
	'Stop Timer1, Load the result into Timer1ValueW and convert it
	'to milliseconds (Assumes an 8MHz clock)
	
	'Stop Timer1
	Peeksfr RAM_T1CON,T1CON
	TMR1ON_BIT = 0		'Stops Timer1
	Pokesfr RAM_T1CON,T1CON

	'Load result
	Peeksfr RAM_TMR1,Word Timer1ValueW
	'sertxd(#Timer1ValueW," = timer value",cr,lf)
	'Convert result to milliseconds.
	'With a 8MHz clock, and a pre-scaler of 1:1, Timer1 increments every 0.5uS.
	'With a pre-scaler of 1:8 it increments every 4uS. So the time in uS =
	'4 * Timer1ValueW. So the time in mS = 4 * Time1ValueW / 1000 =
	'Timer1ValueW / 250.
	Timer1ValueW = Timer1ValueW / 250

	'Check for Timer1 overflow and if it has overflowed add on another 262ms
	'onto Timer1ValueW

	Peeksfr RAM_PIR1,PIR1
	If TMR1IF_BIT = 1 Then
		Timer1ValueW = Timer1ValueW + 262
				
	Endif

Return
Results of measurements:
Commanded Pause = 0 ms. Measured = 2 ms
Commanded Pause = 10 ms. Measured = 12 ms
Commanded Pause = 20 ms. Measured = 22 ms
Commanded Pause = 30 ms. Measured = 32 ms
Commanded Pause = 40 ms. Measured = 42 ms
Commanded Pause = 50 ms. Measured = 52 ms
Commanded Pause = 60 ms. Measured = 62 ms
Commanded Pause = 70 ms. Measured = 72 ms
Commanded Pause = 80 ms. Measured = 82 ms
Commanded Pause = 90 ms. Measured = 92 ms
Commanded Pause = 100 ms. Measured = 102 ms
Commanded Pause = 110 ms. Measured = 112 ms
Commanded Pause = 120 ms. Measured = 122 ms
Commanded Pause = 130 ms. Measured = 132 ms
Commanded Pause = 140 ms. Measured = 142 ms
Commanded Pause = 150 ms. Measured = 152 ms
Commanded Pause = 160 ms. Measured = 162 ms
Commanded Pause = 170 ms. Measured = 171 ms
Commanded Pause = 180 ms. Measured = 181 ms
Commanded Pause = 190 ms. Measured = 191 ms
Commanded Pause = 200 ms. Measured = 201 ms
Commanded Pause = 210 ms. Measured = 211 ms
Commanded Pause = 220 ms. Measured = 221 ms
Commanded Pause = 230 ms. Measured = 231 ms
Commanded Pause = 240 ms. Measured = 241 ms
Commanded Pause = 250 ms. Measured = 251 ms
Commanded Pause = 260 ms. Measured = 261 ms
Commanded Pause = 270 ms. Measured = 271 ms
Commanded Pause = 280 ms. Measured = 281 ms
Commanded Pause = 290 ms. Measured = 291 ms
Commanded Pause = 300 ms. Measured = 301 ms
Commanded Pause = 310 ms. Measured = 311 ms
Commanded Pause = 320 ms. Measured = 321 ms
Commanded Pause = 330 ms. Measured = 331 ms
Commanded Pause = 340 ms. Measured = 341 ms
Commanded Pause = 350 ms. Measured = 351 ms
Commanded Pause = 360 ms. Measured = 361 ms
Commanded Pause = 370 ms. Measured = 371 ms
Commanded Pause = 380 ms. Measured = 381 ms
Commanded Pause = 390 ms. Measured = 391 ms
Commanded Pause = 400 ms. Measured = 401 ms
Commanded Pause = 410 ms. Measured = 411 ms
Commanded Pause = 420 ms. Measured = 421 ms
Commanded Pause = 430 ms. Measured = 431 ms
Commanded Pause = 440 ms. Measured = 441 ms
Commanded Pause = 450 ms. Measured = 451 ms
Commanded Pause = 460 ms. Measured = 460 ms
Commanded Pause = 470 ms. Measured = 470 ms
Commanded Pause = 480 ms. Measured = 480 ms
Commanded Pause = 490 ms. Measured = 490 ms
Commanded Pause = 500 ms. Measured = 500 ms
Commanded Pause = 510 ms. Measured = 510 ms
Commanded Pause = 520 ms. Measured = 520 ms
 

jaybeetoo

New Member
I have tried the original TIMER1 code on a PICAXE 28X2 and I get these results:

Code:
Paused = 40ms. Measured = 0ms.
Paused = 50ms. Measured = 0ms.
Paused = 60ms. Measured = 0ms.
Paused = 70ms. Measured = 0ms.
Paused = 80ms. Measured = 0ms.
Paused = 90ms. Measured = 0ms.
Paused = 100ms. Measured = 0ms.
Paused = 110ms. Measured = 0ms.
Paused = 120ms. Measured = 0ms.
Paused = 130ms. Measured = 0ms.
Paused = 140ms. Measured = 0ms.
Paused = 150ms. Measured = 0ms.
Paused = 160ms. Measured = 0ms.
Paused = 170ms. Measured = 0ms.
Paused = 180ms. Measured = 0ms.
Paused = 190ms. Measured = 0ms.
Paused = 200ms. Measured = 0ms.
Paused = 210ms. Measured = 0ms.
Paused = 220ms. Measured = 0ms.
This is the code I used from http://www.picaxeforum.co.uk/showthread.php?5824-Timer1-a-possible-simple-use-for-it/page2&highlight=timer+jeremy:
Code:
#PICAXE 28X2
#rem
################################################## #######
# TIMER1 TEST CODE #
################################################## #######
#endrem

Symbol TimePeriod = w2
Symbol TempW = w3
Symbol Timer1ValueW = w5

Initialise:
SetFreq M8
Gosub InitialiseTimer1

Main:
For TimePeriod = 0 To 520 Step 10 'in milliseconds
'Because using M8 need to double for Pause command
TempW = TimePeriod * 2 

'Reset Timer1 
Gosub ResetAndStartTimer1

'Simulate a delay dues to a block of code executing...
Pause TempW

'Get the elspased time
Gosub GetTime

'Transmit the results
SerTxd ("Paused = ",#TimePeriod,"ms. Measured = ",#Timer1ValueW,"ms.",CR,LF)
Next
Goto Main	

#Rem
################################################## #######
# TIMER1 'MODULE'. J.Leach December 2006 #
################################################## #######

This module enables you to time events in milliseconds using Timer1. 

At 8MHz clock the maximum time that can be meaured is 524ms

These routines have been written following discovery of the detail 
by the Happy Hippy.

#endrem

'RAM Addresses:
Symbol RAM_PIR1	 = $0C
Symbol RAM_T1CON	 = $10
Symbol RAM_TMR1	 = $0E

'PIR1:
Symbol ADIF_BIT	 = bit6
Symbol RCIF_BIT	 = bit5
Symbol TXIF_BIT	 = bit4
Symbol SSPIF_BIT	 = bit3
Symbol CCP1IF_BIT	 = bit2
Symbol TMR2IF_BIT	 = bit1
Symbol TMR1IF_BIT	 = bit0

'T1CON:
Symbol T1RUN_BIT	 = bit6
Symbol T1CKPS1_BIT	= bit5
Symbol T1CKPS0_BIT	= bit4
Symbol T1OSCEN_BIT	= bit3
Symbol NOT_T1SYNC_BIT	= bit2
Symbol T1INSYNC_BIT	= bit2
Symbol TMR1CS_BIT	 = bit1
Symbol TMR1ON_BIT	 = bit0

'General Timer1 variable
'Symbol Timer1ValueW = w0 'Set to any suitable Word variable, but not w0.
Symbol T1CON = b0
Symbol PIR1 = b0

InitialiseTimer1:
'Sets the T1CON control register. Only needs to be called once, before
'using Timer1.

T1CKPS1_BIT	 = 1'Divide by 8 Pre-Scaler
T1CKPS0_BIT	 = 1'Divide by 8 Pre-Scaler
T1OSCEN_BIT	 = 0'External LP Oscillator Not Enabled
NOT_T1SYNC_BIT	= 0'Ignored if Internal Clock
TMR1CS_BIT	 = 0'Internal Clock
TMR1ON_BIT	 = 0'Timer 1 Disabled

Poke RAM_T1CON,T1CON 'Set T1CON
Return

ResetAndStartTimer1:
'Clear Timer1 and the interrupt(overflow) flag. Start Timer1.

'Set both LSB and MSB of Timer1 to 0
Poke RAM_TMR1,0,0

'Clear Timer1 Interrupt
Peek RAM_PIR1,PIR1
TMR1IF_BIT = 0
Poke RAM_PIR1,PIR1

'Start Timer1
Peek RAM_T1CON,T1CON
TMR1ON_BIT = 1 
Poke RAM_T1CON,T1CON
Return

GetTime:
'Stop Timer1, Load the result into Timer1ValueW and convert it 
'to milliseconds (Assumes an 8MHz clock)

'Stop Timer1
Peek RAM_T1CON,T1CON
TMR1ON_BIT = 0 
Poke RAM_T1CON,T1CON

'Load result
Peek RAM_TMR1,Word Timer1ValueW 

'Convert result to milliseconds.
'With a 8MHz clock, and a pre-scaler of 1:1, Timer1 increments every 0.5uS.
'With a pre-scaler of 1:8 it increments every 4uS. So the time in uS = 
'4 * Timer1ValueW. So the time in mS = 4 * Time1ValueW / 1000 = 
'Timer1ValueW / 250. 
Timer1ValueW = Timer1ValueW / 250 

'Check for Timer1 overflow and if it has overflowed add on another 262ms
'onto Timer1ValueW

Peek RAM_PIR1,PIR1
If TMR1IF_BIT = 1 Then
Timer1ValueW = Timer1ValueW + 262
Endif
Return
Is there something different about the 28X2 that causes this not to work?
 

hippy

Ex-Staff (retired)
Is there something different about the 28X2 that causes this not to work?
Yes, as srnet says it was written for a different chip architecture. In moving to the 28X2 -

Need to use PEEKSFR/POKESFR rather than PEEK/POKE
Need to change SFR addresses
Might need to adjust SFR bit locations
May need to use different SFR registers
 

jaybeetoo

New Member
Here is my modified Timer1 code for the 28X2:

Code:
#PICAXE 28X2

#rem
#
#######################################################
# TIMER1 test code						#
#######################################################
#endrem


; Timer1 result
	symbol Timer1ValueW	= W1
	symbol Timer1ValueWL	= b2
	symbol Timer1ValueWH	= b3

; Variables for test
	symbol TimePeriod	= W2

Initialise:
	SetFreq M8
	gosub InitialiseTimer1
	
Main:
	for TimePeriod = 0 to 520 step 10	; in milliseconds
				
		; Reset Timer1
		gosub ResetAndStartTimer1
		
		; Simulate a delay due to a block of code executing...
		pause TimePeriod
		
		; Get the elapsed time
		gosub GetTime
	
		; Transmit the results
		sertxd (CR,LF, "Paused = ", #TimePeriod, "ms. Measured = ", #Timer1ValueW, "ms.")
	
	next TimePeriod
 
 	goto main

	end

#rem
#
#######################################################
# TIMER1 'MODULE'. J.Leach December 2006			#
#	Modified for 28X2 by jaybeetoo May 2013		#
#######################################################

This module enables you to time events in milliseconds using Timer1. 

At 8MHz clock the maximum time that can be meaured is 524ms

These routines have been written following discovery of the detail 
by the Happy Hippy.

#endrem

; Registers
	symbol SFR_T1CON	= $CD	; TIMER1 CONTROL REGISTER
	symbol SFR_TMR1H	= $CF	; Timer1 high byte
	symbol SFR_TMR1L	= $CE	; Timer1 low byte
	symbol SFR_PIR1	= $9E	; PIR1: PERIPHERAL INTERRUPT REQUEST (FLAG) REGISTER 1

; TXCON: TIMER1 CONTROL REGISTER
;	bit 7-6 TMRxCS<1:0>: Timer1/3/5 Clock Source Select bits
;			11 =Reserved. Do not use.
;			10 =Timer1/3/5 clock source is pin or oscillator:
;				If TxSOSCEN = 0:
;					External clock from TxCKI pin (on the rising edge)
;				If TxSOSCEN = 1:
;					Crystal oscillator on SOSCI/SOSCO pins
;			01 =Timer1/3/5 clock source is system clock (FOSC)
;			00 =Timer1/3/5 clock source is instruction clock (FOSC/4)
;	bit 5-4 TxCKPS<1:0>: Timer1/3/5 Input Clock Prescale Select bits
;			11 = 1:8 Prescale value
;			10 = 1:4 Prescale value
;			01 = 1:2 Prescale value
;			00 = 1:1 Prescale value
;	bit 3 TxSOSCEN: Secondary Oscillator Enable Control bit
;			1 = Dedicated Secondary oscillator circuit enabled
;			0 = Dedicated Secondary oscillator circuit disabled
;	bit 2 TxSYNC: Timer1/3/5 External Clock Input Synchronization Control bit
;			TMRxCS<1:0> = 1X
;			1 = Do not synchronize external clock input
;			0 = Synchronize external clock input with system clock (FOSC)
;
;			TMRxCS<1:0> = 0X
;			This bit is ignored. Timer1/3/5 uses the internal clock when TMRxCS<1:0> = 1X.
;	bit 1 TxRD16: 16-Bit Read/Write Mode Enable bit
;			1 = Enables register read/write of Timer1/3/5 in one 16-bit operation
;			0 = Enables register read/write of Timer1/3/5 in two 8-bit operation
;	bit 0 TMRxON: Timer1/3/5 On bit
;			1 = Enables Timer1/3/5
;			0 = Stops Timer1/3/5
;				Clears Timer1/3/5 Gate flip-flop
	symbol T1CON	= b0
	symbol TMR1CS1	= bit7
	symbol TMR1CS2	= bit6
	symbol T1CKPS1	= bit5
	symbol T1CKPS0	= bit4
	symbol T1SOSCEN	= bit3
	symbol T1SYNC	= bit2
	symbol T1RD16	= bit1
	symbol TMR1ON	= bit0

; PIR1: PERIPHERAL INTERRUPT REQUEST (FLAG) REGISTER 1
;	bit 7 Unimplemented: Read as &#8216;0&#8217;.
;	bit 6 ADIF: A/D Converter Interrupt Flag bit
;		1 = An A/D conversion completed (must be cleared by software)
;		0 = The A/D conversion is not complete or has not been started
;	bit 5 RC1IF: EUSART1 Receive Interrupt Flag bit
;		1 = The EUSART1 receive buffer, RCREG1, is full (cleared when RCREG1 is read)
;		0 = The EUSART1 receive buffer is empty
;	bit 4 TX1IF: EUSART1 Transmit Interrupt Flag bit
;		1 = The EUSART1 transmit buffer, TXREG1, is empty (cleared when TXREG1 is written)
;		0 = The EUSART1 transmit buffer is full
;	bit 3 SSP1IF: Master Synchronous Serial Port 1 Interrupt Flag bit
;		1 = The transmission/reception is complete (must be cleared by software)
;		0 = Waiting to transmit/receive
;	bit 2 CCP1IF: CCP1 Interrupt Flag bit
;		Capture mode:
;		1 = A TMR1 register capture occurred (must be cleared by software)
;		0 = No TMR1 register capture occurred
;		Compare mode:
;		1 = A TMR1 register compare match occurred (must be cleared by software)
;		0 = No TMR1 register compare match occurred
;		PWM mode:
;		Unused in this mode
;	bit 1 TMR2IF: TMR2 to PR2 Match Interrupt Flag bit
;		1 = TMR2 to PR2 match occurred (must be cleared by software)
;		0 = No TMR2 to PR2 match occurred
;	bit 0 TMR1IF: TMR1 Overflow Interrupt Flag bit
;		1 = TMR1 register overflowed (must be cleared by software)
;		0 = TMR1 register did not overflow
	symbol PIR1		= b0
	symbol TMR1IF	= bit0

InitialiseTimer1:
	; Sets the TIMER1 control register
	TMR1CS1	= 0	; Timer1 clock source is instruction clock (FOSC/4)
	TMR1CS2	= 0	; Timer1/3/5 clock source is instruction clock (FOSC/4)
	T1CKPS1	= 1	; 1:8 Prescale value
	T1CKPS0	= 1	; 1:8 Prescale value
	T1SOSCEN	= 0	; Dedicated Secondary oscillator circuit disabled
	T1SYNC	= 1	; Do not synchronize external clock input
	T1RD16	= 0 	; Enables register read/write of Timer1 in two 8-bit operation
	TMR1ON	= 0	; Stops Timer1

	pokeSFR SFR_T1CON, T1CON	; Set TIMER1 control register

	return

ResetAndStartTimer1:
	; Clear Timer1 and the interrupt (overflow) flag, Start Timer1
	
	; Set Timer1 to 0
	pokeSFR SFR_TMR1H, 0
	pokeSFR SFR_TMR1L, 0
	
	; Clear Timer 1 overflow interrupt
	peekSFR SFR_PIR1, PIR1
	TMR1IF = 0
	pokeSFR SFR_PIR1, PIR1
	
	; Start Timer1
	peekSFR SFR_T1CON, T1CON
	TMR1ON   = 1	;	 Enables Timer1
	pokeSFR SFR_T1CON, T1CON

	return

GetTime:
	; Stop Timer1, load the results into Timer1ValueW and convert it
	; to milliseconds (assumes 8MHz clock)
	
	; Stopt Timer1
	peekSFR SFR_T1CON, T1CON
	TMR1ON   = 0	;	 Stops Timer1
	pokeSFR SFR_T1CON, T1CON
	
	; Get result
	peekSFR SFR_TMR1H, Timer1ValueWH
	peekSFR SFR_TMR1L, Timer1ValueWL
	
	; Convert result to milliseconds
	Timer1ValueW = Timer1ValueW / 250
	
	; Check for an overflow
	peekSFR SFR_PIR1, PIR1
	if TMR1IF = 1 then
		 Timer1ValueW = Timer1ValueW + 262
	endif
	
	return
 

jaybeetoo

New Member
And here is the output:

Code:
Paused = 50ms. Measured = 51ms.
Paused = 60ms. Measured = 61ms.
Paused = 70ms. Measured = 71ms.
Paused = 80ms. Measured = 81ms.
Paused = 90ms. Measured = 91ms.
Paused = 100ms. Measured = 101ms.
Paused = 110ms. Measured = 111ms.
Paused = 120ms. Measured = 121ms.
Paused = 130ms. Measured = 131ms.
Paused = 140ms. Measured = 141ms.
Paused = 150ms. Measured = 151ms.
Paused = 160ms. Measured = 161ms.
Paused = 170ms. Measured = 171ms.
Paused = 180ms. Measured = 181ms.
Paused = 190ms. Measured = 191ms.
Paused = 200ms. Measured = 201ms.
Paused = 210ms. Measured = 211ms.
Paused = 220ms. Measured = 220ms.
 
Top