Procházet zdrojové kódy

增加动态修改频率功能

dev1
hanyongwei před 1 měsícem
rodič
revize
dacd97c62a
8 změnil soubory, kde provedl 99 přidání a 7 odebrání
  1. +1
    -1
      iar/plsr.dep
  2. +2
    -0
      modbus/modbus_fc.c
  3. +71
    -0
      plsr/command/plsr_command.c
  4. +5
    -0
      plsr/command/plsr_command.h
  5. +1
    -1
      plsr/param/plsr_param.h
  6. +1
    -0
      plsr/path_plan/plsr_path_plan.c
  7. +1
    -1
      plsr/path_plan/plsr_path_plan.h
  8. +17
    -4
      plsr/run_control/plsr_run_control.c

+ 1
- 1
iar/plsr.dep Zobrazit soubor

@@ -2134,7 +2134,7 @@
<inputs> <inputs>
<tool> <tool>
<name>ICCARM</name> <name>ICCARM</name>
<file> 479 198 123 248 102 189 600 470 542 5 1 395 12 6 2 4 13 16 8 597 9 3 0 7 608 135 398 407 409 408 403 402 11 404 405 406 399 394 396 400 397 555 549 534 282 21 543 520 577 560 477 519 528 320 609</file>
<file> 479 198 123 248 102 189 600 470 542 5 1 395 12 6 2 4 13 16 8 597 9 3 0 7 608 135 398 407 409 408 403 402 11 404 405 406 399 394 396 400 397 555 549 534 282 21 543 520 577 560 477 519 528 548 320 609</file>
</tool> </tool>
</inputs> </inputs>
</file> </file>


+ 2
- 0
modbus/modbus_fc.c Zobrazit soubor

@@ -8,6 +8,7 @@
#include "modbus_data.h" #include "modbus_data.h"
#include "modbus_port.h" #include "modbus_port.h"
#include "plsr_param.h" #include "plsr_param.h"
#include "plsr_command.h"
#include <string.h> #include <string.h>


/*应答帧组帧缓冲 */ /*应答帧组帧缓冲 */
@@ -379,6 +380,7 @@ static void WriteMultiRegs(const uint8_t *frame, uint16_t len)
AppendCrcAndSend(g_modbus_tx_buf, 6U); AppendCrcAndSend(g_modbus_tx_buf, 6U);


PlsrParamBlockOnHoldWrite(startAddr, quantity); PlsrParamBlockOnHoldWrite(startAddr, quantity);
PlsrCommandOnSegFreqHoldWrite(startAddr, quantity);
} }


/*============================================================================*/ /*============================================================================*/


+ 71
- 0
plsr/command/plsr_command.c Zobrazit soubor

@@ -9,6 +9,8 @@
#include "modbus_rtu.h" #include "modbus_rtu.h"


static uint16_t s_fault = PLSR_ERR_NONE; static uint16_t s_fault = PLSR_ERR_NONE;
static volatile uint8_t s_live_freq_req;
static volatile uint32_t s_live_freq_hz;


static void PlsrCommandWriteDWord(uint16_t addr, uint32_t value) static void PlsrCommandWriteDWord(uint16_t addr, uint32_t value)
{ {
@@ -45,10 +47,71 @@ uint16_t PlsrCommandGetFault(void)
void PlsrCommandInit(void) void PlsrCommandInit(void)
{ {
WriteHoldReg(PLSR_CTRL_REG, 0U); WriteHoldReg(PLSR_CTRL_REG, 0U);
s_live_freq_req = 0U;
s_live_freq_hz = 0U;
PlsrCommandClearFault(); PlsrCommandClearFault();
PlsrCommandPublishMonitor(); PlsrCommandPublishMonitor();
} }


/**
* 上位机只改当前段频率:地址必须是当前段 FREQ_L,且一次写 2 字。
* 更新 s_seg[].freq_hz,置位由 Poll 调 ChangeFreq。
*/
void PlsrCommandOnSegFreqHoldWrite(uint16_t start_addr, uint16_t quantity)
{
uint16_t cur1;
uint16_t seg0;
uint16_t off;
uint32_t f;
PlsrSeg_t *seg;

if (quantity != 2U)
{
return;
}
if (PlsrIsBusy() == 0U)
{
return;
}
if (start_addr < PLSR_REG_SEG1_BASE)
{
return;
}

off = (uint16_t)(start_addr - PLSR_REG_SEG1_BASE);
if ((off % PLSR_SEG_STRIDE) != PLSR_SEG_OFF_FREQ_L)
{
return;
}
seg0 = (uint16_t)(off / PLSR_SEG_STRIDE);
if (seg0 >= PLSR_SEG_MAX)
{
return;
}

cur1 = PlsrRunControlGetCurSeg();
if ((cur1 < 1U) || ((uint16_t)(cur1 - 1U) != seg0))
{
return;
}

f = (uint32_t)ReadHoldReg(start_addr) |
((uint32_t)ReadHoldReg((uint16_t)(start_addr + 1U)) << 16);
if ((f < 1U) || (f > 100000U))
{
return;
}

seg = PlsrParamGetSeg(seg0);
if (seg != (PlsrSeg_t *)0)
{
seg->freq_hz = (int32_t)f;
}

s_live_freq_hz = f;
s_live_freq_req = 1U;
}

void PlsrCommandPoll(void) void PlsrCommandPoll(void)
{ {
uint16_t ctrl = ReadHoldReg(PLSR_CTRL_REG); uint16_t ctrl = ReadHoldReg(PLSR_CTRL_REG);
@@ -80,5 +143,13 @@ void PlsrCommandPoll(void)
} }
} }


/* 动态改频:标志置位后按新目标重规划剩余脉冲 */
if (s_live_freq_req != 0U)
{
uint32_t f = s_live_freq_hz;
s_live_freq_req = 0U;
(void)PlsrChangeFreq(f);
}

PlsrCommandPublishMonitor(); PlsrCommandPublishMonitor();
} }

+ 5
- 0
plsr/command/plsr_command.h Zobrazit soubor

@@ -33,5 +33,10 @@ void PlsrCommandPoll(void);
void PlsrCommandSetFault(uint16_t code); void PlsrCommandSetFault(uint16_t code);
void PlsrCommandClearFault(void); void PlsrCommandClearFault(void);
uint16_t PlsrCommandGetFault(void); uint16_t PlsrCommandGetFault(void);
/**
* FC10 写段频率双字后调用:仅当地址对应「当前运行段」频率时,
* 更新段表并置标志,由 Poll 调 ChangeFreq。
*/
void PlsrCommandOnSegFreqHoldWrite(uint16_t start_addr, uint16_t quantity);


#endif #endif

+ 1
- 1
plsr/param/plsr_param.h Zobrazit soubor

@@ -77,7 +77,7 @@ typedef enum {


typedef enum { typedef enum {
PLSR_POS_RELATIVE = 0, /* 脉冲数=相对位移 */ PLSR_POS_RELATIVE = 0, /* 脉冲数=相对位移 */
PLSR_POS_ABSOLUTE = 1 /* 脉冲数=绝对坐标 */
PLSR_POS_ABSOLUTE = 1 /* 脉冲数=相对本次启动原点的绝对坐标 */
} PlsrPosMode_e; } PlsrPosMode_e;


typedef enum { typedef enum {


+ 1
- 0
plsr/path_plan/plsr_path_plan.c Zobrazit soubor

@@ -41,6 +41,7 @@ uint8_t PlsrPathPlanIsForward(uint16_t seg_0based, int32_t acc_pulse)


if (cfg->run_mode == PLSR_POS_ABSOLUTE) if (cfg->run_mode == PLSR_POS_ABSOLUTE)
{ {
/* move = 段目标 − 相对本次启动原点的位置 */
move = seg->pulse_cnt - acc_pulse; move = seg->pulse_cnt - acc_pulse;
} }
else else


+ 1
- 1
plsr/path_plan/plsr_path_plan.h Zobrazit soubor

@@ -21,7 +21,7 @@ int16_t PlsrPathPlanNextSeg(uint16_t cur_seg_0based);


/** /**
* @brief 判断该段运动方向 * @brief 判断该段运动方向
* @param acc_pulse 当前累计脉冲(绝对模式算位移用)
* @param acc_pulse 相对本次启动原点的位置(绝对模式算位移用)
* @return 1=正向,0=反向 * @return 1=正向,0=反向
*/ */
uint8_t PlsrPathPlanIsForward(uint16_t seg_0based, int32_t acc_pulse); uint8_t PlsrPathPlanIsForward(uint16_t seg_0based, int32_t acc_pulse);


+ 17
- 4
plsr/run_control/plsr_run_control.c Zobrazit soubor

@@ -49,6 +49,7 @@ static volatile uint32_t s_cur_freq;
static volatile int32_t s_done; static volatile int32_t s_done;
static volatile int32_t s_target; static volatile int32_t s_target;
static volatile int32_t s_acc_pulse; static volatile int32_t s_acc_pulse;
static int32_t s_abs_origin; /* 本次启动时累计作绝对原点 */


static INT32U s_dir_deadline; static INT32U s_dir_deadline;
static uint32_t s_wait_deadline_ms; /* TIM3:段后 WAIT 时间 / ACT※4 剩余 */ static uint32_t s_wait_deadline_ms; /* TIM3:段后 WAIT 时间 / ACT※4 剩余 */
@@ -101,6 +102,7 @@ static uint16_t PlsrRunControlWaitTimeMs(const PlsrSeg_t *seg);
static void PlsrRunControlPlanSeg(uint32_t total, uint32_t f_from, static void PlsrRunControlPlanSeg(uint32_t total, uint32_t f_from,
uint32_t f_tgt, uint32_t f_end, uint32_t f_tgt, uint32_t f_end,
uint16_t accel_ms, uint16_t decel_ms); uint16_t accel_ms, uint16_t decel_ms);
static int32_t PlsrRunControlAbsLocalPos(void);
static uint32_t PlsrRunControlClampSpeed(uint32_t spd); static uint32_t PlsrRunControlClampSpeed(uint32_t spd);
static uint8_t PlsrRunControlGetSegTargetFreq(int32_t freq_hz, static uint8_t PlsrRunControlGetSegTargetFreq(int32_t freq_hz,
uint32_t default_spd, uint32_t default_spd,
@@ -153,7 +155,7 @@ static void PlsrRunControlCutSegToNext(void)
next0 = PlsrPathPlanResolveAfterSeg(s_cur_seg); next0 = PlsrPathPlanResolveAfterSeg(s_cur_seg);
keep = 0U; keep = 0U;
if ((next0 >= 0) && (s_pwm_on != 0U) && (s_cur_freq >= 1U) && if ((next0 >= 0) && (s_pwm_on != 0U) && (s_cur_freq >= 1U) &&
(PlsrPathPlanIsForward((uint16_t)next0, s_acc_pulse) == s_forward))
(PlsrPathPlanIsForward((uint16_t)next0, PlsrRunControlAbsLocalPos()) == s_forward))
{ {
keep = 1U; keep = 1U;
} }
@@ -199,7 +201,7 @@ static void PlsrRunControlActExpire(void)
if ((next0 >= 0) && if ((next0 >= 0) &&
((s_pwm_on != 0U) || (s_act_handoff_keep != 0U)) && ((s_pwm_on != 0U) || (s_act_handoff_keep != 0U)) &&
(s_cur_freq >= 1U) && (s_cur_freq >= 1U) &&
(PlsrPathPlanIsForward((uint16_t)next0, s_acc_pulse) == s_forward))
(PlsrPathPlanIsForward((uint16_t)next0, PlsrRunControlAbsLocalPos()) == s_forward))
{ {
keep = 1U; keep = 1U;
} }
@@ -541,7 +543,7 @@ static uint8_t PlsrRunControlWillFollowKeep(uint16_t cur_seg)
{ {
return 0U; return 0U;
} }
if (PlsrPathPlanIsForward((uint16_t)next0, s_acc_pulse) != s_forward)
if (PlsrPathPlanIsForward((uint16_t)next0, PlsrRunControlAbsLocalPos()) != s_forward)
{ {
return 0U; return 0U;
} }
@@ -674,6 +676,12 @@ static uint32_t PlsrRunControlRemainPulses(void)
return 0U; return 0U;
} }


/** 绝对模式:相对本次启动原点的位置 */
static int32_t PlsrRunControlAbsLocalPos(void)
{
return s_acc_pulse - s_abs_origin;
}

static void PlsrRunControlEnterDecel(uint32_t from_hz, uint32_t remain_pulses) static void PlsrRunControlEnterDecel(uint32_t from_hz, uint32_t remain_pulses)
{ {
PlsrRunControlEnterPhase(PH_DECEL, from_hz); PlsrRunControlEnterPhase(PH_DECEL, from_hz);
@@ -966,7 +974,8 @@ static void PlsrRunControlBeginSeg(uint16_t seg_0)


if (cfg->run_mode == PLSR_POS_ABSOLUTE) if (cfg->run_mode == PLSR_POS_ABSOLUTE)
{ {
move = cnt - s_acc_pulse;
/* 以本次启动时累计为原点:move = 段目标 − 相对原点位置 */
move = cnt - PlsrRunControlAbsLocalPos();
if (move == 0) if (move == 0)
{ {
s_busy = 1U; s_busy = 1U;
@@ -1052,6 +1061,7 @@ void PlsrRunControlInit(void)
s_done = 0; s_done = 0;
s_target = 0; s_target = 0;
s_acc_pulse = 0; s_acc_pulse = 0;
s_abs_origin = 0;
s_follow_cont = 0U; s_follow_cont = 0U;
s_chain_freq = 0U; s_chain_freq = 0U;
s_chain_valid = 0U; s_chain_valid = 0U;
@@ -1096,6 +1106,8 @@ uint8_t PlsrRunControlStart(uint16_t start_seg_1based)
s_chain_valid = 0U; s_chain_valid = 0U;
s_chain_freq = 0U; s_chain_freq = 0U;
s_cur_freq = PlsrRunControlClampSpeed(cfg->start_speed); s_cur_freq = PlsrRunControlClampSpeed(cfg->start_speed);
/* 绝对模式:本次启动瞬间累计作为坐标原点(不清零监控累计) */
s_abs_origin = s_acc_pulse;
PlsrSignalIoClearEdges(); PlsrSignalIoClearEdges();
PlsrRunControlBeginSeg((uint16_t)(start_seg_1based - 1U)); PlsrRunControlBeginSeg((uint16_t)(start_seg_1based - 1U));
return 1U; return 1U;
@@ -1375,6 +1387,7 @@ int32_t PlsrRunControlGetAccPulse(void)
void PlsrRunControlClearAccPulse(void) void PlsrRunControlClearAccPulse(void)
{ {
s_acc_pulse = 0; s_acc_pulse = 0;
s_abs_origin = 0;
} }


uint16_t PlsrRunControlGetCurSeg(void) uint16_t PlsrRunControlGetCurSeg(void)


Načítá se…
Zrušit
Uložit