|
|
|
@@ -1,10 +1,10 @@ |
|
|
|
/** |
|
|
|
* @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_param.h" |
|
|
|
@@ -22,35 +22,32 @@ |
|
|
|
#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,读清 */ |
|
|
|
volatile uint8_t pending; /* EXTI 下降沿,待 20ms 确认 */ |
|
|
|
volatile uint8_t wait_ms; |
|
|
|
volatile uint8_t fell; /* 确认后的下降沿,读清 */ |
|
|
|
GPIO_TypeDef *port; |
|
|
|
uint16_t pin; |
|
|
|
} PlsrDebounce_t; |
|
|
|
} PlsrEdge_t; |
|
|
|
|
|
|
|
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 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; |
|
|
|
} |
|
|
|
|
|
|
|
static void PlsrSignalIoArmDebounce(PlsrDebounce_t *db) |
|
|
|
static void PlsrSignalIoOnFalling(PlsrEdge_t *db) |
|
|
|
{ |
|
|
|
db->pending = 1U; |
|
|
|
db->wait_ms = 0U; |
|
|
|
} |
|
|
|
|
|
|
|
static void PlsrSignalIoDebounceConfirm(PlsrDebounce_t *db) |
|
|
|
static void PlsrSignalIoDebounceConfirm(PlsrEdge_t *db) |
|
|
|
{ |
|
|
|
uint8_t on; |
|
|
|
|
|
|
|
if (db->pending == 0U) |
|
|
|
{ |
|
|
|
return; |
|
|
|
@@ -65,15 +62,11 @@ static void PlsrSignalIoDebounceConfirm(PlsrDebounce_t *db) |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
on = PlsrSignalIoPinOnNow(db); |
|
|
|
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_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.Speed = GPIO_SPEED_FREQ_LOW; |
|
|
|
|
|
|
|
@@ -95,6 +91,11 @@ static void PlsrSignalIoGpioExtiInit(void) |
|
|
|
gpio.Pin = PLSR_X5_PIN; |
|
|
|
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_EnableIRQ(EXTI9_5_IRQn); |
|
|
|
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.pending = 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.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; |
|
|
|
s_db_x5.fell = 0U; |
|
|
|
|
|
|
|
PlsrSignalIoGpioExtiInit(); |
|
|
|
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) |
|
|
|
@@ -165,11 +168,13 @@ uint8_t PlsrSignalIoMsReached(uint32_t deadline_ms) |
|
|
|
|
|
|
|
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; |
|
|
|
} |
|
|
|
@@ -177,22 +182,30 @@ static PlsrDebounce_t *PlsrSignalIoDbBySel(uint16_t sel_01) |
|
|
|
uint8_t PlsrSignalIoWaitIsOn(void) |
|
|
|
{ |
|
|
|
PlsrCfg_t *cfg = PlsrParamGetCfg(); |
|
|
|
return PlsrSignalIoDbBySel(cfg->wait_x_sel)->stable_on; |
|
|
|
return PlsrSignalIoPinIsLow(PlsrSignalIoDbBySel(cfg->wait_x_sel)); |
|
|
|
} |
|
|
|
|
|
|
|
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) |
|
|
|
{ |
|
|
|
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 0U; |
|
|
|
@@ -215,7 +228,7 @@ void PlsrSignalIoOnExti9_5(void) |
|
|
|
if (__HAL_GPIO_EXTI_GET_IT(PLSR_X4_PIN) != 0U) |
|
|
|
{ |
|
|
|
__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) |
|
|
|
{ |
|
|
|
__HAL_GPIO_EXTI_CLEAR_IT(PLSR_X5_PIN); |
|
|
|
PlsrSignalIoArmDebounce(&s_db_x5); |
|
|
|
PlsrSignalIoOnFalling(&s_db_x5); |
|
|
|
} |
|
|
|
} |