there are three input parameters:

- oscillator speed (crystal or rc value)

- target tmr2 interrupt speed (desired tmr2/4/6 interrupt frequency)

- max prescaler 16:1(standard) or 64:1(enhanced midrange chips)

enter input values then select "do it" and the closest match will be returned with all the parameters, if a match is not found with in the search criteria it will return message "refine search"

the search range is half of the "target tmr2 interrupt speed" value, but applies to both above and below the desired frequency. what i mean by this is, if you desire 100 hz, it will set up a search range of (50 to 150), if desired 1000 it will set a range of (500 to 1500), allowing quicker results by only logging near matches, as it runs through the program when ever a returned value is closer than the high or low search range it modifies the search range to the new high or low range value, this is how it finds the closest match, by looking above the desired and below the desired, then after all is processed it checks to see which is closer to the desired (range_high or range_low), and returns the logged values for those as output results

if you want to see all the math calculations which are many, you can select "more" then hit "do it", it will take a few seconds to log the data, then can scroll veiwing all the combinations for the oscillator and max prescaler settings which are (returned tmr2 freq,prescaler,postscaler,rollover)

there are a couple other helpful features, in theoutput results box there are grey boxes to the left of the results, if you click on one of these boxes you can select to copy the whole line or just the number to clipboard, this allows you to copy the c code lines directly into your flowcharts or the numbers directly into look up tables to run the timers,

notice even thought it says t2con to use this code for tmr4 and tmr6 all you have to do is change the register name from t2con/pr2 to t4con/pr4 or t6con/pr6, the values are the same

another nice feature that rod put into this is the ability to do math on the input values, there are calculator icon's at the end of the oscillator and target timer2 interrupt speed input areas.... here is where this comes in handy, suppose you what to toggle a pin at 1124.589 hz so you type this in the desired frequency area... but then you realize that you are gonna toggle the pin so you'll need 2 times this frequency, just click on the calculator at the end of the line, it will open with the value that is currently in the box, then hit ( * 2 = "accept and close" ) it will now put the result on the line so you can resimulate

another good use of this is by using the calculator thats on the oscillator line, suppose your using a oscillator speed of 19660804 and you need 1hz tmr2 interrupt speed.... the way you go about this is put 19660804 in the osc box then put 1 in the desired tmr2 freq box, then select your max prescaler!

hit "do it" , yep you get a message "refine search" no worries though, open your calculator on the oscillator line and hit

( /2 = "accept and close" ) after that hit "do it"

you would keep doing this until you get the value that you want, so check this out

Code: Select all

```
19660804
1 hz
16:1 max
no results but divide the osc by 2 and resimulate until you get 1hz
you will see that if you divide it down enought by 2 you will arrive at a direct match with this
oscillator = 153600.03125
Frequency Result: 1
Prescaler: 16
Postscaler: 16
Rollover: 150
t2con=126;
pr2=149;
ok so your thinking how is that gonna help me right?
if you take your hardware osc that you first entered in which was 19660804 / 153600.03125 you get 128, because your just divided by two each time,
so now you can use the results for 153600.03125 crystal with the 19660804 crystal if you only run the code in the tmr2 isr every 128th time, this can be done with a count variable, if count == 128, count=0, allow_ isr kind of thing
does that make sense?
what i usually do is have a look up table with t2con values, another table with pr2 values, and another table with timer divide values, then use a variable to access the tables to write the tmr2 and divide variable with
```

the values that were entered into the program will be saved, so when you open calculator it will contain previous session, also can open many of these at the same time,.... i hope you guys find this calculator as useful as i do....

here is picture in basic mode

here is picture of "more" box checked here is the flowchart as well (simulation only)

here is the algarithm that i created in form of a function to find the closest match

Code: Select all

```
/*==============================================================================
crystal enter your oscillator speed here
target enter you target tmr2 interrupt speed here
max_prescaler ENTER (3 for 16:1) || (4 for 64:1)
16f1800 and 16f1900 series chips use extended 64:1 prescaler values
this give a total of 16384 combinations of timer2
==============================================================================*/
void calculate (float crystal, float target, char max_prescaler){
float instruction_speed ;
float range_high;
float range_low;
unsigned int prescaler = 1;
unsigned int postscaler = 1;
unsigned int rollover = 1;
float result = 0;
float result_high = 0;
float prescaler_high = 0;
float postscaler_high = 0;
float rollover_high = 0;
float result_low = 0;
float prescaler_low = 0;
float postscaler_low = 0;
float rollover_low = 0;
float difference_high = 0;
float difference_low = 0;
float output_result = 0;
float output_prescaler = 0;
float output_postscaler = 0;
float output_rollover = 0;
char t2con_register = 0;
char t2con_high = 0;
char t2con_low = 0;
char pr2_register = 0;
float float_prescaler;
float float_postscaler;
float float_rollover;
char i;
send_string("please wait ");
instruction_speed = crystal / 4;
range_high = (target / 2) + target;
range_low = target - (target / 2);
prescaler=1;
send_string("*");
for(i=0;i<max_prescaler;i++){
for(postscaler=1;postscaler<17;postscaler++){
for(rollover=1;rollover<257;rollover++){
float_prescaler=prescaler;
float_postscaler=postscaler;
float_rollover=rollover;
result = instruction_speed;
result = result / float_prescaler;
result = result / float_postscaler;
result = result / float_rollover;
if(result >= target){
if(result < range_high){
range_high = result;
result_high = result;
prescaler_high = float_prescaler;
postscaler_high = float_postscaler;
rollover_high = float_rollover;
}
}
if(result <= target){
if(result > range_low){
range_low = result;
result_low = result;
prescaler_low = float_prescaler;
postscaler_low = float_postscaler;
rollover_low = float_rollover;
}
}
}
}
prescaler*=4;
send_string("*");
}
clear();
difference_high = result_high - target;
difference_low = target - result_low;
if(difference_high < difference_low){
output_result = result_high;
output_prescaler = prescaler_high;
output_postscaler = postscaler_high;
output_rollover = rollover_high;
}
else{
output_result = result_low;
output_prescaler = prescaler_low;
output_postscaler = postscaler_low;
output_rollover = rollover_low;
}
clear();
if(output_prescaler==1) t2con_low=0;
else if(output_prescaler==4) t2con_low=1;
else if(output_prescaler==16) t2con_low=2;
else if(output_prescaler==64) t2con_low=3;
t2con_high = output_postscaler - 1;
t2con_register = t2con_low;
t2con_register |= (t2con_high) << 3;
t2con_register |= 1 << 2;
clear();
if(output_result>0){
send_float(output_result);
cursor(0,1);
send_number(output_prescaler);
send_ascii(32);
send_number(output_postscaler);
send_ascii(32);
send_number(output_rollover);
cursor(0,2);
send_string("t2con=");
send_number(t2con_register);
send_string(";");
cursor(0,3);
send_string("pr2=");
send_number((output_rollover-1));
send_string(";");
}
else{
send_string("- redefine search -");
cursor(0,1);
send_string("results out of range");
}
}
```