mirror of
https://github.com/eddyem/IR-controller.git
synced 2025-12-06 02:35:14 +03:00
110 lines
3.6 KiB
C
110 lines
3.6 KiB
C
/*
|
|
* stepper_motors.c - moving of stepper motors
|
|
*
|
|
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
|
* MA 02110-1301, USA.
|
|
*/
|
|
#include "includes.h"
|
|
|
|
uint8_t Motor_number = 0;// number of active motor
|
|
static uint8_t timers_activated = 0; // flag of activated timers
|
|
// one pulse period *1e-5s (one step == 16 pulses)
|
|
uint16_t Motor_period = 25; // near 250 steps per second
|
|
// amount of steps
|
|
volatile uint32_t Motor_steps = 0;
|
|
|
|
static void activate_timers(){
|
|
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
|
|
TIM_OCInitTypeDef TIM_OCInitStructure;
|
|
/*
|
|
* Time base configuration
|
|
*/
|
|
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
|
|
TIM_TimeBaseStructure.TIM_Period = Motor_period;
|
|
// timer prescaler: 10mks period
|
|
TIM_TimeBaseStructure.TIM_Prescaler = (uint16_t) (SystemCoreClock / 100000) - 1;
|
|
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; // no division
|
|
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
|
|
TIM_TimeBaseInit(SM_Timer, &TIM_TimeBaseStructure);
|
|
/*
|
|
* compare/toggle configuration
|
|
* Channel 1 will toggle its state every timer pulse
|
|
*/
|
|
TIM_OCStructInit(&TIM_OCInitStructure);
|
|
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
|
|
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
|
|
TIM_OCInitStructure.TIM_Pulse = Motor_period / 2; // instead of 50% we can do constant length impulses
|
|
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
|
|
TIM_OC1Init(SM_Timer, &TIM_OCInitStructure);
|
|
TIM_OC1PreloadConfig(SM_Timer, TIM_OCPreload_Enable);
|
|
// enable IRQs & run timer
|
|
if(User_value < 0){
|
|
User_value = -User_value;
|
|
SM_DIR_GPIOx->BSRR = SM_DIR_PIN; // set DIR bit to rotate ccw
|
|
}else
|
|
SM_DIR_GPIOx->BRR = SM_DIR_PIN; // reset DIR bit
|
|
Motor_steps = ((uint32_t)User_value) << 4; // multiply by 16 to get steps count
|
|
//printInt((uint8_t*)&Motor_steps, 4);
|
|
//newline();
|
|
TIM_Cmd(SM_Timer, ENABLE);
|
|
TIM_CtrlPWMOutputs(SM_Timer, ENABLE);
|
|
// configure interrupts: only from CC1 (that's mean that all is over)
|
|
TIM_ITConfig(SM_Timer, SM_IT_CC, ENABLE);
|
|
timers_activated = 1;
|
|
}
|
|
|
|
/**
|
|
* Move motor Motor_number to User_value steps
|
|
*/
|
|
void move_motor(){
|
|
if(User_value == 0) return;
|
|
// check whether motor is moving
|
|
if(timers_activated){
|
|
MSG("err: moving", "err");
|
|
newline();
|
|
return;
|
|
}
|
|
// activate motor # Motor_number
|
|
SM_EN_GPIOx->BSRR = (SM_EN0_PIN << (Motor_number)); // set proper bit
|
|
// set steps counter to User_value & run timer
|
|
activate_timers();
|
|
}
|
|
|
|
|
|
/**
|
|
* Stop timer1 when all steps are over; turn off motor voltage
|
|
*/
|
|
void stop_timer1(){
|
|
// disable IRQs & stop timer
|
|
TIM_Cmd(SM_Timer, DISABLE);
|
|
TIM_ITConfig(SM_Timer, TIM_IT_Update, DISABLE);
|
|
// turn off power
|
|
SM_EN_GPIOx->BRR = SM_EN_PINS; // reset all EN bits
|
|
SM_PUL_GPIOx->BRR = SM_PUL_PIN; // reset signal on PUL
|
|
timers_activated = 0;
|
|
Motor_steps = 0;
|
|
}
|
|
|
|
/**
|
|
* Sets motor period to user value & refresh timer
|
|
*/
|
|
void set_motor_period(){
|
|
Motor_period = (uint16_t)User_value;
|
|
SM_Timer->ARR = Motor_period;
|
|
SM_Timer->SM_CCR = Motor_period / 2;
|
|
}
|