Hi,
Experimenting on a stepper motor control (DRV8834). I want to be able to send a single square wave output, with a specified number of pulses. I managed to put together something that works ok using two timers and PPI after reading posts on DevZone. Now I need to find a way to modify this to achieve acceleration / decceleration. I would prefer in the same style using PPI if possible. Any suggestions?
typedef enum { MICROSTEP_1 = 1, MICROSTEP_2 = 2, MICROSTEP_4 = 4, MICROSTEP_8 = 8, MICROSTEP_16 = 16, MICROSTEP_32 = 32 }step_mode_t; void move_linear(uint32_t travel_distance_um, uint32_t mm_per_sec, step_mode_t step_mode) { const uint8_t step_len_um = 13; float nbr_pulses = (float)(travel_distance_um*step_mode)/step_len_um; uint32_t nbr_toggles = (uint32_t)(nbr_pulses*2); float pt_pulses_us = ((float)travel_distance_um*1000/mm_per_sec)/nbr_toggles; uint32_t timer_ticks_reload = (uint32_t)(pt_pulses_us / 0.0625) + 3; // Stop timers before change NRF_TIMER1->TASKS_STOP = 1; NRF_TIMER2->TASKS_STOP = 1; //Setup pulse out pin NRF_GPIOTE->CONFIG[0] = GPIOTE_CONFIG_MODE_Task << GPIOTE_CONFIG_MODE_Pos | GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos | LED_1 << GPIOTE_CONFIG_PSEL_Pos | GPIOTE_CONFIG_OUTINIT_Low << GPIOTE_CONFIG_OUTINIT_Pos; //Setup pulse counter NRF_TIMER2->MODE = 1; //Counter mode NRF_TIMER2->BITMODE = 3; //32 bit NRF_TIMER2->TASKS_CLEAR = 1; //Clear counter value NRF_TIMER2->CC[1] = nbr_toggles; //Stop after <nbr> of pulses NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE1_CLEAR_Enabled << TIMER_SHORTS_COMPARE1_CLEAR_Pos; //Setup pulse out timer NRF_TIMER1->MODE = 0; //Timer mode NRF_TIMER1->BITMODE = 3; //32 bit NRF_TIMER1->PRESCALER = 0; //16Mhz NRF_TIMER1->CC[1] = timer_ticks_reload; NRF_TIMER1->SHORTS = TIMER_SHORTS_COMPARE1_CLEAR_Enabled << TIMER_SHORTS_COMPARE1_CLEAR_Pos; //PPI connections NRF_PPI->CH[0].EEP = (uint32_t) &NRF_TIMER1->EVENTS_COMPARE[1]; // input = compare event of timer1 NRF_PPI->CH[0].TEP = (uint32_t) &NRF_GPIOTE->TASKS_OUT[0]; // output = polarity toggle of the selected gpio NRF_PPI->FORK[0].TEP = (uint32_t) &NRF_TIMER2->TASKS_COUNT; NRF_PPI->CH[1].EEP = (uint32_t) &NRF_TIMER2->EVENTS_COMPARE[1]; // input = compare event of timer2 NRF_PPI->CH[1].TEP = (uint32_t) &NRF_TIMER2->TASKS_CAPTURE[1]; NRF_PPI->FORK[1].TEP = (uint32_t) &NRF_TIMER1->TASKS_STOP; //Stop pulse timer afer X pulses counted NRF_PPI->CHENSET = (PPI_CHENSET_CH0_Enabled << PPI_CHENSET_CH0_Pos); NRF_PPI->CHENSET = (PPI_CHENSET_CH1_Enabled << PPI_CHENSET_CH1_Pos); //*(uint32_t*)0x40009C0C = 1; // pan73_workaround NRF_TIMER2->TASKS_START = 1; // Start counter NRF_TIMER1->TASKS_START = 1; // Start timer } int main(void) { move_linear(13, 10, MICROSTEP_16); while(1); }
BR
//Ola