Hello Skaptor,
There are two different methods of achieving a linear frequency control. The method that Rocco has used might be described as a "table lookup" method. The method that I previously referenced is a direct digital synthesis (DDS) method, with square wave output. Either method would require the use of two timers, one for generating the output frequency, and a second one for the slow ramp output control.
My personal preference is the DDS method, for which the timer interrupt period remains constant. This represents the DDS clock. The method would utilize a 16-bit accumulating register, with a value N added to the accumulator during each interrupt. Each overflow of the accumulator represents one cycle of the output frequency. Therefore, the higher the value of N, the more quickly will the accumulator overflow, and the higher will be the output frequency. The output frequency will be given by the formula:
Fout = Fclk * N / 65536
The incremental frequency step will be:
delta_F = Fclk / 65526
Let's assume delta_F = 0.1 Hz. The will result in Fclk = 6553.6 Hz (or Tclk = 152.6 us). Assume that the TPM1 module is used, with software output compare on channel 0, for this purpose. Your current interpretation of TPM operation seems to be incorrect.
For the frequency ramp control, I have assumed that TPM2 module is used, again with software output compare on channel 0. In this case, an interrupt would occur each 10ms, where the current N value would be incremented, decremented, or remain unchanged, depending on the current speed setting for the stepper. This will result in a frequency ramp of 0.1 Hz per 10ms, or 10 Hz per second.
The following snippet shows the ISR code for each interrupt. I have not shown the initialisation required for each TPM module, nor the code required to set the speed value.
.
// For following output compare intervals, 8 MHz bus frequency is assumed
#define INCR_VAL 1220 // TPM1C0 Output compare period 152.6us with prescale 1
#define RAMPTIME 19999 // TPM2C0 Output compare period 10ms with prescale 4
#define STEP_CLK PTAD_PTAD0 // GPIO pin
word ramp, speed; // Global variables
interrupt void ISR_TPM1C0( void) // 152.6us intervals
{
static word accum = 0;
TPM1C0SC_CHOF = 0; // Clear flag
TPM1C0V += INCR_VAL; // Set next compare value
accum += ramp; // Update accumulation count
if (accum & 0x8000) // Test MSB
STEP_CLK = 1;
else
STEP_CLK = 0;
}
interrupt void ISR_TPM2C0( void) // 10ms intervals
{
TPM2C0SC_CHOF = 0; // Clear flag
TPM2C0V += RAMPTIME; // Set next compare value
if (ramp < speed) ramp++;
if (ramp > speed) ramp--;
}
.
In practice, the maximum value within the global variable speed would be limited to about 2000, giving an upper frequency limit of 200 Hz. This will minimize short term frequency jitter.
Regards,
Mac