C语言电机控制,曲线加速 ,直线加速
1.函数说明
void vStepMotor_Init(void);
初始化步进电机参数:使能脚,方向,脉冲,原点检测信号,终点检测信号 运动最小速度 最大速度 加速步长等等。
void vStepMotor_Calc_S_Wave(unit16_t speedLow, unit16_t speedHigh , StepMotor_Typedef * Motor , unit16_t size );
根据设定计算 电机运动的参数,也就是计算得到定时器翻转脉冲的间隔。
void vStepMotor_Run(StepMotor_Typedef * Motor , Motor_State Dir, uint16_t steps);
电机执行的方向和步数。
void vStepMotor_Run_Motion(StepMotor_Typedef motor);
该函数在对应的定时器中断中执行,根据计算的定时器反转脉冲时间翻转脉冲。
程序框架
void main(void)
{
vStepMotor_Init();
vStepMotor_Calc_S_Wave(400,600,60);
while(1)
{
vStepMotor_Run(motor, Dir, steps);
}
}
void TIM2_IRQHandler(void)
(
if(TIM_Get ITStatus(TIM, TIM_IT_Update)==SET)
{
TIM_ClearFlag(TIM,TIM_FLAG_Updata);
vStepMotor_Run_Motion(&Motor);
}
)
手机更新中
void StepMotor_Init(void)
{
vStepMotorGPIOInit();
//-------------------------------------------------------------------------------------
WasteWat_Mtr.Ctrl_Status=STOP;
WasteWat_Mtr.PIN_EN =&PDout(12);
WasteWat_Mtr.PIN_DIR=&PDout(13);
WasteWat_Mtr.PIN_CLK=&PDout(14);
//Pump_WasteLiquid_Mtr.PIN_ORI=&PBin(15);
WasteWat_Mtr.TIM_ARR=&MEM_ADDR(&TIM4->ARR);//tim5
WasteWat_Mtr.Para_S_Type=FULL_S_WAVE;
WasteWat_Mtr.Run_S_Len=wParaGet(WasteWater_Num, mStepsS);//
WasteWat_Mtr.S_Wave=&S_Wave_WasteWa_Mtr[0];
WasteWat_Mtr.Para_OriginDir=CCW; //100ul
WasteWat_Mtr.Para_OriginSteps=60; //无原点
WasteWat_Mtr.Run_Timer_Freq=2000000;
WasteWat_Mtr.Para_ClkPerStep=8;
WasteWat_Mtr.Run_Low_Speed =300;
WasteWat_Mtr.Run_High_Speed=500;
WasteWat_Mtr.CW_CCW_AntiLogic=TRUE;
WasteWat_Mtr.Dir_Enable=TRUE; //方向不使能
WasteWat_Mtr.Origin_Status=TRUE; //
StepMotor_Calc_S_Wave(wParaGet(WasteWater_Num,mSpeedMin), wParaGet(WasteWater_Num,mSpeedMax), &WasteWat_Mtr,WasteWat_S_Wave_Size); //废液电机} void StepMotor_Calc_S_Wave(uint16_t low,uint16_t high,StepMotor_TypeDef* Motor,uint16_t size)
{
u16 S_len_arr,step;
float a1,b1,c1,a2,b2,c2;
Motor->Run_Low_Speed=low; Motor->Run_High_Speed=high; S_len_arr = Motor->Run_S_Len/2;// Motor->S_Wave[t]=(Motor->Run_Timer_Freq/2)/(Vt*Motor->Para_ClkPerStep); //数组中存储的是计算好的定时器ARR值 //计算前一段抛物线参数 y = a*x*x + b*x + c a1 = (float)(high-low)/(3*S_len_arr*S_len_arr); b1 = (float)(high-low)/(6*S_len_arr); c1 = (float)low; //计算后一段抛物线参数 y = a*x*x + b*x + c a2 = (float)(3*(low-high))/(8*S_len_arr*S_len_arr); b2 = (float)(13*(high-low))/(8*S_len_arr); c2 = (float)((7*low)/4 - (3*high)/4); for(step = 0;step < 2*S_len_arr;step++) //对所有步数的S_wave进行计算 { if(/*step >= 0 &&*/ step < S_len_arr){ Motor->S_Wave[step] = a1*step*step + b1*step + c1; }else if(step >= S_len_arr && step <= S_len_arr*2){ Motor->S_Wave[step] = a2*step*step + b2*step + c2; } } if(Motor->Run_S_Len%2){ //对奇数的最后一步进行单独处理 Motor->S_Wave[Motor->Run_S_Len-1] = high; } }
//void StepMotor_Calc_S_Wave(uint16_t low,uint16_t high,StepMotor_TypeDef* Motor,uint16_t size)
//{
// //Fcur = Fmin + (Fmax-Fmin)/(1+e^(-flexible*(i-num)/num));
// //flexible = 4~6; num = length/2; length = 加减速步长
// const int l_dwFlexible = -6;
// //const float e = 2.72; //e 约等于2.72
// int l_wNum = 0;
// uint32_t l_dwFValue = 0;
// uint16_t l_wLenth = 0;
// uint16_t l_wLow = 0, l_wHigh = 0;
// uint16_t i = 0;
// float l_Tmp = 0.0;
// //Motor = &g_StepMtrCtrlInfo[byStepMNbr];
// if (Motor->Run_S_Len >= 200 )
// {
// Motor->Run_S_Len = 200;
// }
// l_wLenth = Motor->Run_S_Len;
// l_wNum = l_wLenth/2;
// l_wLow = low;
// l_wHigh = high;
// for (i = 1; i <= l_wLenth; i++)
// {
// l_Tmp = 1 + expf(l_dwFlexible*(i-l_wNum)/l_wNum);
// l_dwFValue = 0.5 + l_wLow + (float)(l_wHigh - l_wLow)/l_Tmp;
// //Motor->S_Wave[i-1] = Motor->Run_Timer_Freq/2/(l_dwFValue*Motor->Para_ClkPerStep);
// Motor->S_Wave[i-1] = l_dwFValue;
// }
// for (i = l_wLenth; i < 200; i++) //将曲线数组填充满
// {
// //Motor->S_Wave = Motor->Run_Timer_Freq/2/(l_wHigh*Motor->Para_ClkPerStep);
// //Motor->S_Wave = Motor->S_Wave[i-1];
// }
//}
//void StepMotor_Calc_S_Wave(uint16_t low,uint16_t high,StepMotor_TypeDef* Motor,uint16_t size)
//{
// //y=kx+b
// uint16_t i = 0;
// float k = 0;
//
// if(size > 200)
// {
// size =200;
// }
//
// k = (float)(high-low) / size;
//
// for(i=0; i< size; i++)
// {
// Motor->S_Wave = ((float)i*k) +low+0.5;
// }
//}
C语言电机控制,曲线加速 ,直线加速
1.函数说明
void vStepMotor_Init(void);
初始化步进电机参数:使能脚,方向,脉冲,原点检测信号,终点检测信号 运动最小速度 最大速度 加速步长等等。
void vStepMotor_Calc_S_Wave(unit16_t speedLow, unit16_t speedHigh , StepMotor_Typedef * Motor , unit16_t size );
根据设定计算 电机运动的参数,也就是计算得到定时器翻转脉冲的间隔。
void vStepMotor_Run(StepMotor_Typedef * Motor , Motor_State Dir, uint16_t steps);
电机执行的方向和步数。
void vStepMotor_Run_Motion(StepMotor_Typedef motor);
该函数在对应的定时器中断中执行,根据计算的定时器反转脉冲时间翻转脉冲。
程序框架
void main(void)
{
vStepMotor_Init();
vStepMotor_Calc_S_Wave(400,600,60);
while(1)
{
vStepMotor_Run(motor, Dir, steps);
}
}
void TIM2_IRQHandler(void)
(
if(TIM_Get ITStatus(TIM, TIM_IT_Update)==SET)
{
TIM_ClearFlag(TIM,TIM_FLAG_Updata);
vStepMotor_Run_Motion(&Motor);
}
)
手机更新中
void StepMotor_Init(void)
{
vStepMotorGPIOInit();
//-------------------------------------------------------------------------------------
WasteWat_Mtr.Ctrl_Status=STOP;
WasteWat_Mtr.PIN_EN =&PDout(12);
WasteWat_Mtr.PIN_DIR=&PDout(13);
WasteWat_Mtr.PIN_CLK=&PDout(14);
//Pump_WasteLiquid_Mtr.PIN_ORI=&PBin(15);
WasteWat_Mtr.TIM_ARR=&MEM_ADDR(&TIM4->ARR);//tim5
WasteWat_Mtr.Para_S_Type=FULL_S_WAVE;
WasteWat_Mtr.Run_S_Len=wParaGet(WasteWater_Num, mStepsS);//
WasteWat_Mtr.S_Wave=&S_Wave_WasteWa_Mtr[0];
WasteWat_Mtr.Para_OriginDir=CCW; //100ul
WasteWat_Mtr.Para_OriginSteps=60; //无原点
WasteWat_Mtr.Run_Timer_Freq=2000000;
WasteWat_Mtr.Para_ClkPerStep=8;
WasteWat_Mtr.Run_Low_Speed =300;
WasteWat_Mtr.Run_High_Speed=500;
WasteWat_Mtr.CW_CCW_AntiLogic=TRUE;
WasteWat_Mtr.Dir_Enable=TRUE; //方向不使能
WasteWat_Mtr.Origin_Status=TRUE; //
StepMotor_Calc_S_Wave(wParaGet(WasteWater_Num,mSpeedMin), wParaGet(WasteWater_Num,mSpeedMax), &WasteWat_Mtr,WasteWat_S_Wave_Size); //废液电机} void StepMotor_Calc_S_Wave(uint16_t low,uint16_t high,StepMotor_TypeDef* Motor,uint16_t size)
{
u16 S_len_arr,step;
float a1,b1,c1,a2,b2,c2;
Motor->Run_Low_Speed=low; Motor->Run_High_Speed=high; S_len_arr = Motor->Run_S_Len/2;// Motor->S_Wave[t]=(Motor->Run_Timer_Freq/2)/(Vt*Motor->Para_ClkPerStep); //数组中存储的是计算好的定时器ARR值 //计算前一段抛物线参数 y = a*x*x + b*x + c a1 = (float)(high-low)/(3*S_len_arr*S_len_arr); b1 = (float)(high-low)/(6*S_len_arr); c1 = (float)low; //计算后一段抛物线参数 y = a*x*x + b*x + c a2 = (float)(3*(low-high))/(8*S_len_arr*S_len_arr); b2 = (float)(13*(high-low))/(8*S_len_arr); c2 = (float)((7*low)/4 - (3*high)/4); for(step = 0;step < 2*S_len_arr;step++) //对所有步数的S_wave进行计算 { if(/*step >= 0 &&*/ step < S_len_arr){ Motor->S_Wave[step] = a1*step*step + b1*step + c1; }else if(step >= S_len_arr && step <= S_len_arr*2){ Motor->S_Wave[step] = a2*step*step + b2*step + c2; } } if(Motor->Run_S_Len%2){ //对奇数的最后一步进行单独处理 Motor->S_Wave[Motor->Run_S_Len-1] = high; } }
//void StepMotor_Calc_S_Wave(uint16_t low,uint16_t high,StepMotor_TypeDef* Motor,uint16_t size)
//{
// //Fcur = Fmin + (Fmax-Fmin)/(1+e^(-flexible*(i-num)/num));
// //flexible = 4~6; num = length/2; length = 加减速步长
// const int l_dwFlexible = -6;
// //const float e = 2.72; //e 约等于2.72
// int l_wNum = 0;
// uint32_t l_dwFValue = 0;
// uint16_t l_wLenth = 0;
// uint16_t l_wLow = 0, l_wHigh = 0;
// uint16_t i = 0;
// float l_Tmp = 0.0;
// //Motor = &g_StepMtrCtrlInfo[byStepMNbr];
// if (Motor->Run_S_Len >= 200 )
// {
// Motor->Run_S_Len = 200;
// }
// l_wLenth = Motor->Run_S_Len;
// l_wNum = l_wLenth/2;
// l_wLow = low;
// l_wHigh = high;
// for (i = 1; i <= l_wLenth; i++)
// {
// l_Tmp = 1 + expf(l_dwFlexible*(i-l_wNum)/l_wNum);
// l_dwFValue = 0.5 + l_wLow + (float)(l_wHigh - l_wLow)/l_Tmp;
// //Motor->S_Wave[i-1] = Motor->Run_Timer_Freq/2/(l_dwFValue*Motor->Para_ClkPerStep);
// Motor->S_Wave[i-1] = l_dwFValue;
// }
// for (i = l_wLenth; i < 200; i++) //将曲线数组填充满
// {
// //Motor->S_Wave = Motor->Run_Timer_Freq/2/(l_wHigh*Motor->Para_ClkPerStep);
// //Motor->S_Wave = Motor->S_Wave[i-1];
// }
//}
//void StepMotor_Calc_S_Wave(uint16_t low,uint16_t high,StepMotor_TypeDef* Motor,uint16_t size)
//{
// //y=kx+b
// uint16_t i = 0;
// float k = 0;
//
// if(size > 200)
// {
// size =200;
// }
//
// k = (float)(high-low) / size;
//
// for(i=0; i< size; i++)
// {
// Motor->S_Wave = ((float)i*k) +low+0.5;
// }
//}
举报