#define AXIS_PULSE_0 GPIO_Pin_8
#define AXIS_PULSE_1 GPIO_Pin_2
#define AXIS_PULSE_2 GPIO_Pin_7
#define AXIS_PULSE_3 GPIO_Pin_3
u16 AxisPulsePin[4] = {AXIS_PULSE_0, AXIS_PULSE_1, AXIS_PULSE_2, AXIS_PULSE_3};// pa8, pa2, pa7, pa3
u16 AxisDirPin[4] = {GPIO_Pin_0, GPIO_Pin_2, GPIO_Pin_3, GPIO_Pin_13}; // pc0, pc2, pc3, pc13
double tim_count_num = 1000000;
#define step_psc 71
#define STOP 0 //停止
#define ACCEL 1 //加速
#define DECEL 2 //减速
#define RUN 3 //最大速度运行
#define PAUSE 4 //减速停止
AxisData axisData[4]; //工作状态
void get_ad_step(long steps, double start_speed, double max_speed, double a_speed, double d_speed, int *a_step, int *d_step){
int a, d;
double count = 0;
double v = start_speed;
a = 1;
d = 1;
while(v < max_speed){
v += a_speed/v;
a ++;
}
v = start_speed;
while(v < max_speed){
v += d_speed/v;
d++;
}
if(a + d <= steps){
*a_step = a;
*d_step = d;
}else{
*a_step = steps * a /(a + d);
*d_step = steps - *a_step;
}
}
void init_axis_data(int ax, long steps, double start_speed, double max_speed, double a_speed, double d_speed)
{
int a_step, d_step;
get_ad_step(steps, start_speed, max_speed, a_speed, d_speed, &a_step, &d_step);
if(steps >= 0)
{
axisData[ax].dir = 1;
axisData[ax].step_count = steps;
}else{
axisData[ax].dir = -1;
axisData[ax].step_count = -steps;
}
axisData[ax].start_speed = start_speed;
axisData[ax].cur_speed = start_speed;
axisData[ax].max_speed = max_speed;
axisData[ax].a_speed = a_speed;
axisData[ax].d_speed = d_speed;
axisData[ax].a_step = a_step;
axisData[ax].d_step = d_step;
axisData[ax].step_delay = tim_count_num/start_speed;
axisData[ax].max_delay = tim_count_num/start_speed;
axisData[ax].min_delay = tim_count_num/max_speed;
axisData[ax].step_run = 0;
axisData[ax].run_state = ACCEL;
}
int stepper_t_move(int ax, long steps, double start_speed, double max_speed, double a_speed, double d_speed)
{
// if(ax < 0 || ax > 4 )
// {
// return -1;
// }
init_axis_data(ax, steps, start_speed, max_speed, a_speed, d_speed);
if(steps >= 0){
GPIO_SetBits(GPIOC, AxisDirPin[ax]);
}else{
GPIO_ResetBits(GPIOC, AxisDirPin[ax]);
}
if(ax == 0){
}else if(ax == 1){
TIM2->CCR3 = axisData[1].step_delay/2;//占空比50%
TIM2->ARR = axisData[1].step_delay;
TIM_Cmd(TIM2, ENABLE);
}else if(ax == 2){
}else if(ax == 3){
}
}
//获取ax轴运行状态 0表示已停止
int stepper_get_state(int ax)
{
return axisData[ax].run_state;
}
//获取剩余步数 ax 轴号
long stepper_get_rem_steps(int ax)
{
return axisData[ax].step_count - axisData[ax].step_run;
}
//减速停止
void stepper_set_pause(int ax)
{
axisData[ax].run_state = PAUSE;
}
void init_stepper()
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
NVIC_Configuration(); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM5 | RCC_APB2Periph_AFIO , ENABLE); //使能GPIO外设和AFIO复用功能模块时钟
//初始化脉冲输出口
GPIO_InitStructure.GPIO_Pin = AxisPulsePin[0] | AxisPulsePin[1] | AxisPulsePin[2] | AxisPulsePin[3];
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIO
//初始化方向输出口
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin = AxisDirPin[0] | AxisDirPin[1] | AxisDirPin[2] | AxisDirPin[3]; //TIM1_CH1
GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIO
}
void TIM2_init()
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
//初始化TIM2
TIM_TimeBaseStructure.TIM_Period = axisData[1].step_delay; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
TIM_TimeBaseStructure.TIM_Prescaler =step_psc; //设置用来作为TIMx时钟频率除数的预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
// TIM_TimeBaseStructure.TIM_RepetitionCounter = 0x0;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
/*初始化TIM2 Channel3 PWM模式*/
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1 计数值 < CCRX时 为高电平,否则为低电平
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC3Init(TIM2, &TIM_OCInitStructure);
TIM_ClearFlag(TIM2,TIM_FLAG_Update);
// TIM_ARRPreloadConfig(TIM3,DISABLE) ;
TIM_OC3PreloadConfig(TIM2, TIM_OCPreload_Enable); //使能TIM2在CCR3上的预装载寄存器
TIM_ITConfig( //使能或者失能指定的TIM中断
TIM2, //TIM3
TIM_IT_Update ,
ENABLE //使能
);
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM2中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
}
void TIM2_IRQHandler(void) //TIM2中断
{
u8 ReadValue;
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update ); //清除TIMx的中断待处理位:TIM 中断源
}
axisData[1].step_run ++;
if(axisData[1].run_state == RUN){
if( axisData[1].step_run > axisData[1].step_count){
axisData[1].run_state = STOP;
TIM_Cmd(TIM2, DISABLE);
return;
}
if(axisData[1].step_count - axisData[1].step_run <= axisData[1].d_step){
axisData[1].cur_speed -= axisData[1].d_speed/axisData[1].cur_speed;
axisData[1].step_delay = tim_count_num/axisData[1].cur_speed + 0.5;
axisData[1].run_state = DECEL;
}
}else if(axisData[1].run_state == ACCEL){
TIM2->CCR3 = axisData[1].step_delay/2;//占空比50%
TIM2->ARR = axisData[1].step_delay;
if(axisData[1].step_delay > axisData[1].min_delay){
axisData[1].cur_speed += axisData[1].a_speed/axisData[1].cur_speed;
axisData[1].step_delay = tim_count_num/axisData[1].cur_speed + 0.5;
if(axisData[1].step_delay < axisData[1].min_delay){
axisData[1].step_delay = axisData[1].min_delay;
}
}
if(axisData[1].step_run >= axisData[1].a_step){
axisData[1].run_state = RUN;
}
}else if(axisData[1].run_state == DECEL){
if( axisData[1].step_run > axisData[1].step_count){
axisData[1].run_state = STOP;
TIM_Cmd(TIM2, DISABLE);
return;
}
TIM2->CCR3 = axisData[1].step_delay/2;//占空比50%
TIM2->ARR = axisData[1].step_delay;
if(axisData[1].step_delay < axisData[1].max_delay){
axisData[1].cur_speed -= axisData[1].d_speed/axisData[1].cur_speed;
axisData[1].step_delay = tim_count_num/axisData[1].cur_speed + 0.5;
if(axisData[1].step_delay > axisData[1].max_delay){
axisData[1].step_delay = axisData[1].max_delay;
}
}
}else if (axisData[1].run_state == PAUSE){
TIM2->CCR3 = axisData[1].step_delay/2;//占空比50%
TIM2->ARR = axisData[1].step_delay;
if(axisData[1].step_delay < axisData[1].max_delay){
axisData[1].cur_speed -= axisData[1].d_speed/axisData[1].cur_speed;
axisData[1].step_delay = tim_count_num/axisData[1].cur_speed + 0.5;
if(axisData[1].step_delay > axisData[1].max_delay){
axisData[1].step_delay = axisData[1].max_delay;
}
}else{
axisData[1].run_state = STOP;
TIM_Cmd(TIM2, DISABLE);
return;
}
}else{
axisData[1].run_state = STOP;
TIM_Cmd(TIM2, DISABLE);
return;
}
}
int main(void)
{
init_stepper();
TIM2_init();
stepper_t_move(1, 1000, 200, 4000, 2000, 2000);
while(1)
{
}
}
以上只是示列代码,正在将代码封装成可以直接调用的库