#define KEY1_PIN 4 // 红色:上升沿触发
#define KEY2_PIN 11 // 绿色:下降沿触发
#define KEY3_PIN 2 // 蓝色:跳变沿触发
#define KEY4_PIN 35 // 黄色:低电平触发
#define KEY5_PIN 19 // 黑色:退出
#define RISING_EVENT 1
#define FALLING_EVENT 2
#define CHANGE_EVENT 4
#define LOW_EVENT 8
#define CLEAR_EVENT 16
#define ALL_EVENT 31 //RISING_EVENT | FALLING_EVENT | CHANGE_EVENT | LOW_EVENT | CLEAR_EVENT
TaskHandle_t xKeyHandler = NULL; // 按键驱动任务句柄
// 上升沿触发中断服务函数
void IRAM_ATTR ISR_RISING(){
xTaskNotifyFromISR(xKeyHandler, RISING_EVENT, eSetBits, NULL);
}
// 下降沿触发中断服务函数
void IRAM_ATTR ISR_FALLING(){
xTaskNotifyFromISR(xKeyHandler, FALLING_EVENT, eSetBits, NULL);
}
// 跳变沿触发中断服务函数
void IRAM_ATTR ISR_CHANGE(){
xTaskNotifyFromISR(xKeyHandler, CHANGE_EVENT, eSetBits, NULL);
}
// 低电平触发中断服务函数
void IRAM_ATTR ISR_LOW(){
xTaskNotifyFromISR(xKeyHandler, LOW_EVENT, eSetBits, NULL);
}
// 下降沿触发,删除所有中断
void IRAM_ATTR ISR_CLEAN(){
xTaskNotifyFromISR(xKeyHandler, CLEAR_EVENT, eSetBits, NULL);
}
// 键盘驱动线程
void key_driver_entry(void *params){
pinMode(KEY1_PIN, INPUT_PULLDOWN); // 上升沿触发,所以必须下拉
pinMode(KEY2_PIN, INPUT_PULLUP); // 下降沿触发,所以必须上拉
pinMode(KEY3_PIN, INPUT); // 跳变沿触发,用哪种拉无所谓
pinMode(KEY4_PIN, INPUT_PULLUP); // 低电平触发,所以必须上拉
pinMode(KEY5_PIN, INPUT_PULLUP); // 下降沿触发,电阻上拉
// 安装中断
attachInterrupt(KEY1_PIN, ISR_RISING, RISING);
attachInterrupt(KEY2_PIN, ISR_FALLING, FALLING);
attachInterrupt(KEY3_PIN, ISR_CHANGE, CHANGE);
attachInterrupt(KEY4_PIN, ISR_LOW, LOW);
attachInterrupt(KEY5_PIN, ISR_CLEAN, FALLING);
// 初始化按键情况
printf("红色按键情况:%d\n", digitalRead(KEY1_PIN));
printf("绿色按键情况:%d\n", digitalRead(KEY2_PIN));
printf("蓝色按键情况:%d\n", digitalRead(KEY3_PIN));
printf("黄色按键情况:%d\n", digitalRead(KEY4_PIN));
uint32_t events = 0;
while(1){
// 接收任务通知前,先清空所有位,接收后也清空所有位
if (xTaskNotifyWait(UINT32_MAX, UINT32_MAX, &events, portMAX_DELAY) == pdTRUE){
if(events>0){
// 当收到任务通知后,等待10ms,如果该按键在查看电平状态,则表示真的触发了,真机中可以调整这个值达到去抖目的
delay(50);
if((events & RISING_EVENT) > 0){
// 上升沿按键可能被触发
if(digitalRead(KEY1_PIN)==HIGH){
printf("您按下了红色按键!\n");
}
}else if((events & FALLING_EVENT) > 0){
if(digitalRead(KEY2_PIN)==LOW){
printf("您按下了绿色按键!\n");
}
}else if((events & CHANGE_EVENT) > 0){
printf("您按下了蓝色按键!\n");
}else if((events & LOW_EVENT) > 0){
if(digitalRead(KEY4_PIN)==LOW){
printf("黄色按键被按下!\n");
}
}else if((events & CLEAR_EVENT) > 0){
if(digitalRead(KEY5_PIN)==LOW){
printf("终结所有按键中断!\n");
//卸载中断
detachInterrupt(KEY1_PIN);
detachInterrupt(KEY2_PIN);
detachInterrupt(KEY3_PIN);
detachInterrupt(KEY4_PIN);
detachInterrupt(KEY5_PIN);
}
}
}
xTaskNotifyStateClear(NULL); // 清空所有状态
}
events = 0;
delay(1);
}
vTaskDelete(NULL);
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial.println("Hello, ESP32-S3!");
xTaskCreate(key_driver_entry, "KD", 10240, NULL, 1, &xKeyHandler);
vTaskDelete(NULL);
}
void loop() {
}
esp:0
esp:1
esp:2
esp:3
esp:4
esp:5
esp:6
esp:7
esp:8
esp:9
esp:10
esp:11
esp:12
esp:13
esp:14
esp:15
esp:16
esp:17
esp:18
esp:19
esp:20
esp:21
esp:35
esp:36
esp:37
esp:38
esp:39
esp:40
esp:41
esp:42
esp:45
esp:46
esp:47
esp:48
esp:3V3.1
esp:3V3.2
esp:RST
esp:5V
esp:GND.1
esp:GND.2
esp:TX
esp:RX
esp:GND.3
esp:GND.4
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
btn2:1.l
btn2:2.l
btn2:1.r
btn2:2.r
btn3:1.l
btn3:2.l
btn3:1.r
btn3:2.r
btn4:1.l
btn4:2.l
btn4:1.r
btn4:2.r
btn5:1.l
btn5:2.l
btn5:1.r
btn5:2.r