主控传参结构体强制转换(单针运行为例)
//假设DWIN屏给命令0x2015068300070100C8
Event_With_Para_t NewCommand;
uint16_t CommandPara;
uint16_t CommandAddr;
CommandAddr = ((uint16_t)pcNewCommandString[1] << 8) | pcNewCommandString[2];
CommandPara = ((uint16_t)pcNewCommandString[4] << 8) | pcNewCommandString[5];
//CommandAddr = 0x0007,CommandPara = 0x00C8
SingleStitch_CmdData_t* pNewData = (SingleStitch_CmdData_t *) &NewCommand.Para;
NewCommand.Event = EX_STITCHTEST;
pNewData->Type = STITCH_COUNT;
pNewData->StitchCount = ((uint16_t)pcNewCommandString[4] << 8) | pcNewCommandString[5]; // 0x00C8
xQueueSendToBack(xEventWithParaQueue, &NewCommand, (TickType_t)0);
// 进入单针运行回调函数
Command_Block_t NewCommand;
Event_With_Para_t* pMessage = (Event_With_Para_t*)parameter; //parameter 是队列中所接收到的NewCommand
SingleStitch_CmdData_t* pNewStitch = (SingleStitch_CmdData_t*)NewCommand.CmdData; //pNewStitch 指向 NewCommand.CmdData 操作pNewStitch就是操作NewCommand.CmdData
SingleStitch_CmdData_t* pOldStitch = (SingleStitch_CmdData_t*)pMessage->Para;
if(xSysVar.FSMStatFlag.bit.File_is_Valid) // 判断文件是否有效
{
NewCommand.eCommandType = SINGLE_STITCH_CMD;
pNewStitch->Type = pOldStitch->Type;
pNewStitch->StitchCount = pOldStitch->StitchCount;
prvSendToAction(&NewCommand);
}
// 动作分配函数
// 单针运行 前提! 执行模块优先级比本模块高 保证当前针永远是正确的
static void prvSingleStitchCmd(Command_Block_t *pNewCommand)
{
SingleStitch_CmdData_t *pNewStitch = (SingleStitch_CmdData_t *)pNewCommand->CmdData; //pNewStitch 指向 NewCommand.CmdData 操作pNewStitch就是操作NewCommand.CmdData
position Travel_mm, offset_position, first_point, rotary_position, target_position, cur_position;
double total;
uint32_t uStitchCnt = 0xFFFFFFFF;
static uint32_t uStitchInc = 1;
static uint32_t uStitchtmp = 0;
Event_List_t xReturnEvent;
static TimeRecorder_t time_record;
// 当前针设置计数值
if (pNewStitch->StitchCount > g_CurFile.CF_TotalStitchNum - 1)
uStitchCnt = g_CurFile.CF_TotalStitchNum - 1;
else
uStitchCnt = pNewStitch->StitchCount;
xReturnEvent = FB_STITCH_SINGLE_COUNT_OK;
if (vGetExeError() == EXE_NO_ERROR)
{
// 反馈
Event_With_Para_t NewCommand;
SingleStitch_CmdData_t* pNewData = (SingleStitch_CmdData_t *) &NewCommand.Para;
NewCommand.Event = xReturnEvent;
pNewData->StitchCount = uStitchCnt;
xQueueSendToBack(xEventWithParaQueue, &NewCommand, (TickType_t)0);
}
else
prvErrorReport(vGetExeError());
}
/*
带参数事件结构体
typedef struct
{
uint8_t Para[64]; // 参数
Event_List_t Event;
}Event_With_Para_t;
*/
/*
命令结构体
typedef struct _Command_Block
{
uint8_t CmdData[64]; // 由于字节对齐原因,字符数组必须定义在前面
Command_List_t eCommandType;
}Command_Block_t;
*/
/*
单针数据
typedef struct _SingleStitch_CmdData
{
enum __Type
{
STITCH_UP,
STITCH_DOWN,
STITCH_COUNT,
}Type;
uint32_t StitchCount;
}SingleStitch_CmdData_t;
*/
/*
uint8_t Para[64];
NewCommand.Para强制转换成SingleStitch_CmdData_t类型 (对齐内存结构)
———— ———— ———— ———— ———— ———— ———— ———— char类型
____ ____ ____ ____ ____ ____ ____ ____
———— ———— ———— ———— ———— ———— ———— ————
____ ____ ____ ____ \ ____ ____ ____ ____
\
———— ———— ———— ———— ———————————— \ ———— ———— ———— ————
____ ____ ____ ____ ———————————— / ____ ____ ____ ____
/
———— ———— ———— ———— / ———— ———— ———— ————
char类型 ____ ____ ____ ____ ____ ____ ____ ____
———— ———— ———— ———— ———— ———— ———— ————
____ ____ ____ ____ ____ ____ ____ ____
———— ———— ———— ———— ———— ———— ———— ————
____ ____ ____ ____ ____ ____ ____ ____
———— ———— ———— ———— ———— ———— ———— ————
____ ____ ____ ____ ____ ____ ____ ____
———— ———— ———— ———— ——————————————————— (int) enum --> 相当于一个int类型的符号常量
____ ____ ____ ____ ___________________ uint32_t StitchCount
*/
单针运行过程
typedef struct vector_
{
double x;
double y;
}vector;
typedef vector position;
//#define TEST_0318_1 // 增加运动信息文件输出
//#define TEST_0321_1 // 记录原始数据 不输出
typedef struct stitch_
{
StitchInfo_t info; /* uses codes defined above */
double xx; /* absolute position (not relative)*/
double yy; /* positive is up, units are in mm */
double arg;
double spd;
vector axis; // 位移距离
uint8_t compensate;
#ifdef TEST_0318_1
useful_data data_x;
useful_data data_y;
#endif
#ifdef TEST_0321_1
axis_data_t x_instance_save;
axis_data_t y_instance_save;
#endif
}stitch;
// 当前文件结构体
typedef struct _Current_File
{
uint16_t CF_EntityNum; // 线段数目
uint16_t CF_StitchNum[SEW_FILE_MAX_ENTITY]; // 每条线段的点数
uint16_t CF_Idx[SEW_FILE_MAX_ENTITY]; // 每条线段的开始下标
int16_t CF_ModifyStitch[SEW_FILE_MAX_ENTITY]; // 针数修改参数 每段线段可以修改针数(尾部) 正数为加 负数为减
uint32_t CF_TotalStitchNum; // 总针数
uint32_t CF_StitchCnt; // 起始位置 针数
uint32_t CF_EntityCnt; // 实体数
position Max_Position; // xy分别能达到的最大位置
position Min_Position; // xy分别能达到的最小位置
position Tamplate_Position; // 放模板位置
position Fixed_Point; // 参考点
position Default_Origin_Point; // 默认原点
stitch *CF_Stitch; // 针
File_Info_t CF_Info; // 文件信息
}CurrentFile_t;
CurrentFile_t g_CurFile;
// 如果设置成功 则可以开始运动
if(uStitchCnt == 0xFFFFFFFF)
return;
target_position.x = g_CurFile.CF_Stitch[uStitchCnt].xx;
target_position.y = g_CurFile.CF_Stitch[uStitchCnt].yy;
first_point.x = g_CurFile.CF_Stitch[0].xx;
first_point.y = g_CurFile.CF_Stitch[0].yy;
// 旋转矫正
rotary_position = PositionRotary(first_point, target_position,g_CurFile.CF_Info.Offset_Angle);
// 平移矫正
offset_position = GetPositionOffset(g_CurFile.CF_EntityCnt,g_CurFile.CF_Info.Entity_Offset);
// 相对机械原点的距离
Travel_mm.x = rotary_position.x + offset_position.x + g_CurFile.CF_Info.File_Origin.x ;
Travel_mm.y = rotary_position.y + offset_position.y + g_CurFile.CF_Info.File_Origin.y ;
// 相对当前位置的距离
GetCurrentPosition(&cur_position.x , &cur_position.y);
Travel_mm.x = Travel_mm.x - cur_position.x;
Travel_mm.y = Travel_mm.y - cur_position.y;
// 运动
total = Travel_mm.x * Travel_mm.x + Travel_mm.y * Travel_mm.y;
if(total > 25) // 总距离大于5 则用加减速 否则用匀速
axis(Travel_mm.x, Travel_mm.y, Settings.jumping_speed, Settings.single_stitch_acc);
else
axis_Uniform_Motion(Travel_mm.x, Travel_mm.y, Settings.single_stitch_speed);
MilisecondCounter(1, &time_record);
if (vGetExeError() == EXE_NO_ERROR)
{
// 反馈
Event_With_Para_t NewCommand;
SingleStitch_CmdData_t* pNewData = (SingleStitch_CmdData_t *) &NewCommand.Para;
NewCommand.Event = xReturnEvent;
pNewData->StitchCount = uStitchCnt;
xQueueSendToBack(xEventWithParaQueue, &NewCommand, (TickType_t)0);
}
else
prvErrorReport(vGetExeError());
坐标轴移动距离传给底层
//X、Y轴的移动距离表示
1.Swing.c 跑线或空移过程中
Axis_Write_Reg(&Block.x_instance);
2.Axis_Driver.c
/* 寄存器写入传给底层FPGA */
void Axis_Write_Reg(axis_data_t *this_axis)
{
this_axis->fpga_reg->AXIS_COMMAND.all = this_axis->axis_command.all;
this_axis->fpga_reg->AXIS_FEED_INC.all = this_axis->axis_feed_inc.all;
this_axis->fpga_reg->AXIS_AA_ED_TIME = this_axis->axis_acc_acc_time;
this_axis->fpga_reg->AXIS_DA_ED_TIME = this_axis->axis_dec_acc_time;
this_axis->fpga_reg->AXIS_AD_ST_TIME = this_axis->axis_acc_dec_time;
this_axis->fpga_reg->AXIS_DD_ST_TIME = this_axis->axis_dec_dec_time;
this_axis->fpga_reg->AXIS_ACC_FREQ = this_axis->axis_acc_freq;
this_axis->fpga_reg->AXIS_JERK_FREQ_REG = this_axis->axis_jerk_freq;
this_axis->fpga_reg->AXIS_ACC_DELT = this_axis->axis_acc_delta;
this_axis->fpga_reg->AXIS_SPD_INIT = this_axis->axis_spd_init * TICK_FACTOR;
}
//其中参数axis_feed_inc.all为所发的脉冲数
3.planning_Motion.c
//坐标轴匀速运动规划
void Planning_Uniform_Axis_Motion(
axis_data_t *object, // 坐标轴输出数据
axis_plan *AxplPar // 坐标轴输入数据
)
{
uint32_t direction = (0 ^ AxplPar->dir_polar) & BIT0; // 为默认方向
if (AxplPar->axpl_mm_of_travel < 0.0)// 运动距离和方向
{
AxplPar->axpl_mm_of_travel = -AxplPar->axpl_mm_of_travel;
direction = (~direction) & BIT0; // 反方向
}
object->axis_command.all = AxplPar->axpl_control;
object->axis_jerk_freq = 1;
object->axis_acc_freq = 1;
object->axis_acc_delta = 0;
object->axis_acc_acc_time = 0;
object->axis_dec_acc_time = 0;
object->axis_acc_dec_time = 1000000;
object->axis_dec_dec_time = 1000000;
object->axis_spd_init = (uint32_t)(AxplPar->startup_spd_mm_s * AxplPar->steps_per_mm + 1);
object->axis_feed_inc.all = (uint32_t)(AxplPar->axpl_mm_of_travel * AxplPar->steps_per_mm + 0.5 );
object->axis_feed_inc.bit.AXIS_DIR = direction;
}
//其中object->axis_feed_inc.all = (uint32_t)(AxplPar->axpl_mm_of_travel * AxplPar->steps_per_mm + 0.5 );
//脉冲数 = 移动距离 * 传动比
4.planing_Utils.c
/* XY匀速运动规划 不含加减速 */
void plan_Axis_Uniform_Motion(
axis_block *pxBlock,
double X_travel_mm,
double Y_travel_mm,
double spd_mm_s,
settings *pSettings
)
{
axis_plan sXaxis_Plan; // X轴运动规划参数
axis_plan sYaxis_Plan; // Y轴运动规划参数
/* X轴运动数据计算 */
sXaxis_Plan.axpl_control = AXIS_DEFAULT_COMMAND; // X轴使能
sXaxis_Plan.axpl_mm_of_travel = X_travel_mm;
sXaxis_Plan.axpl_time_of_travel = 0; // 无效
sXaxis_Plan.dir_polar = pSettings->x_direction_polarity;
sXaxis_Plan.steps_per_mm = pSettings->steps_per_mm_for_X;
sXaxis_Plan.startup_spd_mm_s = spd_mm_s * x_mm / (x_mm + y_mm);
Planning_Uniform_Axis_Motion(&pxBlock->x_instance, &sXaxis_Plan);
}
//移动距离为sXaxis_Plan.axpl_mm_of_travel = X_travel_mm;
5.Swing.c
else if (pxBlock->flag == 5) // 不规划 匀速运动
{
x_travel_mm = pxBlock->x_travel_mm;
y_travel_mm = pxBlock->y_travel_mm;
plan_Axis_Uniform_Motion(pxBlock, x_travel_mm, y_travel_mm, pxBlock->speed, &Settings); // 运动规划
}
//pxBlock->x_travel_mm做为实际传进来的移动距离,或为绝对距离或为相对距离