PDA

View Full Version : High resolution timer problem



Macgman2000
- 13th May 2010, 17:53
Hello,

I am trying to use Robert Wozniak's high resolution timer on a 18F4680. I am using MPASM due to
DT's interrupts. I have the latest everything so I should be good to go. I am getting more errors than I can copy and paste. It says "Fatal error (21), and
numerous "bad data type" errors.

Does this software require PBPL? Or should it work with regular PBP? Any insight would be appreciated.

Nick

Darrel Taylor
- 13th May 2010, 18:56
Yes, WOZZY wrote that for PBPL.
I think he was using it to make displaying the numbers easier.

But since it uses N-Bit_Math, you can do the same thing without PBPL or even on 16F's.
The Timers doing most of the work. You just need to catch the overflows and do the math.

And there's a routine to display large numbers without PBPL now (using N-Bit_Math).
http://www.picbasic.co.uk/forum/showthread.php?t=13214&p=89430#post89430

Macgman2000
- 13th May 2010, 19:07
Hello Darrel,

Here is the code I am working with. With all the includes, and PBP....still getting errors.




'************************************************* *****************
'*********************[ High-Resolution Timer ]********************
'************************************************* *****************
'** Author : Robert Wozniak, Robert.Wozniak -at- gmail.com **
'** Notice : This code may be freely used and distributed **
'** for use in non-commercial applications **
'** Version : 6.10 : Feb 06, 2010 **
'** Date : JAN 14, 2010 **
'************************************************* *****************
'** Versions: **
'** 6.0 : All 64 bit MATH, 99 min limit **
'** 5.0 : Working Timer and Speed Calculator with 64 bit math **
'************************************************* *****************
'** Hardware Tested: PIC18F4680 @20MHz **
'** 4x16 Parallel LCD Module **
'** PBP 2.60 / MPLAB IDE 8.40.000 **
'** Compiled with: [-n -ampasmwin] Build Options **
'** 32 BIT LONG SIGNED INTEGER **
'** **
'** Thanks to Darrel & Bruce at MEL PB Forums for Code examples **
'** Alexander for N-Bit Math...Excellent ASM code **
'************************************************* *****************
'** MAX OVRFLO=457763, COUNTS=44041 for 99min:59.9999998sec **
'** MIN OVRFLO=0, COUNTS=261 for 9999.999MPH **
'************************************************* *****************

PRECISION CON 8 SYSTEM ; Set 8 bytes = 64-bit Precision for N-Bit_Math.pbp

INCLUDE "N-BIT_Math.pbp" ; Include Alexander Avtanski's Multibyte Arithmetic
; Assembly Library Wrapped for PBP by Darrel Taylor [Version:1.3 Beta (JAN 07,2010)]
; Version:1.3 Beta (1/7/2010)
INCLUDE "DT_INTS-18.bas" ; Include Darrel Taylor's Base Interrupt System for PIC18F [Version:3.3 (MAR 24, 2008)]
INCLUDE "ReEnterPBP-18.bas" ; Include Darrel Taylor's PBP interrupts for PIC18F [Version:1.4 (MAR 24, 2008)]

DEFINE OSC 20

DEFINE DEBUG_REG PORTC
DEFINE DEBUG_BIT 6
DEFINE DEBUG_BAUD 57600 ' 38400 BAUD N-8-1, PORT C6
DEFINE DEBUG_MODE 1 ' 1 = inverted, 0 = true

DEFINE LCD_DREG PORTA ' Set LCD Data port
DEFINE LCD_DBIT 0 ' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_RSREG PORTA ' Set LCD Register Select port
DEFINE LCD_RSBIT 4 ' Set LCD Register Select bit
DEFINE LCD_EREG PORTB ' Set LCD Enable port
DEFINE LCD_EBIT 3 ' Set LCD Enable bit
DEFINE LCD_BITS 4 ' Set LCD bus size (4 or 8 bits)
DEFINE LCD_LINES 4 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 2000 ' Set command delay time in us (2000)
DEFINE LCD_DATAUS 50 ' Set data delay time in us (50)

TRISA=%00000000 ' SET to Output
TRISC.2=1 ' SET to Input
ADCON0=%11000000
ADCON1=%00000111
T1CON.7=1 ' Set Timer1 to 16 bit mode

LED VAR PORTD.1 ' Alias PORTD.0 to LED
I VAR BYTE
J VAR BYTE
OVRFLO VAR LONG ' Timer1 Overflow total
COUNTS VAR WORD ' Timer1 Counts after falling edge capture
PRESET VAR BYTE
OVFLS32 VAR LONG
COUNTS32 VAR LONG
TSEC32 VAR LONG
OVFLS64 VAR BYTE[PRECISION]
OVFLS64M VAR BYTE[PRECISION]
COUNTS64 VAR BYTE[PRECISION]
TSEC64 VAR BYTE[PRECISION]
BITS16 VAR LONG
BITS1664 VAR BYTE[PRECISION]
TMIN64 VAR BYTE[PRECISION]
TSECINT64 VAR BYTE[PRECISION]
TSECDEC64 VAR BYTE[PRECISION]
CONVSEC VAR LONG
CONVSEC64 VAR BYTE[PRECISION]
AA32 VAR LONG
AA64 VAR BYTE[PRECISION]
BB32 VAR LONG
BB64 VAR BYTE[PRECISION]
CC32 VAR LONG
CC64 VAR BYTE[PRECISION]
TMIN VAR LONG
TSEC VAR LONG
TSECINT VAR LONG
TSECDEC VAR LONG
DISTINCH VAR LONG
DISTFT VAR LONG
DISTFT64 VAR BYTE[PRECISION]
DISTFT64M VAR BYTE[PRECISION]
FPS32 VAR LONG
FPS64 VAR BYTE[PRECISION]
FPSINT VAR LONG
FPSINT64 VAR BYTE[PRECISION]
FPSDEC VAR LONG
FPSDEC64 VAR BYTE[PRECISION]
MPH64 VAR BYTE[PRECISION]
MPHINT64 VAR BYTE[PRECISION]
MPHDEC64 VAR BYTE[PRECISION]
MPH32 VAR LONG
MPHINT VAR LONG
MPHDEC VAR LONG

' ****** Setup Variables with Initial Parameters and 64-BIT Constants
I = 0
J = 1
PRESET = 3 ' ********** PER OVERFLOW LOOP TICS CORRECTION **********
BITS16 = 65536 * 2 ' ********** COUNTS MAX * 200 NS PER TIC**********
@ MOVE?LP _BITS16, _BITS1664
DISTINCH = 6000 ' ********** 6.000 inches (MAX = 65.535 in) **********
DISTFT = ((DISTINCH*10000)/12)
@ MOVE?LP _DISTFT, _DISTFT64 ' ********** CONVERT TO FEET **********
AA32 = 1000000 ' ********** BUMP UP RESOLUTION
@ MOVE?LP _AA32, _AA64
@ MATH_MUL _DISTFT64, _AA64, _DISTFT64M ' ********** BUMP UP DISTANCE DIGITS
CONVSEC = 600000000
@ MOVE?LP _CONVSEC, _CONVSEC64 ' ********** BUMP UP TIME DIGITS


Pause 500
LCDOUT $FE,1
LCDOUT $FE,$80,"HIGH-RESOLUTION "
LCDOUT $FE,$C0," TIMER "
LCDOUT $FE,$90," Version 6.10 "
LCDOUT $FE,$D0," Robert Wozniak "

DEBUG 10,13,10,13,10,13
DEBUG "HIGH-RESOLUTION ",10,13
DEBUG " TIMER ",10,13
DEBUG " Version 6.10 ",10,13
DEBUG " Robert Wozniak ",10,13,10,13,10,13

For I = 1 to 5
HIGH LED ' Turn ON LED connected to PORTD.1
Pause 50
LOW LED
PAUSE 50 ' Turn OFF LED connected to PORTD.1
NEXT I
I = 0

;----[High Priority Interrupts (DT_INTS_18)]----------------------------------------
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler CCP1_INT, _Capture, PBP, yes
INT_Handler TMR1_INT, _Timer1, PBP, yes
endm
INT_CREATE ; Creates the High Priority interrupt processor
ENDASM

CCP1CON = %00000101 ' Capture mode, capture on rising edge
T1CON = 0 ' TMR1 prescale=1, clock=Fosc/4, TMR1=off (200nS per count @20MHz)
@ INT_ENABLE CCP1_INT ; enable Capture interrupts

Main:

IF T1CON.0 <> 0 And I = 0 THEN
LCDOUT $FE,1
LCDOUT $FE,$C0," MEASURING"
I = 1
GOTO LCDEND
ENDIF

IF T1CON.0 <> 0 THEN LCDEND
IF T1CON.0 = 0 AND J = 0 THEN

'********** CONVERT COUNTS, OVERFLOWS to SECONDS **********
@ MOVE?LP _OVRFLO, _OVFLS64
@ MATH_MUL _OVFLS64, _BITS1664, _OVFLS64M
COUNTS32 = (COUNTS-10)*2 ' 10 TICS START CORRECTION, 200 nS PER COUNT
@ MOVE?LP _COUNTS32, _COUNTS64
@ MATH_ADD _OVFLS64M, _COUNTS64, _TSEC64

' ********** CONVERT SECONDS TO MINUTES **********
@ MATH_DIV _TSEC64, _CONVSEC64, _TMIN64
@ MOVE?PL _TMIN64, _TMIN

' ********** GET INTEGER SECONDS **********
CC32 = 10000000
@ MOVE?LP _CC32, _CC64
@ MATH_MUL _TMIN64, _CONVSEC64, _AA64
@ MATH_SUB _TSEC64, _AA64, _BB64
@ MATH_DIV _BB64, _CC64, _TSECINT64
@ MOVE?PL _TSECINT64, _TSECINT

' ********** GET DECIMAL SECONDS **********
@ MATH_MUL _TSECINT64, _CC64, _AA64
@ MATH_SUB _BB64, _AA64, _TSECDEC64
@ MOVE?PL _TSECDEC64, _TSECDEC

' ********** CALCULATE SPEED (FPS) **********
@ MATH_DIV _DISTFT64M, _TSEC64, _FPS64

' ********** GET INTEGER FPS **********
CC32 = 1000000
@ MOVE?LP _CC32, _CC64
@ MATH_DIV _FPS64, _CC64, _FPSINT64
@ MOVE?PL _FPSINT64, _FPSINT

' ********** GET DECIMAL FPS **********
@ MATH_MUL _FPSINT64, _CC64, _BB64
@ MATH_SUB _FPS64, _BB64, _FPSDEC64
@ MOVE?PL _FPSDEC64, _FPSDEC

' ********** CONVERT FPS to MPH **********
AA32 = 15
@ MOVE?LP _AA32, _AA64
BB32 = 22
@ MOVE?LP _BB32, _BB64
@ MATH_MUL _AA64, _FPS64, _CC64
@ MATH_DIV _CC64, _BB64, _MPH64

' ********** GET INTEGER MPH **********
AA32 = 1000000
@ MOVE?LP _AA32, _AA64
@ MATH_DIV _MPH64, _AA64, _MPHINT64
@ MOVE?PL _MPHINT64, _MPHINT

' ********** GET DECIMAL MPH **********
@ MATH_MUL _MPHINT64, _AA64, _BB64
@ MATH_SUB _MPH64, _BB64, _MPHDEC64
@ MOVE?PL _MPHDEC64, _MPHDEC

' ********** DISPLAY RESULTS **********
LCDOUT $FE,1
LCDOUT $FE,$80," ",DEC2 TMIN,":",DEC2 TSECINT,".",DEC7 TSECDEC
LCDOUT $FE,$90, DEC4 FPSINT,".",DEC6 FPSDEC," FPS"
LCDOUT $FE,$D0, DEC4 MPHINT,".",DEC6 MPHDEC," MPH"

DEBUG "OVRFLO: ",DEC10 OVRFLO,13,10
DEBUG "COUNTS: ",DEC10 COUNTS,13,10,13,10
DEBUG "TIME: ",DEC2 TMIN,":", DEC2 TSECINT,".",DEC7 TSECDEC,13,10
DEBUG "SPEED: ",DEC4 FPSINT,".",DEC6 FPSDEC," FPS",13,10
DEBUG "SPEED: ",DEC4 MPHINT,".",DEC6 MPHDEC," MPH",13,10,13,10

J = 1
ENDIF
GOTO LCDEND

LCDEND:
PAUSE 25
@ INT_ENABLE CCP1_INT ; Start new capture
GOTO Main

'---[CCP1 - interrupt handler]------------------------------------------
Capture:
IF CCP1CON = %00000101 THEN ' If rising edge capture then
HIGH LED ' Turn on LED to Indicate Measuring
TMR1L = PRESET ' Clear Timer1 counts with Preset (High)
TMR1H = 0 ' Clear Timer1 counts (LOW)
T1CON.0 = 1 ' Turn Timer1 on at rising edge capture
OVRFLO = 0 ' Zero Over flow counts
COUNTS = 0 ' Zero remainder
CCP1CON = %00000100 ' Switch to falling edge capture
PIR1.0 = 0 ' Clear Timer1 overflow flag before enable
I = 0 : J = 0
@ INT_ENABLE TMR1_INT ; Enable Timer 1 Interrupts
GOTO OVER_CCP ' Done, exit
ENDIF

IF CCP1CON = %00000100 THEN ' If falling edge capture then
T1CON.0 = 0 ' Stop Timer1
CCP1CON = %00000101 ' Switch back to rising edge capture
@ INT_DISABLE TMR1_INT ; Disable Timer 1 Interrupts
@ INT_DISABLE CCP1_INT ; Disable CCP1 Interrupts
COUNTS.LowByte = TMR1L ' Get remaining Timer1 counts on falling edge (Low Byte)
COUNTS.HighByte = TMR1H ' Get remaining Timer1 counts on falling edge (High Byte)
LOW LED ' Turn off LED
ENDIF

OVER_CCP:
@ INT_RETURN

'---[TMR1 - interrupt handler]---------------------------------------------
Timer1:
OVRFLO = OVRFLO + 1
@ INT_RETURN
END

Darrel Taylor
- 13th May 2010, 19:14
Yup, that's WOZZY's code. (for PBPL)

Are you using PBPL now?
If not, you are going to have to make a lot of changes.

Macgman2000
- 13th May 2010, 19:20
I have never used PBPL before. Can I simply point my Microcode studio to use PBPL instead of PBP?

Nick

Darrel Taylor
- 13th May 2010, 19:32
Assuming you have PBP 2.50 or higher ...

In MCS, go to View > Compile and Program Options > Compiler Tab.
And check the "Use PBPL" checkbox.

Macgman2000
- 13th May 2010, 21:19
I have PBP 2.60, Microcode studio 3.0.0.0.
I went to the compiler path and it does not have that option. Only to search automatically or
manually for the compiler. sigh....some how I know it was not going to be that easy..LOL

Darrel Taylor
- 13th May 2010, 21:28
You should have MCS version 3.0.0.5

If not, run the on-line update (MCS+ only) or download the latest free version here.
http://www.mecanique.co.uk/code-studio/

Macgman2000
- 15th May 2010, 17:37
Ok got it to compile without errors and flashed the micro. THANKS!!!
I need to test it Tuesday to see if it works correctly.

Is it possible to modify the code such that I have one start IR and 2 IR stop? My application involves timing the travel of a ball from a starting line to a distance of 15' and as it continues to roll at 40'. Displaying 2 time intervals and the FPS and MPH at 15' and 40'.

Nick