
在上一篇博文中,我们能够确定级联控制器回路的稳定P-I参数。有了这些知识,我们想向您展示我们是如何创建一个小的示例程序的,并放入Landungsrbücke的固件中。
此代码的基本功能是初始化步进电机控制的TMC4671。这是在init_Basics(…)中通过编写几个配置寄存器来完成的,而reset_Basics(…)将此工作中使用的所有寄存器重置为定义的0状态。这将取代IDE配置向导中使用默认按钮的第一步。
配置ABN(…)-功能将在功率因数调整转子至0后将ABN计数设置为0。要做到这一点,我们还需要对磁通施加电压。
init_PosMode(…)设置TMC4671进入位置模式的正确寄存器。
使用TMC4671_setAbsolutTargetPosition(…)将控制器的目标位置设置为所需值,使电机转动,直到达到目标位置。这里的绝对位置总是指我们在configure_ABN(…)函数中配置的零位置。
注:如果您希望相对于实际位置移动,可以使用函数TMC4671_setRelativeTargetPosition(…)。
为了找到我的设置的最小和最大位置,我在“查找目标位置”(…)中选择了两个无法到达的目标位置。对我来说,这是500000和-500000。控制器等待一定时间以确保它到达结束位置。然后用函数TMC4671_getActualPosition(…)保存实际位置。另一个方向也进行同样的设置。两个端点的值现在可以用于新的目标位置,可以再次使用TMC4671_setAbsolutTargetPosition(…)来设置。
运行时也可以使用线性坡道加速和减速, 使用函数TMC_ramp_linear_compute(…)和类型为TMC_LinearRamp的结构来实现这个功能(您可以在文件LinearRamp1.h和LinearRamp1.c中的API中找到更多信息)。这将在软件中创建一个包含我们的轨迹信息的斜坡。我还使用上述文件中的相应函数设置了结构的一些参数。我可以使用结构中的TMC_ramp_linear_set_target position(…)设置渐变的目标位置。之后,我使用TMC4671_setAbsolutTargetPosition(calculated_ramp)中计算出的斜坡位置, 循环工作直到达到实际目标位置,。
斜坡有什么作用?我们不是设定一条指令可以到达的绝对目标位置,而是将轨迹划分为多个子目标位置。在循环的每次迭代中,我们增加目标位置,控制器将调整到新的目标。然而,Landungsbrücke增加目标位置的速度比我们控制器的自适应速度高,因此随着时间的推移,目标位置和实际电机位置之间的差异增大。当实际位置和目标位置之间的偏移量增加时,这会导致电机加速。
减速则相反。Landungsbrücke将降低设定目标位置的速度,控制器将慢慢跟上,直到到达终点位置。
为了提高马达的速度,我把实际的斜坡位置乘以1024倍。这必须通过将软件斜坡的目标位置除以1024来补偿。这样我们就可以根据我们的应用来调整斜坡,并增加马达的加速度和速度。
为什么要使用(软件)渐变?基本上,它给了我们一个更稳定的方法来达到我们的目标位置,因为我们有一个确定的加速和减速的方法,它大大减少了超过目标的可能性。
Landungsbrücke在TMC4671寄存器中交替这些目标位置,因此电机将交替滑动的位置。
使用完成的代码,我为Landungsrbücke的引导加载程序生成一个十六进制文件,并使用TMCL-IDE更新它。
希望你能利用一些显示的例子,以便你转换数字信息为你的项目的物理运动!
使用以下代码,将初始化我的驱动器,执行编码器初始化,并在两个末端停止上执行重设原点。然后,执行来回运动。
我可以用TMCL-IDE将固件上传到Landungsbrücke,开机后它会自动启动。我可以通过RTMI监控系统行为。
代码示例:
#include "boards/Board.h"
#include "hal/derivative.h"
#include "hal/HAL.h"
#include "tmc/IdDetection.h"
#include "tmc/TMCL.h"
#include "tmc/VitalSignsMonitor.h"
#include "tmc/BoardAssignment.h"
#include "tmc/ramp/LinearRamp1.h"
#include "TMC-API/tmc/ic/TMC4671/TMC4671.h"
#include "TMC-API/tmc/ic/TMC4671/TMC4671_Register.h" //As I use the names of its registers this needs to be included
//mydefines
#define STATE_START_INIT 1
#define STATE_RUN_1 2
#define STATE_RUN_2 3
#define UD_EXT 3202
//Torque-Flux Limits 15000
#define TORQUE_FLUX_LIMIT 10000
//Velocity Limit 10000
#define VELOCITY_LIMIT 10000
//P-I-defines
#define TORQUE_FLUX_P 4952
#define TORQUE_FLUX_I 10939
#define VELOCITY_P 2200
#define VELOCITY_I 2000
#define POSITION_P 45
#define POSITION_I 0
//for checking motor supply voltage
#define VM_FACTOR 713
#define ADC_VM_RES 65535 //Landungsbruecke define -- change for Startrampe
//Software-Ramp defines
#define STEPDIR_FREQUENCY (1 << 17)
#define STEPDIR_MAX_VELOCITY (1 << 20)
#define STEPDIR_MAX_ACCELERATION 2147418111
#define STEPDIR_DEFAULT_ACCELERATION 100000
#define STEPDIR_DEFAULT_VELOCITY STEPDIR_MAX_VELOCITY
#define RAMP_SPEED_FACTOR 1024
//end mydefines
void init_PosMode(uint8_t motor)
{ //Set registers needed for position mode
//tmc4671_writeInt(motor, TMC4671_VELOCITY_SELECTION, TMC4671_VELOCITY_PHI_M_ABN);
tmc4671_writeInt(motor, TMC4671_PID_TORQUE_FLUX_TARGET_DDT_LIMITS, 32767); //max
tmc4671_writeInt(motor, TMC4671_PIDOUT_UQ_UD_LIMITS, 32767); //max
tmc4671_writeInt(motor, TMC4671_PID_TORQUE_FLUX_LIMITS, TORQUE_FLUX_LIMIT);
tmc4671_writeInt(motor, TMC4671_PID_ACCELERATION_LIMIT, 2147483647);
tmc4671_writeInt(motor, TMC4671_PID_VELOCITY_LIMIT, VELOCITY_LIMIT);
tmc4671_writeInt(motor, TMC4671_PID_POSITION_LIMIT_LOW, 0x80000001);
tmc4671_writeInt(motor, TMC4671_PID_POSITION_LIMIT_HIGH, 0x7FFFFFFF);
tmc4671_writeInt(motor, TMC4671_PHI_E_SELECTION, 0x00000003); //phi_e_abn
tmc4671_writeInt(motor, TMC4671_VELOCITY_SELECTION, TMC4671_VELOCITY_PHI_M_ABN);
tmc4671_writeInt(motor, TMC4671_POSITION_SELECTION, TMC4671_POSITION_PHI_M_ABN); //phi_m_abn
tmc4671_writeInt(motor, TMC4671_MODE_RAMP_MODE_MOTION, 0x00000003); //position mode
//The following gain-values were determined using the USB-2-RTMI and following the PI-tuning guide
tmc4671_setTorqueFluxPI(motor, TORQUE_FLUX_P, TORQUE_FLUX_I); //(motor, P, I)
tmc4671_setVelocityPI(motor, VELOCITY_P, VELOCITY_I);
tmc4671_setPositionPI(motor, POSITION_P, POSITION_I);
}
//Check VM
uint32_t current_VM()
{
uint32_t VM;
VM = *HAL.ADCs->VM; // read ADC value for motor supply VM
VM = (VM*VM_FACTOR)/ADC_VM_RES; // calculate voltage from ADC value
return VM;
}
//End Check VM
void init_Basics(uint8_t motor)
{
//Configure basic registers like motor type, adc-offset
tmc4671_writeInt(motor, TMC4671_MOTOR_TYPE_N_POLE_PAIRS, 0x00020032); //x0002 - Stepper, x0032 = 50 polepairs
tmc4671_writeInt(motor, TMC4671_PWM_POLARITIES, 0x00000000);
tmc4671_writeInt(motor, TMC4671_PWM_MAXCNT, 0x00000F9F); //Maxcount of PWM-counter
tmc4671_writeInt(motor, TMC4671_PWM_BBM_H_BBM_L, 0x00001919); //Break before make times
tmc4671_writeInt(motor, TMC4671_PWM_SV_CHOP, 0x00000007); //turn on PWM
//Configure ADC -- Values were taken from the ide after the set offset option was used
tmc4671_writeInt(motor, TMC4671_ADC_I_SELECT, 0x18000100); // configure ADC-Inputs
tmc4671_writeInt(motor, TMC4671_dsADC_MCFG_B_MCFG_A, 0x00100010); // configure ADCs
tmc4671_writeInt(motor, TMC4671_dsADC_MCLK_A, 0x20000000); // turn on clock-signal for group-A ADCs
tmc4671_writeInt(motor, TMC4671_dsADC_MCLK_B, 0x00000000); // turn off clock-signal for group-B ADCs
tmc4671_writeInt(motor, TMC4671_dsADC_MDEC_B_MDEC_A, 0x014E014E); // Constants for filter
tmc4671_writeInt(motor, TMC4671_ADC_I0_SCALE_OFFSET, 0x01005D80); // Fill in the offsets determined in the IDE
tmc4671_writeInt(motor, TMC4671_ADC_I1_SCALE_OFFSET, 0x01005CEF); // Fill in the offsets determined in the IDE
// Open loop settings
tmc4671_writeInt(motor, TMC4671_OPENLOOP_MODE, 0x00000000);
tmc4671_writeInt(motor, TMC4671_OPENLOOP_ACCELERATION, 0x0000003C);
tmc4671_writeInt(motor, TMC4671_OPENLOOP_VELOCITY_TARGET, 0x00000000);
tmc4671_writeInt(motor, TMC4671_OPENLOOP_PHI, 0x00000000);
// Feedback selection
tmc4671_writeInt(motor, TMC4671_PHI_E_SELECTION, 0x00000000);
tmc4671_writeInt(motor, TMC4671_MODE_RAMP_MODE_MOTION, 0x00000008);
//tmc4671_writeInt(motor, TMC4671_UQ_UD_EXT, 0x00000F9F);
tmc4671_writeInt(motor, TMC4671_ABN_DECODER_PPR, 0x00009C40);
//Set Limits
tmc4671_writeInt(motor, TMC4671_PID_TORQUE_FLUX_TARGET_DDT_LIMITS, 0x7FFF); //max
tmc4671_writeInt(motor, TMC4671_PIDOUT_UQ_UD_LIMITS, 32767); //max
tmc4671_writeInt(motor, TMC4671_PID_TORQUE_FLUX_LIMITS, TORQUE_FLUX_LIMIT);
tmc4671_writeInt(motor, TMC4671_PID_ACCELERATION_LIMIT, 2147483647);
tmc4671_writeInt(motor, TMC4671_PID_VELOCITY_LIMIT, VELOCITY_LIMIT);
tmc4671_writeInt(motor, TMC4671_PID_POSITION_LIMIT_LOW, 0x80000001);
tmc4671_writeInt(motor, TMC4671_PID_POSITION_LIMIT_HIGH, 0x7FFFFFFF);
}
void reset_Basics(uint8_t motor)
{
//reset registers of TMC4671 that will later be used to 0
wait(1500);
tmc4671_writeInt(motor, TMC4671_PWM_SV_CHOP, 0);
tmc4671_writeInt(motor, TMC4671_MOTOR_TYPE_N_POLE_PAIRS, 0);
tmc4671_writeInt(motor, TMC4671_PWM_POLARITIES, 0);
tmc4671_writeInt(motor, TMC4671_PWM_MAXCNT, 0);
tmc4671_writeInt(motor, TMC4671_PWM_BBM_H_BBM_L, 0);
tmc4671_writeInt(motor, TMC4671_ADC_I_SELECT, 0);
tmc4671_writeInt(motor, TMC4671_dsADC_MCFG_B_MCFG_A, 0);
tmc4671_writeInt(motor, TMC4671_dsADC_MCLK_A, 0);
tmc4671_writeInt(motor, TMC4671_dsADC_MCLK_B, 0);
tmc4671_writeInt(motor, TMC4671_dsADC_MDEC_B_MDEC_A, 0);
tmc4671_writeInt(motor, TMC4671_ADC_I0_SCALE_OFFSET, 0);
tmc4671_writeInt(motor, TMC4671_ADC_I1_SCALE_OFFSET, 0);
tmc4671_writeInt(motor, TMC4671_OPENLOOP_MODE, 0);
tmc4671_writeInt(motor, TMC4671_OPENLOOP_ACCELERATION, 0);
tmc4671_writeInt(motor, TMC4671_OPENLOOP_VELOCITY_TARGET, 0);
tmc4671_writeInt(motor, TMC4671_PHI_E_SELECTION, 0);
tmc4671_writeInt(motor, TMC4671_MODE_RAMP_MODE_MOTION, 0);
tmc4671_writeInt(motor, TMC4671_UQ_UD_EXT, 0);
tmc4671_writeInt(motor, TMC4671_ABN_DECODER_PPR, 0);
tmc4671_writeInt(motor, TMC4671_PID_TORQUE_FLUX_TARGET_DDT_LIMITS, 0);
tmc4671_writeInt(motor, TMC4671_PIDOUT_UQ_UD_LIMITS, 0);
tmc4671_writeInt(motor, TMC4671_PID_TORQUE_FLUX_LIMITS, 0);
tmc4671_writeInt(motor, TMC4671_PID_ACCELERATION_LIMIT, 0);
tmc4671_writeInt(motor, TMC4671_PID_VELOCITY_LIMIT, 0);
tmc4671_writeInt(motor, TMC4671_PID_POSITION_LIMIT_LOW, 0);
tmc4671_writeInt(motor, TMC4671_PID_POSITION_LIMIT_HIGH, 0);
tmc4671_writeInt(motor, TMC4671_PHI_E_SELECTION, 0);
tmc4671_writeInt(motor, TMC4671_VELOCITY_SELECTION, 0);
tmc4671_writeInt(motor, TMC4671_POSITION_SELECTION, 0);
tmc4671_writeInt(motor, TMC4671_MODE_RAMP_MODE_MOTION, 0);
tmc4671_writeInt(motor, TMC4671_PID_POSITION_TARGET, 0);
tmc4671_writeInt(motor, TMC4671_PID_POSITION_ACTUAL, 0);
tmc4671_setTorqueFluxPI(motor, 0, 0); //(motor, P, I)
tmc4671_setVelocityPI(motor, 0, 0); // (motor, P, I)
tmc4671_setPositionPI(motor, 0, 0); // (motor, P, I)
}
void init_softwareRamp(TMC_LinearRamp *linearRamp)
{
tmc_ramp_linear_init(linearRamp);
tmc_ramp_linear_set_mode(linearRamp, TMC_RAMP_LINEAR_MODE_POSITION);
tmc_ramp_linear_set_maxVelocity(linearRamp, STEPDIR_DEFAULT_VELOCITY);
tmc_ramp_linear_set_acceleration(linearRamp, STEPDIR_DEFAULT_ACCELERATION);
}
void find_targetPositions(uint8_t motor, int32_t *lower_End, int32_t*upper_End)
{
tmc4671_setAbsolutTargetPosition(motor, 500000); // ~ 7.5 motor turns
wait(1500);
/* After slide reached one end of the setup the absolute position is stored in memory
For convenience I reduce the value of the target position to be saved a little,
* as driving into the endposition with full force is annoyingly loud :)
* if this is your goal just remove the +/- 1000 */
*lower_End = (tmc4671_getActualPosition(motor)-1000);
tmc4671_setAbsolutTargetPosition(motor, 0); //return to the starting position
wait(1000);
// Assumed an unreachable position so the slide reaches the other side of the setup
tmc4671_setAbsolutTargetPosition(motor, -500000); // ~ -7.5 motor turns
wait(1500);
// After slide reached the other end of the setup the absolute position is stored in memory
*upper_End = (tmc4671_getActualPosition(motor)+1000);
tmc4671_setAbsolutTargetPosition(motor, 0);
wait(1500);
}
void configure_ABN(uint8_t motor, uint16_t startVoltage)
{
// set ABN_DECODER_PHI_E_OFFSET to zero
tmc4671_writeRegister16BitValue(motor, TMC4671_ABN_DECODER_PHI_E_PHI_M_OFFSET, BIT_16_TO_31, 0);
// select phi_e_ext
tmc4671_writeRegister16BitValue(motor, TMC4671_PHI_E_SELECTION, BIT_0_TO_15, 1);
// set an initialization voltage on UD_EXT (to the flux, not the torque!)
tmc4671_writeRegister16BitValue(motor, TMC4671_UQ_UD_EXT, BIT_16_TO_31, 0);
tmc4671_writeRegister16BitValue(motor, TMC4671_UQ_UD_EXT, BIT_0_TO_15, startVoltage);
// set the "zero" angle
tmc4671_writeRegister16BitValue(motor, TMC4671_PHI_E_EXT, BIT_0_TO_15, 0);
tmc4671_writeInt(motor, TMC4671_ABN_DECODER_MODE, 0x00001000);
//Set PHI_E to 0° angle so the rotor alignes itself with it
tmc4671_writeInt(motor, TMC4671_PHI_E_SELECTION, 0x00000000);
wait(4000);
tmc4671_readRegister16BitValue(motor, TMC4671_ABN_DECODER_PHI_E_PHI_M, BIT_16_TO_31);
//After the rotor has aligned this will set the ABN_DECODER_COUNT to 0 so there is a defined 0-position
tmc4671_writeInt(motor, TMC4671_ABN_DECODER_COUNT, 0);
}
void tmc4671setPositionModeAndRun(uint8_t motor, uint8_t *initState, uint16_t startVoltage, int32_t *upper_End, int32_t *lower_End, TMC_LinearRamp *linearRamp)
{
/*State Machine with state-pointer *initState and 3 states
* STATE_START_INIT: Sets TMC4671-registers for my application and configures the ABN-Encoder
* Drives to the ends of the track to get the actual min/max position values
* Drives to the first end position
*
* STATE_RUN_1: Drives to one end and changes direction when the *lower_End is reached
*
* STATE_RUN_2: Drives to the other end and changes direction when *upper_End is reached
*/
switch (*initState)
{
case STATE_START_INIT:
//reset TMC4671 registers
reset_Basics(motor);
//set TMC4671 registers with basic data like motortype, number of polepairs and so on
init_Basics(motor);
//initialize the software ramp
init_softwareRamp(linearRamp);
//configure ABN
configure_ABN(motor, startVoltage);
//Enter position-Mode
init_PosMode(motor);
//configure the end positions and store them in *lower_End and *upper_End
find_targetPositions(motor, lower_End, upper_End);
*initState = STATE_RUN_1;
//set the first target position using the software ramp
tmc_ramp_linear_set_targetPosition(linearRamp, (*lower_End/RAMP_SPEED_FACTOR));
break;
case STATE_RUN_1:
//drive from one end to the other: positive direction
tmc_ramp_linear_compute(linearRamp);
tmc4671_setAbsolutTargetPosition(motor, (RAMP_SPEED_FACTOR*tmc_ramp_linear_get_rampPosition(linearRamp)));
//When the target position is reached we will change direction
if(tmc4671_getActualPosition(motor) >= (*lower_End-RAMP_SPEED_FACTOR))
{
wait(50);
*initState = STATE_RUN_2;
tmc_ramp_linear_set_targetPosition(linearRamp, (*upper_End/RAMP_SPEED_FACTOR));
break;
}
*initState = STATE_RUN_1;
break;
case STATE_RUN_2:
//drive from one end to the other: negative direction
tmc_ramp_linear_compute(linearRamp);
tmc4671_setAbsolutTargetPosition(motor, (RAMP_SPEED_FACTOR*tmc_ramp_linear_get_rampPosition(linearRamp)));
//When the target position is reached we will change direction
if(tmc4671_getActualPosition(motor) <= (*upper_End + RAMP_SPEED_FACTOR))
{
wait(50);
*initState = STATE_RUN_1;
tmc_ramp_linear_set_targetPosition(linearRamp, (*lower_End/RAMP_SPEED_FACTOR));
break;
}
*initState = STATE_RUN_2;
break;
default:
*initState = 0;
break;
}
}
const char *VersionString = MODULE_ID"V308"; // module id and version of the firmware shown in the TMCL-IDE
/* Keep as is! These lines are important for the update functionality. */
#if defined(Landungsbruecke)
const uint8_t Protection[] __attribute__ ((section(".cfmconfig")))=
{
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //Backdoor key
0xFF, 0xFF, 0xFF, 0xFF, //Flash protection (FPPROT)
0x7E, //Flash security (FSEC)
0xF9, //Flash option (FOPT)
0xFF, //reserved
0xFF //reserved
};
struct BootloaderConfig {
uint32_t BLMagic;
uint32_t drvEnableResetValue;
};
// This struct gets placed at a specific address by the linker
struct BootloaderConfig __attribute__ ((section(".bldata"))) BLConfig;
#endif
/* Check if jumping into bootloader is forced */
/* */
/* In order to jump to bootloader e.g. because of an accidental infinite loop */
/* in a modified firmware you may short ID_CLK and ID_CH0 pins on start up. */
/* This will force the entrance into bootloader mode and allow to replace bad firmware. */
void shallForceBoot()
{
// toggle each pin and see if you can read the state on the other
// leave if not, because this means that the pins are not tied together
HAL.IOs->config->toOutput(&HAL.IOs->pins->ID_CLK);
HAL.IOs->config->toInput(&HAL.IOs->pins->ID_CH0);
HAL.IOs->config->setHigh(&HAL.IOs->pins->ID_CLK);
if(!HAL.IOs->config->isHigh(&HAL.IOs->pins->ID_CH0))
return;
HAL.IOs->config->setLow(&HAL.IOs->pins->ID_CLK);
if(HAL.IOs->config->isHigh(&HAL.IOs->pins->ID_CH0))
return;
HAL.IOs->config->toOutput(&HAL.IOs->pins->ID_CH0);
HAL.IOs->config->toInput(&HAL.IOs->pins->ID_CLK);
HAL.IOs->config->setHigh(&HAL.IOs->pins->ID_CH0);
if(!HAL.IOs->config->isHigh(&HAL.IOs->pins->ID_CLK))
return;
HAL.IOs->config->setLow(&HAL.IOs->pins->ID_CH0);
if(HAL.IOs->config->isHigh(&HAL.IOs->pins->ID_CLK))
return;
// not returned, this means pins are tied together
tmcl_boot();
}
/* Call all standard initialization routines. */
static void init()
{
#if defined(Landungsbruecke)
// Default value: Driver enable gets set high by the bootloader
BLConfig.drvEnableResetValue = 1;
#endif
HAL.init(); // Initialize Hardware Abstraction Layer
IDDetection_init(); // Initialize board detection
tmcl_init(); // Initialize TMCL communication
tmcdriver_init(); // Initialize dummy driver board --> preset EvalBoards.ch2
tmcmotioncontroller_init(); // Initialize dummy motion controller board --> preset EvalBoards.ch1
VitalSignsMonitor.busy = 1; // Put state to busy
Evalboards.driverEnable = DRIVER_ENABLE;
Evalboards.ch1.id = 0; // preset id for driver board to 0 --> error/not found
Evalboards.ch2.id = 0; // preset id for driver board to 0 --> error/not found
// We disable the drivers before configurating anything
HAL.IOs->config->toOutput(&HAL.IOs->pins->DIO0);
HAL.IOs->config->setHigh(&HAL.IOs->pins->DIO0);
IdAssignmentTypeDef ids = { 0 };
IDDetection_initialScan(&ids); // start initial board detection
IDDetection_initialScan(&ids); // start second time, first time not 100% reliable, not sure why - too fast after startup?
if(!ids.ch1.id && !ids.ch2.id)
{
shallForceBoot(); // only checking to force jump into bootloader if there are no boards attached
HAL.IOs->config->toOutput(&HAL.IOs->pins->ID_CLK);
HAL.IOs->config->toInput(&HAL.IOs->pins->ID_CH0);
}
Board_assign(&ids); // assign boards with detected id
VitalSignsMonitor.busy = 0; // not busy any more!
}
/* main function */
int main(void)
{
//initialise some pointers
//state pointer for fsm
uint8_t init_State = STATE_START_INIT;
uint8_t *initState;
initState = &init_State;
//store one end of the track
int32_t upper_end = 0;
int32_t *upper_End;
upper_End= &upper_end;
//store the other end
int32_t lower_end = 0;
int32_t *lower_End;
lower_End= &lower_end;
//convenience
uint8_t motor = 0;
//"flipflop"
uint8_t block = 0;
//struct used for the software ramp - see \TMC-API\tmc\ramp\LinearRamp1.h for typedef etc.
TMC_LinearRamp adressRamp;
TMC_LinearRamp *aRamp;
aRamp = &adressRamp;
init();
// Main loop
while(1)
{
// Check all parameters and life signs and mark errors
vitalsignsmonitor_checkVitalSigns();
// Perodic jobs of Motion controller/Driver boards
Evalboards.ch1.periodicJob(systick_getTick());
Evalboards.ch2.periodicJob(systick_getTick());
// Process TMCL communication
tmcl_process();
if (Evalboards.ch1.id != ID_TMC4671)
continue;
if(current_VM()<20){
tmc4671_writeInt(motor, TMC4671_PWM_SV_CHOP, 0); // Turn off PWM after unexpected reset
reset_Basics(motor); // Set the registers needed in this example to a defined default state
continue;
}
if(block == 0)
{
tmc4671_writeInt(motor, TMC4671_PWM_SV_CHOP, 0); //Turn of PWM-Register after SPI was initialized
reset_Basics(motor);
block = 1;
}
tmc4671setPositionModeAndRun(motor, initState, UD_EXT, lower_End, upper_End, aRamp);
}
return 0;
}
TRINAMIC代理商 步进电机驱动 驱动IC 深圳市智联微电子有限公司







评论前必须登录!
注册