#include #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #include "driver/pwm.h" #include "esp_log.h" #include "esp_system.h" #include "nvs_flash.h" #include "esp_bt.h" #include "esp_gap_ble_api.h" #include "esp_gattc_api.h" #include "esp_gatts_api.h" #include "esp_gatt_common_api.h" #define BUTTON_A_GPIO GPIO_NUM_5 #define BUTTON_B_GPIO GPIO_NUM_6 #define BUTTON_C_GPIO GPIO_NUM_7 #define LED_GPIO GPIO_NUM_16 #define PWM_CHANNEL PWM_CHANNEL_0 #define PWM_FREQ 1000 #define PWM_RES 100 #define GATTS_TAG "GATTS_DEMO" #define GATTS_SERVICE_UUID 0x00FF #define GATTS_CHAR_UUID_LED_ON_OFF 0xFF01 #define GATTS_CHAR_UUID_LED_BRIGHTNESS 0xFF02 #define GATTS_CHAR_UUID_LED_CONTROL 0xFF03 static bool led_on = false; static int led_brightness = 0; // 定义蓝牙服务和特征值UUID static uint16_t gatts_service_uuid = GATTS_SERVICE_UUID; static uint16_t gatts_char_uuid_led_on_off = GATTS_CHAR_UUID_LED_ON_OFF; static uint16_t gatts_char_uuid_led_brightness = GATTS_CHAR_UUID_LED_BRIGHTNESS; static uint16_t gatts_char_uuid_led_control = GATTS_CHAR_UUID_LED_CONTROL; // 定义蓝牙特征值句柄 static uint16_t gatts_handle_table[3]; // 定义解析BLE指令的函数 static void parse_ble_command(uint8_t *value, size_t len) { switch (value[0]) { case 0x01: // LED开关 if (len == 2) { if (value[1] == 0x01) { led_on = true; pwm_set_duty(PWM_CHANNEL, led_brightness); pwm_start(); } else if (value[1] == 0x00) { led_on = false; pwm_stop(); } } break; case 0x02: // 逐级增减LED亮度 if (len == 2) { int delta = (value[1] == 0x01 ? 1 : -1); led_brightness += delta; if (led_brightness < 0) { led_brightness = 0; } else if (led_brightness > PWM_RES) { led_brightness = PWM_RES; } if (led_on) { pwm_set_duty(PWM_CHANNEL, led_brightness); pwm_start(); } } break; case 0x03: // 直接指定LED亮度 if (len == 2) { led_brightness = value[1]; if (led_brightness < 0) { led_brightness = 0; } else if (led_brightness > PWM_RES) { led_brightness = PWM_RES; } if ( led_on) { pwm_set_duty(PWM_CHANNEL, led_brightness); pwm_start(); } } break; default: break; } } // 定义BLE GATT Server回调函数 static esp_gatts_cb_event_t gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param) { switch (event) { case ESP_GATTS_REG_EVT: // 注册GATT服务 esp_err_t create_attr_ret = esp_ble_gatts_create_attr_tab((esp_gatts_attr_db_t *)param->reg.create.handles, gatts_if, 3, 0); if (create_attr_ret != ESP_OK) { ESP_LOGE(GATTS_TAG, "create attr table failed, error code = %x", create_attr_ret); } else { // 保存特征值句柄 memcpy(gatts_handle_table, param->reg.create.handles, sizeof(gatts_handle_table)); } break; case ESP_GATTS_READ_EVT: break; case ESP_GATTS_WRITE_EVT: if (param->write.is_prep) { break; } if (param->write.need_rsp) { esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, NULL); } parse_ble_command(param->write.value, param->write.len); break; default: break; } return ESP_GATT_OK; } // 定义按钮A的中断处理函数 static void IRAM_ATTR button_a_isr_handler(void *arg) { static uint64_t button_a_pressed_time = 0; uint64_t button_a_current_time = esp_timer_get_time(); if (gpio_get_level(BUTTON_A_GPIO) == 0) { button_a_pressed_time = button_a_current_time; } else { if (button_a_current_time - button_a_pressed_time > 500000) { // 长按 led_brightness--; if (led_brightness < 0) { led_brightness = 0; } pwm_set_duty(PWM_CHANNEL, led_brightness); pwm_start(); } else { // 短按 led_brightness++; if (led_brightness > PWM_RES) { led_brightness = PWM_RES; } pwm_set_duty(PWM_CHANNEL, led_brightness); pwm_start(); } } } // 定义按钮B的中断处理函数 static void IRAM_ATTR button_b_isr_handler(void *arg) { static uint64_t button_b_pressed_time = 0; uint64_t button_b_current_time = esp_timer_get_time(); if (gpio_get_level(BUTTON_B_GPIO) == 0) { button_b_pressed_time = button_b_current_time; } else { if (button_b_current_time - button_b_pressed_time > 500000) { // 长按 led_brightness++; if (led_brightness > PWM_RES) { led_brightness = PWM_RES; } pwm_set_duty(PWM_CHANNEL, led_brightness); pwm_start(); } else { // 短按 led_brightness--; if (led_brightness < 0) { led_brightness = 0; } pwm_set_duty(PWM_CHANNEL, led_brightness); pwm_start(); } } } // 定义按钮C的中断处理函数 static void IRAM_ATTR button_c_isr_handler(void *arg) { bool led_on = false; if (gpio_get_level(LED_GPIO) == 0) { led_on = true; } led_on = !led_on; gpio_set_level(LED_GPIO, led_on ? 1 : 0); } void app_main() { // 初始化GPIO gpio_pad_select_gpio(BUTTON_A_GPIO); gpio_pad_select_gpio(BUTTON_B_GPIO); gpio_pad_select_gpio(BUTTON_C_GPIO); gpio_pad_select_gpio(LED_GPIO); gpio_set_direction(BUTTON_A_GPIO, GPIO_MODE_INPUT); gpio_set_direction(BUTTON_B_GPIO, GPIO_MODE_INPUT); gpio_set_direction(BUTTON_C_GPIO, GPIO_MODE_INPUT); gpio_set_direction(LED_GPIO, GPIO_MODE_OUTPUT); gpio_set_level(LED_GPIO, 0); // 初始化PWM pwm_init(PWM_CHANNEL, NULL); pwm_set_freq(PWM_CHANNEL, PWM_FREQ); pwm_set_duty(PWM_CHANNEL, 0); pwm_start(); // 设置按钮A的中断 gpio_set_intr_type(BUTTON_A_GPIO, GPIO_INTR_ANYEDGE); gpio_install_isr_service(0); gpio_isr_handler_add(BUTTON_A_GPIO, button_a_isr_handler, NULL); // 设置按钮B的中断 gpio_set_intr_type(BUTTON_B_GPIO, GPIO_INTR_ANYEDGE); gpio_isr_handler_add(BUTTON_B_GPIO, button_b_isr_handler, NULL); // 设置按钮C的中断 gpio_set_intr_type(BUTTON_C_GPIO, GPIO_INTR_ANYEDGE); gpio_isr_handler_add(BUTTON_C_GPIO, button_c_isr_handler, NULL); // 初始化BLE esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); esp_bt_controller_init(&bt_cfg); esp_bt_controller_enable(ESP_BT_MODE_BTDM); esp_bluedroid_init(); esp_bluedroid_enable(); esp_ble_gatts_register_callback(gatts_event_handler); esp_ble_gatts_app_register(APP_ID); }