#include "motor.h" #include "app.h" #define STEP_LIN 16 //直行程步长单位数值(脉冲数) #define STEP_ROT 20 //角行程步长单位数值(脉冲数) #define DATA_LEN 10 //角行程步长单位数值(脉冲数) #define MOTOR_STOP 0 //电机停止 #define MOTOR_POS 1 //电机正向运动 #define MOTOR_REV 2 //电机反向运动 #define MOTOR_RETURN 3 //电机返回 int magnet_middle = 1135; //磁条中点 int magnet_start = 800; //磁条范围-起点mv int magnet_end = 1200; //磁条范围-终点mv #define motor_start 200 //电机运动范围起点mv #define motor_end 1800 //电机运动范围终点mv int Travle_Flag = 0; //0 直 1 角 char Motor_Run = 2; //0 停止 1 运行 2 运行到起始点 3 运行到结束点 char Run_Mode = 0; //0 点动 1 方案一 2 方案二 unsigned int Run_Step = 0; //电机运行步长 unsigned int Run_Inter = 0; //电机运行间隔时长 unsigned int Run_Stop = 0; //到“结束点”后,停止时间 unsigned int Run_mm = 1; //行进长度(mm)/转动角度(°) unsigned int Run_num = 0; //角行程电机转动圈数 unsigned int ct_num = 0; //磁条长度 int mov_flag = 0; //脉冲标志 int send_flag = 0; //发送标志 int seat_flag = 0; //位置标志 int motor_dire = 1; //电机转动方向 int flag = 0; int motor_direc = 1;//电机转动方向 char motor_control = 0; //步骤 unsigned char Runmotor_step = 0; //次数 unsigned int Runmotor_Nums = 0; //清除电机标记 void ClrRunmotorStep(void) { //步骤 Runmotor_step = 0; //次数 Runmotor_Nums = 0; //脉冲标记清0 mov_flag = 0; //发送标记清0 send_flag = 0; //位置标记清0 seat_flag = 0; } //处理马达运行 #define SPEED_NORMAL 0x00007530 #define SPEED_MAX 0x0000EA60 int first_flag = 1; void Deal_Motor(void) { TMC5160_SPIReadInt(XACTUAL_ADDR,XA); //读取实际位置XACTUAL XA_32 = Raw_32(XA); TMC5160_SPIReadInt(VACTUAL_ADDR,VA); //读取实际速度VACTUAL VA_32 = Raw_32(VA); //判断直行程还是角行程 if(Travle_Flag == 0)//直行程——电机旋转一圈,磁条水平位移5mm { motor_data[0] = 0x00;//00 直行程 01 角行程 //判断电机停止还是运行,运行到起始位还是结束位 if( Motor_Run == 0)//停止 { tmc5160_operate(MOTOR_STOP,0); if( speed_max != SPEED_NORMAL) { speed_max = SPEED_NORMAL; //VMAX TMC5160_SPIWriteInt(VMAX_ADDR, speed_max,1); speed_1 = speed_max / 2; //V1 TMC5160_SPIWriteInt(V1_ADDR, speed_1,1); } } else if(Motor_Run == 1)//运行 { if(Motor_Run >= 1 && Runmotor_step == 0) { Runmotor_step = 1; } //判断电机运行方式是点动还是连续,点动为方案三,方案一和方案二为连续 if(Run_Mode == 0)//点动(方案三) { mov_step();//点动 } else if(Run_Mode == 1)//连续(方案一)“步长过大可能会越过限位开关” { mov_loop1();//方案一 } // else if(Run_Mode == 2)//连续(方案二)“步长过大可能会越过限位开关” // { // //磁条循环“起始点-结束点-起始点”,一定次数后停在起始点 // mov_loop2();//方案二 // } else//初始化 { tmc5160_operate(MOTOR_STOP,0); } } else if(Motor_Run == 2)//运行到起始位 { if( ocin1 == 0 )//判断是否到达始限位 { motor_direc = MOTOR_POS; Runmotor_step = 0; Motor_Run = 0; return; } // if( ocin2 == 0 )//判断是否到达终限位 // { // motor_direc = MOTOR_REV; // Runmotor_step = 0; // Motor_Run = 0; // return; // } if( (X_ads1220 <= (motor_start + 50) ) && (X_ads1220 != 0) ) { motor_direc = MOTOR_POS; Runmotor_step = 0; Motor_Run = 0; //记录第一次复位时电机位置 if(first_flag) { TMC5160_SPIReadInt(XACTUAL_ADDR,XA); //读取实际位置XACTUAL XA_32 = Raw_32(XA); first_xa_32 = XA_32; first_flag = 0; } return; } if((ocin2 == 1) && (ocin2 == 1)) { if( speed_max != SPEED_MAX) { speed_max = SPEED_MAX; TMC5160_SPIWriteInt(VMAX_ADDR, speed_max,1); // VMAX speed_1 = speed_max / 2; //V1 TMC5160_SPIWriteInt(V1_ADDR, speed_1,1); } tmc5160_operate(MOTOR_REV,51200*30); } } else if(Motor_Run == 3)//运行到结束位 { // if( ocin1 == 0 )//判断是否到达始限位 // { // motor_direc = MOTOR_POS; // Runmotor_step = 0; // Motor_Run = 0; // return; // } if( ocin2 == 0 )//判断是否到达终限位 { motor_direc = MOTOR_REV; Runmotor_step = 0; Motor_Run = 0; return; } if(X_ads1220 >= (motor_end - 50)) { motor_direc = MOTOR_REV; Runmotor_step = 0; Motor_Run = 0; return; } if((ocin2 == 1) && (ocin2 == 1)) { // uint32_t speed_max = 0x00009C40; //VMAX 目标速度 if( speed_max != SPEED_MAX) { speed_max = SPEED_MAX; TMC5160_SPIWriteInt(VMAX_ADDR, speed_max,1); // VMAX speed_1 = speed_max / 2; //V1 TMC5160_SPIWriteInt(V1_ADDR, speed_1,1); } tmc5160_operate(MOTOR_POS,51200*30); } } else//数据错误 { //SC_Init(); } } else //角行程——电机旋转一圈,磁条旋转4° { // motor_data[0] = 0x01;//00 直行程 01 角行程 // //判断电机停止还是运行,运行到起始位还是结束位 // if( Motor_Run == 0)//停止 // { // tmc5160_operate(0,0); // } // else if(Motor_Run == 1)//运行 // { // if(Motor_Run >= 1 && Runmotor_step == 0) // { // Runmotor_step = 1; // } // // //判断电机运行方式是点动还是连续,点动为方案三,方案一和方案二为连续 // if(Run_Mode == 0)//点动(方案三) // { // motor_data[2] = 0x00;//发送时反馈的数据 // mov_step_ang();//电机点动运行 // } // else if(Run_Mode == 1)//连续(方案一) // { // motor_data[2] = 0x01;//发送时反馈的数据 // mov_loop1_ang();//磁条旋转一圈 // } // else if(Run_Mode == 2)//连续(方案二) // { // motor_data[2] = 0x02;//发送时反馈的数据 // if(seat_flag == 0) // { // if(GPIO_ReadPin(GPIO1,GPIO_PIN_4) == 0) //判断是否到达限位处 // { // motor_stop(); //电机停止 // Run_mm = 0; // seat_flag = 1;//位置标记 // } // else // { // REV(); //反转 // motor_start(); //运行 // motor_mov(1); //提供脉冲信号 // } // } // else // { // mov_loop2_ang();//磁条旋转一圈 // } // } // else//初始化 // { // motor_stop(); // } // } // else if(Motor_Run == 2 || Motor_Run == 3)//运行到起始位 // { // mov_begin();//回到起始位 // } // else//数据错误 // SC_Init(); } } //电机点动运行,方案三(直行程) void mov_step(void) { if( (ocin1 == 0) && (motor_direc != MOTOR_POS) )//判断是否到达始限位 { motor_direc = MOTOR_POS; Runmotor_step = 0; Motor_Run = 0; return; } if( (ocin2 == 0) && (motor_direc != MOTOR_REV) )//判断是否到达终限位 { motor_direc = MOTOR_REV; Runmotor_step = 0; Motor_Run = 0; return; } // TMC5160_SPIReadInt(XACTUAL_ADDR,XA); //读取实际位置XACTUAL // XA_32 = Raw_32(XA); // TMC5160_SPIReadInt(VACTUAL_ADDR,VA); //读取实际速度VACTUAL // VA_32 = Raw_32(VA); if(Run_mm == 0) return;//步长不能为0 switch(Runmotor_step) { case 1 : //电机运行准备 { Runmotor_Nums = 0; //运行次数 mov_flag = 0; Runmotor_step++; } break; case 2 : //电机运行过程 { if(Run_Step == 0) //上位机无消息时使用下位机的控制参数Run_mm { tmc5160_operate(motor_direc,Run_mm * 10240); }else { tmc5160_operate(motor_direc,Run_Step * 1024);//Runstep cm } if(busy_flag == 0) { Runmotor_step++; } } break; case 3 : { // if(busy_flag == 0) // { // Runmotor_step++; // } Runmotor_step++; } break; case 4 : { if(it_50ms_flag) //检查1ms定时标志 { it_50ms_flag = 0;//定时标志清零 Runmotor_Nums++; } if(Runmotor_Nums >= 10)//时间 { Runmotor_Nums = 0; Runmotor_step++; get_state(); //读取电机当前状态 send_set_resp(0xF001, OBJ_DEVICE_ADDR, DATA_LEN, motor_data);//数据发送 } } break; case 5 : { Runmotor_step = 0; Motor_Run = 0; //运行标记清除,等待下一次上位机发送命令 } break; default : { } break; } } //电机连续运行,方案一(直行程) void mov_loop1(void) { // TMC5160_SPIReadInt(XACTUAL_ADDR,XA); //读取实际位置XACTUAL // XA_32 = Raw_32(XA); // TMC5160_SPIReadInt(VACTUAL_ADDR,VA); //读取实际速度VACTUAL // VA_32 = Raw_32(VA); switch(Runmotor_step) { case 1 : //电机运行准备 { //motor_direc = MOTOR_POS; //初始为正转 motor_dire = 1; // Run_mm = 0; Run_num = 0; motor_data[2] = 0x00; //发送时反馈的数据 Runmotor_Nums = 0; //运行次数 mov_flag = 0; busy_flag = 0; Runmotor_step++; } break; case 2 : //电机运行过程,运行至磁条所在范围 { if( X_ads1220 > magnet_start ) //电阻尺位置判断 { tmc5160_operate(MOTOR_STOP,0); // if(busy_flag == 1) break; if(it_1000ms_flag) //检查1ms定时标志 { it_1000ms_flag = 0; //定时标志清零 Runmotor_Nums++; } if(Runmotor_Nums >= Run_Stop) //时间 { Runmotor_step++; Runmotor_Nums = 0; get_state(); //读取电机当前状态 send_set_resp(0xF001, OBJ_DEVICE_ADDR, DATA_LEN, motor_data);//数据发送 } } else { if(send_flag == 0) { send_flag = 1; // get_state(); //读取电机当前状态 // send_set_resp(0xF001, OBJ_DEVICE_ADDR, DATA_LEN, motor_data);//数据发送 } //进入磁条范围前,以大步长进行运动,单位为mm,5mm转一圈 if( speed_max != SPEED_MAX) { speed_max = SPEED_MAX; TMC5160_SPIWriteInt(VMAX_ADDR, speed_max,1); // VMAX speed_1 = speed_max / 2; //V1 TMC5160_SPIWriteInt(V1_ADDR, speed_1,1); } tmc5160_operate( motor_direc, 51200*30 ); Runmotor_step = 6;//在case 2 - 6 之间循环,2运动,6限位 } } break; case 3 : { //进入磁条范围后,以小步长进行运动,单位为mm if( speed_max != SPEED_NORMAL) { speed_max = SPEED_NORMAL; //VMAX TMC5160_SPIWriteInt(VMAX_ADDR, speed_max,1); speed_1 = speed_max / 2; //V1 TMC5160_SPIWriteInt(V1_ADDR, speed_1,1); } if(Run_Step == 0) { tmc5160_operate(motor_direc,Run_mm*10240);//5mm-51200,1mm-10240 }else { tmc5160_operate(motor_direc,Run_Step*1024); } if(busy_flag == 0)//到达指定位置后释放busy_flag { Runmotor_step++; } } break; case 4 : //延时 { if(it_50ms_flag) //检查1ms定时标志 { it_50ms_flag = 0;//定时标志清零 Runmotor_Nums++; } if(Runmotor_Nums >= (Run_Inter / 50))//时间 { Runmotor_Nums = 0; Runmotor_step++; send_flag = 0; get_state(); //读取电机当前位置 send_set_resp(0xF001, OBJ_DEVICE_ADDR, DATA_LEN, motor_data);//数据发送 } } break; case 5 : { if( (ocin1 == 0) && (motor_direc != MOTOR_POS) )//判断是否到达始限位 { motor_direc = MOTOR_POS; Runmotor_step = 0; Motor_Run = 0; break; } if( (ocin2 == 0) && (motor_direc != MOTOR_REV) )//判断是否到达终限位 { motor_direc = MOTOR_REV; Runmotor_step = 0; Motor_Run = 0; break; } Runmotor_step = 3; if((X_ads1220 >= magnet_end) && (motor_direc != MOTOR_REV)) //超出磁条范围判断 { tmc5160_operate(MOTOR_STOP,0); if(busy_flag == 0) { motor_direc = MOTOR_REV; //反转 Runmotor_Nums = 0; Runmotor_step = 7; } } if((X_ads1220 <= magnet_start) && (motor_direc == MOTOR_REV)) //超出磁条范围判断 { Motor_Run = 2; //回起点 Runmotor_step = 0; } } break; case 6 : { if( (ocin1 == 0) && (motor_direc != MOTOR_POS) )//判断是否到达始限位 { motor_direc = MOTOR_POS; Runmotor_step = 0; Motor_Run = 0; break; } if( (ocin2 == 0) && (motor_direc != MOTOR_REV) )//判断是否到达终限位 { motor_direc = MOTOR_REV; Runmotor_step = 0; Motor_Run = 0; break; } Runmotor_step = 2;//在case 2 - 6 之间循环,2运动,6限位 } break; case 7 : { if(it_10ms_flag) //检查1ms定时标志 { it_10ms_flag = 0; //定时标志清零 Runmotor_Nums++; } if((Runmotor_Nums/100) >= Run_Stop) //时间 { Runmotor_step = 3; Runmotor_Nums = 0; } } break; default : { } break; } } void get_state(void) { motor_data[1] = Motor_Run; motor_data[2] = Run_Mode; motor_data[4] = rx_data2[1]; //磁条485 motor_data[5] = rx_data2[2]; motor_data[6] = rx_data2[3]; motor_data[7] = rx_data2[4]; /*电阻尺读数*/ // motor_data[8] = ((uint16_t)(X_ads1220*10) & 0xff00)>> 8; //磁条长度高8位 // motor_data[9] = (uint16_t)(X_ads1220*10) & 0x00ff; //磁条长度低8位 /*电机内部编码*/ uint16_t send_xa = 0; send_xa = ((XA_32 - first_xa_32) * 100) / 10240; motor_data[8] = ((uint16_t)send_xa & 0xff00)>> 8; //磁条长度高8位 motor_data[9] = ((uint16_t)send_xa & 0x00ff); //磁条长度低8位 if( ocin1 == 0 )//判断是否到达始限位 motor_data[3] = 1; else if(ocin2 == 0) motor_data[3] = 2; else motor_data[3] = motor_direc + 2; }