复制
收藏
提问
简洁

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

5e9deaf72
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,以及写入ARRwriteARR

typedef struct {
    pTimer startTimer; // 启动定时器的回调函数的地址
    pST stopTimer;     // 停止定时器的回调函数的地址
    pARR writeARR;     // 写ARR的回调函数的地址
} sSM_FC;

写入ARR的回调函数WriteARR

这个函数根据电机的ID来设置对应的定时器的自动重载寄存器ARRARR的值减1后赋给相应的定时器。

void WriteARR(u8 smid, u16 arr) {
    switch (smid) {
        // ... 省略其他case分支
    }
}

电机停止判断函数JudgeMotorStop

这个函数根据电机的停止模式来判断电机是否应该停止。它检查了多种停止条件,例如到达HOME位、步数走完、一直转动不停止等。

void JudgeMotorStop(eSM_ID smid) {
    // ... 省略具体逻辑
}

这段代码是一个电机控制系统的一部分,涉及到电机的初始化、参数配置、控制逻辑以及与硬件定时器的交互。如果您有更具体的问题或需要进一步的解释,请随时提问。

你觉得结果怎么样?
如何初始化电机控制结构体sSMP?
sSM_IP结构体中homeMaxSteps的作用是什么?
如何使用pTimer类型定义定时器回调函数?
eSM_ID枚举类型代表什么?
如何编写电机停止判断函数JudgeMotorStop?
WriteARR函数如何根据电机ID设置定时器值?

以上内容由AI搜集生成,仅供参考

在线客服