Quellcode durchsuchen

修复X4/X5未触发被当成已触发,需要在20ms内检测到两次低电平才认为触发,不再用下降沿判断触发

Signed-off-by: hanyongwei <2043702190@qq.com>
master
hanyongwei vor 1 Monat
Ursprung
Commit
bf6f8096bb
5 geänderte Dateien mit 76 neuen und 57 gelöschten Zeilen
  1. +1
    -1
      plsr/param/plsr_param.h
  2. +1
    -1
      plsr/pulse_driver/plsr_pulse_driver.c
  3. +13
    -6
      plsr/run_control/plsr_run_control.c
  4. +54
    -41
      plsr/signal_io/plsr_signal_io.c
  5. +7
    -8
      plsr/signal_io/plsr_signal_io.h

+ 1
- 1
plsr/param/plsr_param.h Datei anzeigen

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


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


+ 1
- 1
plsr/pulse_driver/plsr_pulse_driver.c Datei anzeigen

@@ -80,7 +80,7 @@ void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
__HAL_RCC_GPIOF_CLK_ENABLE(); __HAL_RCC_GPIOF_CLK_ENABLE();


gpio.Mode = GPIO_MODE_AF_PP; gpio.Mode = GPIO_MODE_AF_PP;
gpio.Pull = GPIO_NOPULL;
gpio.Pull = GPIO_PULLDOWN;
gpio.Speed = GPIO_SPEED_FREQ_HIGH; gpio.Speed = GPIO_SPEED_FREQ_HIGH;


if (htim->Instance == TIM10) if (htim->Instance == TIM10)


+ 13
- 6
plsr/run_control/plsr_run_control.c Datei anzeigen

@@ -103,7 +103,15 @@ static void PlsrRunControlArmActExtOnPulseStart(void)
{ {
PlsrSeg_t *seg = PlsrParamGetSeg(s_cur_seg); PlsrSeg_t *seg = PlsrParamGetSeg(s_cur_seg);


PlsrSignalIoClearEdges();
/*
* EXT 中途切段:开跑时丢掉旧沿,避免上一段的 WAIT 沿立刻切段。
* WAIT 信号不在这里清:段中落地的下降沿要留给※2。
*/
if ((seg->wait_type == PLSR_WAIT_EXT) ||
(seg->wait_type == PLSR_WAIT_EXT_OR_DONE))
{
PlsrSignalIoClearEdges();
}
s_act_armed = 0U; s_act_armed = 0U;
if ((seg->wait_type == PLSR_WAIT_ACT) && (seg->act_ms > 0U)) if ((seg->wait_type == PLSR_WAIT_ACT) && (seg->act_ms > 0U))
{ {
@@ -162,10 +170,8 @@ static void PlsrRunControlEnterPostWaitOrNext(void)
if (seg->wait_type == PLSR_WAIT_SIGNAL) if (seg->wait_type == PLSR_WAIT_SIGNAL)
{ {
/* /*
* 与 WAIT 时间相同:本段已按末段走完(停表),再等条件才 BeginSeg。
* ※2 导通发生在发完之前:发完立刻下一段。
* ※3 发完仍未导通:等到导通(消抖后)才下一段。
* 不在此处清沿/电平,否则会丢掉段中已经导通的状态。
* 与 WAIT 时间相同:本段发完停表,再等 EXTI 确认后的下降沿。
* 只认锁存的沿,不读当前电平——口线虚低或脉冲耦合都会误跳下一段。
*/ */
PlsrPulseDriverStop(); PlsrPulseDriverStop();
s_follow_cont = 0U; s_follow_cont = 0U;
@@ -173,7 +179,7 @@ static void PlsrRunControlEnterPostWaitOrNext(void)
s_chain_valid = 0U; s_chain_valid = 0U;
s_chain_freq = 0U; s_chain_freq = 0U;
s_cur_freq = 0U; s_cur_freq = 0U;
if (PlsrSignalIoWaitIsOn() != 0U)
if (PlsrSignalIoTakeWaitFalling() != 0U)
{ {
PlsrRunControlGotoNextOrFinish(s_cur_seg); PlsrRunControlGotoNextOrFinish(s_cur_seg);
return; return;
@@ -885,6 +891,7 @@ 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);
PlsrSignalIoClearEdges();
PlsrRunControlBeginSeg((uint16_t)(start_seg_1based - 1U)); PlsrRunControlBeginSeg((uint16_t)(start_seg_1based - 1U));
return 1U; return 1U;
} }


+ 54
- 41
plsr/signal_io/plsr_signal_io.c Datei anzeigen

@@ -1,10 +1,10 @@
/** /**
* @file plsr_signal_io.c * @file plsr_signal_io.c
* @brief WAIT/EXT:EXTI 边沿触发 + TIM3 20ms 消抖确认
* @brief WAIT/EXT:EXTI 下降沿触发(X4=PB5、X5=PG12)
* *
* 上拉默认高;外部导通拉低为 ON
* 触发仍走 EXTI(升降沿);抖动会连打中断,只把消抖计时清零。
* TIM3 只在“有待确认沿”时数 20ms,到期再读一次电平,不是平时轮询当主触发
* 输入上拉,空闲为高;飞线接地产生下降沿
* 触发只认 EXTI,不靠平时扫口。沿到来后等 20ms 再读一次:
* 仍为低才锁存(消抖,并滤掉 Y0 脉冲耦合出的尖峰)
*/ */
#include "plsr_signal_io.h" #include "plsr_signal_io.h"
#include "plsr_param.h" #include "plsr_param.h"
@@ -22,35 +22,32 @@
#define PLSR_SIGNAL_DEBOUNCE_MS 20U #define PLSR_SIGNAL_DEBOUNCE_MS 20U


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


static volatile uint32_t s_ms; static volatile uint32_t s_ms;
static PlsrDebounce_t s_db_x4;
static PlsrDebounce_t s_db_x5;
static PlsrEdge_t s_db_x4;
static PlsrEdge_t s_db_x5;


static TIM_HandleTypeDef s_htim3; static TIM_HandleTypeDef s_htim3;


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


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


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

if (db->pending == 0U) if (db->pending == 0U)
{ {
return; return;
@@ -65,15 +62,11 @@ static void PlsrSignalIoDebounceConfirm(PlsrDebounce_t *db)
return; return;
} }


on = PlsrSignalIoPinOnNow(db);
db->pending = 0U; db->pending = 0U;
if (db->stable_on != on)
/* 尖峰/耦合在 20ms 后已回到高,不算触发;飞线接地保持为低才算 */
if (PlsrSignalIoPinIsLow(db) != 0U)
{ {
if (on != 0U)
{
db->rose = 1U;
}
db->stable_on = on;
db->fell = 1U;
} }
} }


@@ -85,7 +78,10 @@ static void PlsrSignalIoGpioExtiInit(void)
__HAL_RCC_GPIOG_CLK_ENABLE(); __HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_SYSCFG_CLK_ENABLE(); __HAL_RCC_SYSCFG_CLK_ENABLE();


gpio.Mode = GPIO_MODE_IT_RISING_FALLING;
HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);
HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);

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


@@ -95,6 +91,11 @@ static void PlsrSignalIoGpioExtiInit(void)
gpio.Pin = PLSR_X5_PIN; gpio.Pin = PLSR_X5_PIN;
HAL_GPIO_Init(PLSR_X5_PORT, &gpio); HAL_GPIO_Init(PLSR_X5_PORT, &gpio);


__HAL_GPIO_EXTI_CLEAR_IT(PLSR_X4_PIN);
__HAL_GPIO_EXTI_CLEAR_IT(PLSR_X5_PIN);
NVIC_ClearPendingIRQ(EXTI9_5_IRQn);
NVIC_ClearPendingIRQ(EXTI15_10_IRQn);

HAL_NVIC_SetPriority(EXTI9_5_IRQn, 8, 0); HAL_NVIC_SetPriority(EXTI9_5_IRQn, 8, 0);
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 8, 0); HAL_NVIC_SetPriority(EXTI15_10_IRQn, 8, 0);
@@ -126,22 +127,24 @@ void PlsrSignalIoInit(void)
s_db_x4.pin = PLSR_X4_PIN; s_db_x4.pin = PLSR_X4_PIN;
s_db_x4.pending = 0U; s_db_x4.pending = 0U;
s_db_x4.wait_ms = 0U; s_db_x4.wait_ms = 0U;
s_db_x4.stable_on = 0U;
s_db_x4.rose = 0U;
s_db_x4.fell = 0U;


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


PlsrSignalIoGpioExtiInit(); PlsrSignalIoGpioExtiInit();
PlsrSignalIoTim3Init(); PlsrSignalIoTim3Init();


/* 上电已导通时没有沿,补一次确认 */
PlsrSignalIoArmDebounce(&s_db_x4);
PlsrSignalIoArmDebounce(&s_db_x5);
/* 配置 EXTI 时可能打出假沿,丢掉 */
__HAL_GPIO_EXTI_CLEAR_IT(PLSR_X4_PIN);
__HAL_GPIO_EXTI_CLEAR_IT(PLSR_X5_PIN);
s_db_x4.fell = 0U;
s_db_x4.pending = 0U;
s_db_x5.fell = 0U;
s_db_x5.pending = 0U;
} }


uint32_t PlsrSignalIoGetMs(void) uint32_t PlsrSignalIoGetMs(void)
@@ -165,11 +168,13 @@ uint8_t PlsrSignalIoMsReached(uint32_t deadline_ms)


void PlsrSignalIoClearEdges(void) void PlsrSignalIoClearEdges(void)
{ {
s_db_x4.rose = 0U;
s_db_x5.rose = 0U;
s_db_x4.fell = 0U;
s_db_x4.pending = 0U;
s_db_x5.fell = 0U;
s_db_x5.pending = 0U;
} }


static PlsrDebounce_t *PlsrSignalIoDbBySel(uint16_t sel_01)
static PlsrEdge_t *PlsrSignalIoDbBySel(uint16_t sel_01)
{ {
return (sel_01 != 0U) ? &s_db_x5 : &s_db_x4; return (sel_01 != 0U) ? &s_db_x5 : &s_db_x4;
} }
@@ -177,22 +182,30 @@ static PlsrDebounce_t *PlsrSignalIoDbBySel(uint16_t sel_01)
uint8_t PlsrSignalIoWaitIsOn(void) uint8_t PlsrSignalIoWaitIsOn(void)
{ {
PlsrCfg_t *cfg = PlsrParamGetCfg(); PlsrCfg_t *cfg = PlsrParamGetCfg();
return PlsrSignalIoDbBySel(cfg->wait_x_sel)->stable_on;
return PlsrSignalIoPinIsLow(PlsrSignalIoDbBySel(cfg->wait_x_sel));
} }


uint8_t PlsrSignalIoTakeWaitFalling(void) uint8_t PlsrSignalIoTakeWaitFalling(void)
{ {
return PlsrSignalIoWaitIsOn();
PlsrCfg_t *cfg = PlsrParamGetCfg();
PlsrEdge_t *db = PlsrSignalIoDbBySel(cfg->wait_x_sel);

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


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


if (db->rose != 0U)
if (db->fell != 0U)
{ {
db->rose = 0U;
db->fell = 0U;
return 1U; return 1U;
} }
return 0U; return 0U;
@@ -215,7 +228,7 @@ void PlsrSignalIoOnExti9_5(void)
if (__HAL_GPIO_EXTI_GET_IT(PLSR_X4_PIN) != 0U) if (__HAL_GPIO_EXTI_GET_IT(PLSR_X4_PIN) != 0U)
{ {
__HAL_GPIO_EXTI_CLEAR_IT(PLSR_X4_PIN); __HAL_GPIO_EXTI_CLEAR_IT(PLSR_X4_PIN);
PlsrSignalIoArmDebounce(&s_db_x4);
PlsrSignalIoOnFalling(&s_db_x4);
} }
} }


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

+ 7
- 8
plsr/signal_io/plsr_signal_io.h Datei anzeigen

@@ -1,10 +1,9 @@
/** /**
* @file plsr_signal_io.h * @file plsr_signal_io.h
* @brief 等待/EXT 输入(X4=PB5、X5=PG12)软件消抖 + TIM3 1ms 时基
* @brief 等待/EXT 输入(X4=PB5、X5=PG12)
* *
* 公共参数:wait_x_sel / ext_x_sel:0=X4,1=X5。 * 公共参数:wait_x_sel / ext_x_sel:0=X4,1=X5。
* 上拉默认高,外部导通拉低 = ON。
* 边沿由 EXTI 触发;TIM3 仅在有沿之后数 20ms 再读电平确认(消抖)。
* 上拉空闲为高;飞线接地产生下降沿,由 EXTI 触发(不轮询)。
*/ */
#ifndef PLSR_SIGNAL_IO_H #ifndef PLSR_SIGNAL_IO_H
#define PLSR_SIGNAL_IO_H #define PLSR_SIGNAL_IO_H
@@ -22,20 +21,20 @@ uint32_t PlsrSignalIoDeadlineFromNow(uint32_t ms);
/** 1=已到或过期(含无符号环绕) */ /** 1=已到或过期(含无符号环绕) */
uint8_t PlsrSignalIoMsReached(uint32_t deadline_ms); uint8_t PlsrSignalIoMsReached(uint32_t deadline_ms);


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


/** WAIT 所选口消抖后是否导通 */
/** WAIT 口当前是否为低(已接地)。仅段末判断※2 时读一次,不作周期轮询触发 */
uint8_t PlsrSignalIoWaitIsOn(void); uint8_t PlsrSignalIoWaitIsOn(void);


/** /**
* WAIT:消抖后已导通则 1(电平,不读清)
* ※2 段中已导通 → 发完立刻下一段;※3 未导通则一直等。
* WAIT:消耗一次已确认的 EXTI 下降沿
* ※2 段中飞线接地并保持 → 发完立刻下一段;※3 未触发则一直等。
*/ */
uint8_t PlsrSignalIoTakeWaitFalling(void); uint8_t PlsrSignalIoTakeWaitFalling(void);


/** /**
* EXT:消抖后 OFF→ON,读清。一次按压只切一次段。
* EXT:消耗一次 EXTI 下降沿锁存。一次按压只切一次段。
*/ */
uint8_t PlsrSignalIoTakeExtFalling(void); uint8_t PlsrSignalIoTakeExtFalling(void);




Laden…
Abbrechen
Speichern