#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防抖 } } }