Hi,
I gave it a shot anyway:
Code:
PRECISION CON 3 SYSTEM ' 24bits is sufficent for this
INCLUDE "N-bit_Math.pbp" ' Include the math routines.
Dummy1 VAR BYTE[PRECISION] ' Used by N-Bit math
Dummy2 VAR BYTE[PRECISION] ' Used by N-Bit math
Result VAR BYTE[PRECISION] ' Used by N-Bit math
Frequency VAR WORD ' Desired output frequency times 10 (123=12.3Hz)
Reload VAR Word ' Caluclated timer reload value to get desired interrupt rate.
i VAR BYTE ' General purpose counter
HSEROUT ["Start",13]
Main:
For i = 0 to 20
Lookup2 i, [18, 20, 22, 25, 30, 40, 50, 60, 80, 100, 150, 200, 300, 400, 500, 700, 800, 900, 1000, 1100, 1200], Frequency
Gosub CalculateIt
Gosub PrintIt
Pause 100
Next
END
CalculateIt:
' There's 90 "steps" for a complete sine-cycle. If we want 1Hz output frequency
' we need an interrupt frequency of 90Hz, 1/90=0.01111111111111s.
' At 40MHz each instruction cycle (and timertick when prescaler is 1:1) is 100nS
' so 0.0111111111111/100E-9 = 111111 but because we want one decimal place on the
' frequency variable (123 = 12.3Hz) we multiply that by 10 so 1111111.
' Load 1111111 into first 24bit math variable.
Dummy1[2] = $10
Dummy1[1] = $F4
Dummy1[0] = $47
'Load frequency variable into second math variable
Dummy2[2] = 0
Dummy2[1] = Frequency.HighByte
Dummy2[0] = Frequency.LowByte
'Perform the division.
@ MATH_DIV _Dummy1, _Dummy2, _Result
'Move the result to the Reload variable
@ MOVE?PW _Result, _Reload ; Truncate Result into a WORD var
'Negate the value to get the actual reload value.
Reload = -Reload
RETURN
End
PrintIt:
HSEROUT ["Frequency: ", #Frequency/10, ".", #Frequency // 10, "Hz", " Reload: ", #Reload, 13]
Return
1111111 is closer to the real deal than 1120000, upto around Freq=1100 the error is less than 0.01% while at Freq=1200 it "jumps" to 0.1% - pretty good.
Remember that you can not allow the Frequency variable to be less than 17 or you'll end up with a negative reload value which means the frequency will be WAY off. Ie you can't allow Frequency to be 10 for 1Hz output.
Bookmarks