Hi Andrew
The uTasker project has a Stepper Motor interface which allows DMA based FlexTimer operation to generate ramps and such. For optimal use of stepper motor torque exponential ramps can be programmed.
The interface is:
Prepare ramp tables (frequencies and the number of cycles each frequency is present for in the ramp):
static const unsigned short rampFrequencyValue[] = {
PWM_FREQUENCY(4800, 16),
PWM_FREQUENCY(4200, 16),
PWM_FREQUENCY(3200, 16),
PWM_FREQUENCY(1000, 16),
PWM_FREQUENCY(100, 16),
PWM_FREQUENCY(800, 16),
PWM_FREQUENCY(1800, 16),
PWM_FREQUENCY(20000, 16),
};
static const unsigned short rampCountValue[] = {
10,
18,
22,
24,
25,
27,
33,
53,
0,
};
Configure two FlexTimers - one generating a frequency and the other using this as clock input (eg. CLKIN0) to count the cycles (with no output).
PWM_INTERRUPT_SETUP pwm_setup;
pwm_setup.int_type = PWM_INTERRUPT;
pwm_setup.pwm_mode = (PWM_EXTERNAL_CLK | PWM_PRESCALER_0 | PWM_NO_OUTPUT | PWM_FULL_BUFFER_DMA | PWM_DMA_CHANNEL_ENABLE | PWM_DMA_CONTROL_PWM);
pwm_setup.int_handler = 0;
pwm_setup.pwm_reference = (_TIMER_1 | 0);
pwm_setup.pwm_frequency = 0xffff;
pwm_setup.pwm_value = rampCountValue[0];
pwm_setup.ucDmaChannel = 2;
pwm_setup.dma_int_priority = 0;
pwm_setup.usDmaTriggerSource = DMAMUX0_CHCFG_SOURCE_FTM1_C0;
pwm_setup.ptrPWM_Buffer = (unsigned short *)&rampCountValue[1];
pwm_setup.ulPWM_buffer_length = (sizeof(rampCountValue) - sizeof(unsigned short));
pwm_setup.dma_int_handler = fnEndOfRamp;
fnConfigureInterrupt((void *)&pwm_setup);
pwm_setup.pwm_mode = (PWM_SYS_CLK | PWM_PRESCALER_16 | PWM_FULL_BUFFER_DMA | PWM_DMA_CHANNEL_ENABLE | PWM_DMA_CONTROL_FREQUENCY);
pwm_setup.pwm_reference = (_TIMER_0 | 2);
pwm_setup.ucDmaChannel = 1;
pwm_setup.pwm_frequency = rampFrequencyValue[0];
pwm_setup.pwm_value = _PWM_PERCENT(50, PWM_FREQUENCY(20000, 16));
pwm_setup.ptrPWM_Buffer = (unsigned short *)&rampFrequencyValue[1];
pwm_setup.ulPWM_buffer_length = (sizeof(rampFrequencyValue) - sizeof(unsigned short));
pwm_setup.dma_int_handler = 0;
fnConfigureInterrupt((void *)&pwm_setup);
FTM1, channel 0 is used as DMA trigger each time the required cycles have been detected.
FTM0, channel 2 is used to generate an output frequency (50% MSR at the maximum frequency of 20kHz)
On each DMA trigger (after each cycle count match) the next frequency is set and the next cycle count value incremented.
At the end of the ramp the interrupt call back fnEndoOfRamp() is called, which can prepare the next job or stop the operation. Eg.
static void __callback_interrupt fnEndOfRamp(void)
{
FTM0_SC = 0;
}
The stepper motor pulse is a fixed width one (not 50% duty cycle throughout) and the maximum ramp cycle count is 64k due to the 16 bit timer.
Regards
Mark
Complete Kinetis solutions for professional needs, training and support:http://www.utasker.com/kinetis.html
Kinetis K22:
- http://www.utasker.com/kinetis/FRDM-K22F.html
- http://www.utasker.com/kinetis/TWR-K22F120M.html
- http://www.utasker.com/kinetis/BLAZE_K22.html
- http://www.utasker.com/kinetis/tinyK22.html
uTasker: supporting >1'000 registered Kinetis users get products faster and cheaper to market
Request Free emergency remote desk-top consulting at http://www.utasker.com/services.html
https://github.com/uTasker/uTasker-Kinetis