瀏覽代碼

修正wait信号处理逻辑,增加wait信号触发软件消抖。段未发完触发后,段发完立刻进下一段。段发完未触发则等待触发。每一段都走连续段的最后一段的逻辑,有减速阶段

Signed-off-by: hanyongwei <2043702190@qq.com>
master
hanyongwei 1 月之前
父節點
當前提交
9cfefb3501
共有 4 個文件被更改,包括 124 次插入45 次删除
  1. +1
    -1
      plsr/param/plsr_param.h
  2. +11
    -1
      plsr/run_control/plsr_run_control.c
  3. +102
    -34
      plsr/signal_io/plsr_signal_io.c
  4. +10
    -9
      plsr/signal_io/plsr_signal_io.h

+ 1
- 1
plsr/param/plsr_param.h 查看文件

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

typedef enum {
PLSR_WAIT_TIME = 0, /* 发完后等 wait_ms,再跳转 */
PLSR_WAIT_SIGNAL = 1, /* 发完后等 WAIT 口下降沿,再跳转 */
PLSR_WAIT_SIGNAL = 1, /* 发完后等 WAIT 口导通(20ms 消抖),再跳转 */
PLSR_WAIT_ACT = 2, /* 出脉冲满 act_ms 后中途切段并立即跳转 */
PLSR_WAIT_EXT = 3, /* 运行中 EXT 下降沿中途切段并立即跳转 */
PLSR_WAIT_EXT_OR_DONE = 4 /* EXT 沿或脉冲发完,先到先跳转 */


+ 11
- 1
plsr/run_control/plsr_run_control.c 查看文件

@@ -161,13 +161,23 @@ static void PlsrRunControlEnterPostWaitOrNext(void)
}
if (seg->wait_type == PLSR_WAIT_SIGNAL)
{
/*
* 与 WAIT 时间相同:本段已按末段走完(停表),再等条件才 BeginSeg。
* ※2 导通发生在发完之前:发完立刻下一段。
* ※3 发完仍未导通:等到导通(消抖后)才下一段。
* 不在此处清沿/电平,否则会丢掉段中已经导通的状态。
*/
PlsrPulseDriverStop();
s_follow_cont = 0U;
s_pwm_on = 0U;
s_chain_valid = 0U;
s_chain_freq = 0U;
s_cur_freq = 0U;
PlsrSignalIoClearEdges();
if (PlsrSignalIoWaitIsOn() != 0U)
{
PlsrRunControlGotoNextOrFinish(s_cur_seg);
return;
}
s_wait_is_signal = 1U;
s_state = RC_WAIT_COND;
return;


+ 102
- 34
plsr/signal_io/plsr_signal_io.c 查看文件

@@ -1,30 +1,82 @@
/**
* @file plsr_signal_io.c
* @brief X4/X5 EXTI 下降沿 + TIM3 1ms
* @brief WAIT/EXT:EXTI 边沿触发 + TIM3 20ms 消抖确认
*
* 上拉默认高;外部导通拉低为 ON。
* 触发仍走 EXTI(升降沿);抖动会连打中断,只把消抖计时清零。
* TIM3 只在“有待确认沿”时数 20ms,到期再读一次电平,不是平时轮询当主触发。
*/
#include "plsr_signal_io.h"
#include "plsr_param.h"
#include "plsr_run_control.h"
#include "main.h"

/* X4=PB5 → EXTI5;X5=PG12 → EXTI12 */
#define PLSR_X4_PORT GPIOB
#define PLSR_X4_PIN GPIO_PIN_5
#define PLSR_X5_PORT GPIOG
#define PLSR_X5_PIN GPIO_PIN_12

/*
* APB1=42MHz → TIM3CLK=84MHz;PSC=83 ARR=999 → 1kHz 更新
*/
#define PLSR_TIM3_PSC 83U
#define PLSR_TIM3_ARR 999U

#define PLSR_SIGNAL_DEBOUNCE_MS 20U

typedef struct {
volatile uint8_t pending; /* EXTI 置位:等待 20ms 后确认 */
uint8_t wait_ms; /* 距上次沿已过毫秒 */
uint8_t stable_on; /* 消抖后是否导通 */
uint8_t rose; /* 消抖确认的 OFF→ON,读清 */
GPIO_TypeDef *port;
uint16_t pin;
} PlsrDebounce_t;

static volatile uint32_t s_ms;
static volatile uint8_t s_fall_x4;
static volatile uint8_t s_fall_x5;
static PlsrDebounce_t s_db_x4;
static PlsrDebounce_t s_db_x5;

static TIM_HandleTypeDef s_htim3;

static uint8_t PlsrSignalIoPinOnNow(const PlsrDebounce_t *db)
{
return (HAL_GPIO_ReadPin(db->port, db->pin) == GPIO_PIN_RESET) ? 1U : 0U;
}

static void PlsrSignalIoArmDebounce(PlsrDebounce_t *db)
{
db->pending = 1U;
db->wait_ms = 0U;
}

static void PlsrSignalIoDebounceConfirm(PlsrDebounce_t *db)
{
uint8_t on;

if (db->pending == 0U)
{
return;
}

if (db->wait_ms < 0xFFU)
{
db->wait_ms++;
}
if (db->wait_ms < PLSR_SIGNAL_DEBOUNCE_MS)
{
return;
}

on = PlsrSignalIoPinOnNow(db);
db->pending = 0U;
if (db->stable_on != on)
{
if (on != 0U)
{
db->rose = 1U;
}
db->stable_on = on;
}
}

static void PlsrSignalIoGpioExtiInit(void)
{
GPIO_InitTypeDef gpio = {0};
@@ -33,7 +85,7 @@ static void PlsrSignalIoGpioExtiInit(void)
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_SYSCFG_CLK_ENABLE();

gpio.Mode = GPIO_MODE_IT_FALLING;
gpio.Mode = GPIO_MODE_IT_RISING_FALLING;
gpio.Pull = GPIO_PULLUP;
gpio.Speed = GPIO_SPEED_FREQ_LOW;

@@ -69,10 +121,27 @@ static void PlsrSignalIoTim3Init(void)
void PlsrSignalIoInit(void)
{
s_ms = 0U;
s_fall_x4 = 0U;
s_fall_x5 = 0U;

s_db_x4.port = PLSR_X4_PORT;
s_db_x4.pin = PLSR_X4_PIN;
s_db_x4.pending = 0U;
s_db_x4.wait_ms = 0U;
s_db_x4.stable_on = 0U;
s_db_x4.rose = 0U;

s_db_x5.port = PLSR_X5_PORT;
s_db_x5.pin = PLSR_X5_PIN;
s_db_x5.pending = 0U;
s_db_x5.wait_ms = 0U;
s_db_x5.stable_on = 0U;
s_db_x5.rose = 0U;

PlsrSignalIoGpioExtiInit();
PlsrSignalIoTim3Init();

/* 上电已导通时没有沿,补一次确认 */
PlsrSignalIoArmDebounce(&s_db_x4);
PlsrSignalIoArmDebounce(&s_db_x5);
}

uint32_t PlsrSignalIoGetMs(void)
@@ -96,39 +165,37 @@ uint8_t PlsrSignalIoMsReached(uint32_t deadline_ms)

void PlsrSignalIoClearEdges(void)
{
s_fall_x4 = 0U;
s_fall_x5 = 0U;
s_db_x4.rose = 0U;
s_db_x5.rose = 0U;
}

static uint8_t PlsrSignalIoTakePinFalling(uint16_t sel_01)
static PlsrDebounce_t *PlsrSignalIoDbBySel(uint16_t sel_01)
{
if (sel_01 != 0U)
{
if (s_fall_x5 != 0U)
{
s_fall_x5 = 0U;
return 1U;
}
return 0U;
}
if (s_fall_x4 != 0U)
{
s_fall_x4 = 0U;
return 1U;
}
return 0U;
return (sel_01 != 0U) ? &s_db_x5 : &s_db_x4;
}

uint8_t PlsrSignalIoTakeWaitFalling(void)
uint8_t PlsrSignalIoWaitIsOn(void)
{
PlsrCfg_t *cfg = PlsrParamGetCfg();
return PlsrSignalIoTakePinFalling(cfg->wait_x_sel);
return PlsrSignalIoDbBySel(cfg->wait_x_sel)->stable_on;
}

uint8_t PlsrSignalIoTakeWaitFalling(void)
{
return PlsrSignalIoWaitIsOn();
}

uint8_t PlsrSignalIoTakeExtFalling(void)
{
PlsrCfg_t *cfg = PlsrParamGetCfg();
return PlsrSignalIoTakePinFalling(cfg->ext_x_sel);
PlsrDebounce_t *db = PlsrSignalIoDbBySel(cfg->ext_x_sel);

if (db->rose != 0U)
{
db->rose = 0U;
return 1U;
}
return 0U;
}

void PlsrSignalIoOnTim3Irq(void)
@@ -137,7 +204,8 @@ void PlsrSignalIoOnTim3Irq(void)
{
TIM3->SR = (uint32_t)~TIM_SR_UIF;
s_ms++;
/* 升降速:1ms 更新一次输出频率 */
PlsrSignalIoDebounceConfirm(&s_db_x4);
PlsrSignalIoDebounceConfirm(&s_db_x5);
PlsrRunControlOn1ms();
}
}
@@ -147,7 +215,7 @@ void PlsrSignalIoOnExti9_5(void)
if (__HAL_GPIO_EXTI_GET_IT(PLSR_X4_PIN) != 0U)
{
__HAL_GPIO_EXTI_CLEAR_IT(PLSR_X4_PIN);
s_fall_x4 = 1U;
PlsrSignalIoArmDebounce(&s_db_x4);
}
}

@@ -156,6 +224,6 @@ void PlsrSignalIoOnExti15_10(void)
if (__HAL_GPIO_EXTI_GET_IT(PLSR_X5_PIN) != 0U)
{
__HAL_GPIO_EXTI_CLEAR_IT(PLSR_X5_PIN);
s_fall_x5 = 1U;
PlsrSignalIoArmDebounce(&s_db_x5);
}
}

+ 10
- 9
plsr/signal_io/plsr_signal_io.h 查看文件

@@ -1,10 +1,10 @@
/**
* @file plsr_signal_io.h
* @brief 等待/EXT 输入(X4=PB5、X5=PG12 EXTI)+ TIM3 1ms 时基(WAIT/ACT)
* @brief 等待/EXT 输入(X4=PB5、X5=PG12)软件消抖 + TIM3 1ms 时基
*
* 公共参数:wait_x_sel / ext_x_sel:0=X4,1=X5。
* 引脚上拉默认高,外部拉低 → 下降沿触发
* TIM3 仅作毫秒计数,不占用 TIM10/11/13/14
* 上拉默认高,外部导通拉低 = ON
* 边沿由 EXTI 触发;TIM3 仅在有沿之后数 20ms 再读电平确认(消抖)
*/
#ifndef PLSR_SIGNAL_IO_H
#define PLSR_SIGNAL_IO_H
@@ -22,22 +22,23 @@ uint32_t PlsrSignalIoDeadlineFromNow(uint32_t ms);
/** 1=已到或过期(含无符号环绕) */
uint8_t PlsrSignalIoMsReached(uint32_t deadline_ms);

/** 清 X4/X5 下降沿锁存 */
/** 清 WAIT/EXT 的 OFF→ON 锁存(不影响当前消抖电平) */
void PlsrSignalIoClearEdges(void);

/** WAIT 所选口消抖后是否导通 */
uint8_t PlsrSignalIoWaitIsOn(void);

/**
* 取并清除 WAIT 所选口的下降沿(按 cfg->wait_x_sel)
* @return 1=本次取到沿
* WAIT:消抖后已导通则 1(电平,不读清)。
* ※2 段中已导通 → 发完立刻下一段;※3 未导通则一直等。
*/
uint8_t PlsrSignalIoTakeWaitFalling(void);

/**
* 取并清除 EXT 所选口的下降沿(按 cfg->ext_x_sel)
* @return 1=本次取到沿
* EXT:消抖后 OFF→ON,读清。一次按压只切一次段。
*/
uint8_t PlsrSignalIoTakeExtFalling(void);

/* 由 stm32f4xx_it.c 转发 */
void PlsrSignalIoOnTim3Irq(void);
void PlsrSignalIoOnExti9_5(void);
void PlsrSignalIoOnExti15_10(void);


Loading…
取消
儲存