|
|
|
@@ -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); |
|
|
|
} |
|
|
|
} |