Hi,
I gave it a shot anyway:
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.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
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