复制
收藏
提问
简洁
void SM_Init_FCN(eSM_ID smid,pTimer fstart,pST fstop,pARR warr) { sm[smid].smFC.startTimer=fstart; sm[smid].smFC.stopTimer=fstop; sm[smid].smFC.writeARR=warr; } sSMP sm[MOTORS]; typedef struct { sSM_IO smIO; //电机端口地址 sSM_IP smIP; //电机初始化参数 sSM_FC smFC; //函数指针 sSM_RP smRP; //电机运行参数 }sSMP; typedef struct { u32 homeMaxSteps;//HOME最大步数 u16 circleSteps; //1圈对应的步数(1细分),反应步距角。1.8°=360/200,则将circleSteps设为200。 u16 reduRatio; //减速比 u16 startSpeed; //启动速度(调速时使用) u8 subdivide; //细分 eSM_DIR homeDir; //HOME位的运动方向 u16 home0Steps; //进入HOME位0多少步后停止电机 u16 home1Steps; //进入HOME位1多少步后停止电机 eSM_HS home0EL; //进入HOME位0时的电平 eSM_HS home1EL; //进入HOME位1时的电平 }sSM_IP; typedef enum { MOTOR_PI =0, //推进电机 MOTOR_PS =1, //进样电机(单步电机) MOTOR_PO =2, //推出电机 MOTOR_BR =3, //搭桥电机 } eSM_ID; typedef void (*pTimer)(u16 p1); typedef void (*pST)(eSM_ID p1); typedef void (*pARR)(u8 p1,u16 p2); typedef struct { pTimer startTimer;//启动定时器的回调函数的地址 pST stopTimer;//停止定时器的回调函数的地址 pARR writeARR; //写ARR的回调函数的地址 }sSM_FC; void WriteARR(u8 smid,u16 arr) { switch(smid) { case MOTOR_PI: TIM2->ARR=arr-1; break; case MOTOR_PS: TIM3->ARR=arr-1; break; case MOTOR_PO: TIM4->ARR=arr-1; break; case MOTOR_BR: TIM5->ARR=arr-1; break; } } void JudgeMotorStop(eSM_ID smid) { switch(sm[smid].smRP.stopMode) { //运行到HOME0位 case ST_HOME0: if(*((IO_ADDR_TYPE *)(sm[smid].smIO.home0Addr))==sm[smid].smIP.home0EL) //和HOME0电平一致 sm[smid].smRP.inHomeSteps+=sm[smid].smRP.inHomeSteps<0xffff?1:0; else sm[smid].smRP.inHomeSteps=0; if((sm[smid].smRP.inHomeSteps>=sm[smid].smIP.home0Steps)||(sm[smid].smRP.thisTimeRunSteps>=sm[smid].smIP.homeMaxSteps)) SetMotorStop(smid); break; //运行到HOME1位 case ST_HOME1: if(*((IO_ADDR_TYPE *)(sm[smid].smIO.home1Addr))==sm[smid].smIP.home1EL) //和HOME1电平一致 sm[smid].smRP.inHomeSteps+=sm[smid].smRP.inHomeSteps<0xffff?1:0; else sm[smid].smRP.inHomeSteps=0; if((sm[smid].smRP.inHomeSteps>=sm[smid].smIP.home1Steps)||(sm[smid].smRP.thisTimeRunSteps>=sm[smid].smRP.totalSteps)) SetMotorStop(smid); break; //步数走完停止 case ST_STEP: if(sm[smid].smRP.thisTimeRunSteps>=sm[smid].smRP.totalSteps) SetMotorStop(smid); break; //一直转,不停止 case ST_NEVER: break; //离开HOME0 case ST_NOT_HOME0: if(*((IO_ADDR_TYPE *)(sm[smid].smIO.home0Addr))!=sm[smid].smIP.home0EL) //和HOME0电平不同 sm[smid].smRP.inNotHomeSteps+=sm[smid].smRP.inNotHomeSteps<0xffff?1:0; else sm[smid].smRP.inNotHomeSteps=0; if((sm[smid].smRP.inNotHomeSteps>=sm[smid].smIP.home0Steps)||(sm[smid].smRP.thisTimeRunSteps>=sm[smid].smRP.totalSteps)) SetMotorStop(smid); break; //离开HOME1位 case ST_NOT_HOME1: if(*((IO_ADDR_TYPE *)(sm[smid].smIO.home1Addr))!=sm[smid].smIP.home1EL) //和HOME1电平不同 sm[smid].smRP.inNotHomeSteps+=sm[smid].smRP.inNotHomeSteps<0xffff?1:0; else sm[smid].smRP.inNotHomeSteps=0; if((sm[smid].smRP.inNotHomeSteps>=sm[smid].smIP.home1Steps)||(sm[smid].smRP.thisTimeRunSteps>=sm[smid].smRP.totalSteps)) SetMotorStop(smid); break; //运行到下一个HOME0电平 case ST_NEXT_HOME0: if(sm[smid].smRP.inNotHomeSteps<sm[smid].smIP.home0Steps) //先运行到非HOME0电平位置 { if(*((IO_ADDR_TYPE *)(sm[smid].smIO.home0Addr))!=sm[smid].smIP.home0EL) sm[smid].smRP.inNotHomeSteps+=sm[smid].smRP.inNotHomeSteps<0xffff?1:0; if(sm[smid].smRP.thisTimeRunSteps>=sm[smid].smRP.totalSteps) SetMotorStop(smid); }else //再运行到HOME0电平位置 { if(*((IO_ADDR_TYPE *)(sm[smid].smIO.home0Addr))==sm[smid].smIP.home0EL) sm[smid].smRP.inHomeSteps+=sm[smid].smRP.inHomeSteps<0xffff?1:0; else sm[smid].smRP.inHomeSteps=0; if((sm[smid].smRP.inHomeSteps>=sm[smid].smIP.home0Steps)||(sm[smid].smRP.thisTimeRunSteps>=sm[smid].smRP.totalSteps)) SetMotorStop(smid); } break; //运行到下一个HOME1电平 case ST_NEXT_HOME1: if(sm[smid].smRP.inNotHomeSteps<sm[smid].smIP.home1Steps) //先运行到非HOME1电平位置 { if(*((IO_ADDR_TYPE *)(sm[smid].smIO.home1Addr))!=sm[smid].smIP.home1EL) sm[smid].smRP.inNotHomeSteps+=sm[smid].smRP.inNotHomeSteps<0xffff?1:0; if(sm[smid].smRP.thisTimeRunSteps>=sm[smid].smRP.totalSteps) SetMotorStop(smid); }else
1个月前
全网
文档
学术
百科
知识库
回答简洁模式
深入研究一些
您提供的代码是一个电机控制的初始化和控制逻辑的实现。这段代码定义了电机的初始化函数SM_Init_FCN
,电机的控制参数结构体sSM_IP
,电机的函数控制结构体sSM_FC
,以及一些电机控制的回调函数和逻辑判断函数。
电机初始化函数SM_Init_FCN
这个函数用于初始化电机的控制函数指针。它接收电机IDeSM_ID
,启动定时器的函数指针pTimer
,停止定时器的函数指针pST
,以及写入自动重载寄存器ARR
的函数指针pARR
。这些函数指针被分别赋值给电机控制结构体sSMP
中相应电机的smFC
成员。
void SM_Init_FCN(eSM_ID smid, pTimer fstart, pST fstop, pARR warr) {
sm[smid].smFC.startTimer = fstart;
sm[smid].smFC.stopTimer = fstop;
sm[smid].smFC.writeARR = warr;
}
电机控制参数结构体sSM_IP
这个结构体包含了电机的初始化参数,例如HOME最大步数homeMaxSteps
,一圈对应的步数circleSteps
,减速比reduRatio
,启动速度startSpeed
,细分subdivide
,HOME位的运动方向homeDir
,以及进入HOME位0和1的步数和电平。
typedef struct {
// ... 省略其他成员定义
} sSM_IP;
函数控制结构体sSM_FC
这个结构体定义了电机控制的三个回调函数指针:启动定时器startTimer
,停止定时器stopTimer
,以及写入ARR
的writeARR
。
typedef struct {
pTimer startTimer; // 启动定时器的回调函数的地址
pST stopTimer; // 停止定时器的回调函数的地址
pARR writeARR; // 写ARR的回调函数的地址
} sSM_FC;
写入ARR
的回调函数WriteARR
这个函数根据电机的ID来设置对应的定时器的自动重载寄存器ARR
。ARR
的值减1后赋给相应的定时器。
void WriteARR(u8 smid, u16 arr) {
switch (smid) {
// ... 省略其他case分支
}
}
电机停止判断函数JudgeMotorStop
这个函数根据电机的停止模式来判断电机是否应该停止。它检查了多种停止条件,例如到达HOME位、步数走完、一直转动不停止等。
void JudgeMotorStop(eSM_ID smid) {
// ... 省略具体逻辑
}
这段代码是一个电机控制系统的一部分,涉及到电机的初始化、参数配置、控制逻辑以及与硬件定时器的交互。如果您有更具体的问题或需要进一步的解释,请随时提问。
你觉得结果怎么样?