Files
hpw421/project/example/ble/ble_peripheral/app/src/switch_s.c
T
2026-06-25 10:32:06 +08:00

256 lines
5.7 KiB
C

#include "switch_s.h"
#include "xc_drv_gpio.h"
#include "xc60xx.h"
#include "RF433.h"
#include "pwm.h"
// ==================== GPIO1 检测 ====================
uint8_t trig1_cnt = 0; // 连续触发次数
uint16_t trig1_timeout = 0; // 300ms 倒计时
uint8_t trig1_wait = 0; // 0=空闲 1=连续出触发
// ==================== GPIO19 检测 ====================
uint8_t trig2_cnt = 0; // 连续触发次数
uint16_t trig2_timeout = 0; // 300ms 倒计时
uint8_t trig2_wait = 0; // 0=空闲 1=连续出触发
uint8_t rf433_sw_flag=0; //进入对码标志
static volatile debounce_state_t s1_state = DB_IDLE;
static volatile debounce_state_t s2_state = DB_IDLE;
static volatile uint16_t s1_debounce_cnt = 0;
static volatile uint16_t s2_debounce_cnt = 0;
#define DEBOUNCE_MS 2 //消抖时间40ms
//uint16_t switch1_debounce = 0;
//uint16_t switch2_debounce = 0;
uint8_t switch1_RELEASE_flag=0;
uint8_t switch2_RELEASE_flag=0;
uint8_t s1_first_press_flag = 0; //S2首次按下标志
uint8_t s2_first_press_flag = 0; //S2首次按下标志
uint8_t S1_first_on_state=0; //上电时开关的状态
void switch_init(void)
{
GPIO_InitCfg_t GPIO_InitCfg = { 0 }; // 清零初始化配置结构体
GPIO_InitCfg.Mux = GPIO_Mux0; // 选择功能复用器0
GPIO_InitCfg.FunSel = GPIO_Dx; // 选择GPIO功能(非特殊功能)
GPIO_InitCfg.Pull = GPIO_PULLUP; //上拉电阻使能
GPIO_InitCfg.Dir = GPIO_DIR_INPUT; // 输出方向
GPIO_InitCfg.Int = FAIL_EDGE_INT; //使能中断
GPIO_InitCfg.Pin = SWITCH_S1_PIN; // 设置S1引脚
xc_gpio_init(&GPIO_InitCfg); // 初始化GPIO
xc_gpio_it_config(GPIO_1,FAIL_EDGE_INT);
NVIC_EnableIRQ(GPIO_IRQn);
if(xc_gpio_read_pin(SWITCH_S1_PIN)==0)
{
S1_first_on_state=1;
}
else
{
S1_first_on_state=0;
}
}
void trigger_check_process(void)
{
if(S1_first_on_state==1)
{
S1_first_on_state=0;
s1_first_press_flag=1;
s1_state=DB_PRESSED;
}
switch(s1_state)
{
case DB_IDLE: //空闲状态
break;
case DB_PRESS_DEBOUNCE: //按下防抖
if(s1_debounce_cnt>0) s1_debounce_cnt--;
if(s1_debounce_cnt==0)
{
//防抖时间到,采样当前电平是否是低电平
if(xc_gpio_read_pin(SWITCH_S1_PIN)==0)
{
s1_state = DB_PRESSED; //进入按下状态,不响应中断
if(trig1_wait == 0)
{
trig1_cnt = 1;
trig1_timeout = TRIGGER_TIMEOUT_MS;
trig1_wait = 1;
}
else
{
if(trig1_timeout>0)
{
trig1_cnt++;
}
trig1_timeout = TRIGGER_TIMEOUT_MS;
//
}
}
else
{
// 杂波导致误触,回到空闲
s1_state = DB_IDLE;
}
}
break;
case DB_PRESSED: //确认按下
// 等待引脚回高电平
if(xc_gpio_read_pin(SWITCH_S1_PIN) == 1)
{
s1_state = DB_RELEASE_DEBOUNCE;
s1_debounce_cnt = DEBOUNCE_MS; // 释放30ms防抖
}
break;
case DB_RELEASE_DEBOUNCE: //释放防抖
if(s1_debounce_cnt > 0) s1_debounce_cnt--;
if(s1_debounce_cnt == 0)
{
if(xc_gpio_read_pin(SWITCH_S1_PIN) == 1) // 确认释放
{
s1_state = DB_IDLE; // 回到空闲
trig1_timeout = TRIGGER_TIMEOUT_MS;
switch1_RELEASE_flag=1;
if(s1_first_press_flag==1)
{
s1_first_press_flag=2;
}
}
else
{
// 再等20ms
s1_debounce_cnt = DEBOUNCE_MS; // 30ms
}
}
break;
}
// S1 超时处理
if(trig1_timeout > 0)
{
trig1_timeout--;
}
else if(trig1_timeout==0 && switch1_RELEASE_flag==1 )
{
switch1_RELEASE_flag=2;
}
// 600ms倒计时结束,且有计数
if(trig1_timeout == 0 && trig1_cnt == 1 && trig1_wait == 1 && s1_state == DB_PRESSED) //确定按下1次
{
//printf("按下一次 trig1_cnt %d\r\n",trig1_cnt);
trig1_cnt = 0;
trig1_wait = 0;
s1_first_press_flag=1;
xc_gpio_write_pin(GPIO_5,GPIO_PIN_SET);
flash_ch1_state=xc_gpio_read_pin(GPIO_5);
set_TaskComps_timer(6,1000);
}
else if(trig1_timeout == 0 && (trig1_cnt > 1 && trig1_cnt < TRIGGER_CONTINUE_CNT))
{
// printf("乱按 trig1_cnt %d\r\n",trig1_cnt);
trig1_cnt = 0;
trig1_wait = 0;
}
else if(trig1_timeout == 0 && trig1_cnt >= TRIGGER_CONTINUE_CNT)
{
//printf("对码 trig1_cnt %d\r\n",trig1_cnt);
if( s1_state == DB_IDLE)
{
rf433_sw_flag = 1;
trig1_cnt = 0;
trig1_wait = 0;
}
else
{
trig1_cnt = 0;
trig1_wait = 0;
}
}
else if(trig1_timeout == 0 && switch1_RELEASE_flag==2 && s1_state == DB_IDLE && s1_first_press_flag==2 )
{
// printf("低电平 trig2_cnt %d\r\n",trig2_cnt);
s1_state = DB_IDLE;
switch1_RELEASE_flag=0;
s1_first_press_flag=0;
xc_gpio_write_pin(GPIO_5,GPIO_PIN_RESET);
flash_ch1_state=xc_gpio_read_pin(GPIO_5);
set_TaskComps_timer(6,1000);
}
}
void gpio_intr_callback(uint64_t intr_sta)
{
if((intr_sta & ((uint64_t)1 << SWITCH_S1_PIN)) != 0) //如果是GPIO_1的中断
{
if(s1_state == DB_IDLE) // 只有空闲才响应
{
s1_state = DB_PRESS_DEBOUNCE;
s1_debounce_cnt = DEBOUNCE_MS; // 40ms防抖
}
}
}