[固件生成] 【硬件配置 (JSON)】{ "chip": "CC2540", "peripherals": [ { "type": "audio_amp", "model

More
3 weeks 1 day ago #41 by btt
New Topic
硬件配置(JSON格式):
Code:
【硬件配置 (JSON)】 { "chip": "CC2540", "peripherals": [ { "type": "audio_amp", "model": null, "pins": { "bclk": "P2_4", "lrc": "P2_5", "din": "P2_6" } }, { "type": "microphone", "model": null, "pins": { "bclk": "P2_4", "ws": "P2_5", "data": "P2_6" } }, { "type": "button", "model": null, "pins": { "signal_name": "JP1-1" } }, { "type": "led", "model": null, "pins": { "signal_name": "JP1-2" } } ] }

生成的固件代码:
Code:
```c #include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "driver/gpio.h" #include "driver/i2s.h" #include "esp_bt.h" #include "esp_bt_main.h" #include "esp_bt_device.h" #include "esp_gap_bt_api.h" #include "esp_a2dp_api.h" #include "esp_avrc_api.h" // 根据JSON硬件配置调整引脚 #define I2S_BCLK_GPIO GPIO_NUM_26 #define I2S_LRC_GPIO GPIO_NUM_25 #define I2S_DIN_GPIO GPIO_NUM_33 #define BUTTON_GPIO GPIO_NUM_4 #define LED_GPIO GPIO_NUM_2 #define I2S_SAMPLE_RATE 44100 #define I2S_CHANNEL_NUM 2 #define I2S_BITS_PER_SAMPLE I2S_BITS_PER_SAMPLE_16BIT // 蓝牙A2DP回调函数声明 static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param); static void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len); static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param); static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param); // 初始化I2S static void i2s_init(void) { i2s_config_t i2s_config = { .mode = I2S_MODE_MASTER | I2S_MODE_TX, .sample_rate = I2S_SAMPLE_RATE, .bits_per_sample = I2S_BITS_PER_SAMPLE, .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, .communication_format = I2S_COMM_FORMAT_STAND_I2S, .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, .dma_buf_count = 8, .dma_buf_len = 64, .use_apll = true, .tx_desc_auto_clear = true, .fixed_mclk = 0 }; i2s_pin_config_t pin_config = { .bck_io_num = I2S_BCLK_GPIO, .ws_io_num = I2S_LRC_GPIO, .data_out_num = I2S_DIN_GPIO, .data_in_num = I2S_PIN_NO_CHANGE }; i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL); i2s_set_pin(I2S_NUM_0, &pin_config); i2s_zero_dma_buffer(I2S_NUM_0); } // 初始化GPIO static void gpio_init(void) { gpio_config_t io_conf = {0}; // 按钮输入,上拉 io_conf.intr_type = GPIO_INTR_ANYEDGE; io_conf.mode = GPIO_MODE_INPUT; io_conf.pin_bit_mask = (1ULL << BUTTON_GPIO); io_conf.pull_up_en = GPIO_PULLUP_ENABLE; io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; gpio_config(&io_conf); // LED输出 io_conf.intr_type = GPIO_INTR_DISABLE; io_conf.mode = GPIO_MODE_OUTPUT; io_conf.pin_bit_mask = (1ULL << LED_GPIO); io_conf.pull_up_en = GPIO_PULLUP_DISABLE; io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; gpio_config(&io_conf); gpio_set_level(LED_GPIO, 0); } // 蓝牙初始化 static void bt_init(void) { esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); esp_err_t ret = esp_bt_controller_init(&bt_cfg); if (ret != ESP_OK) { ESP_LOGE("BT", "BT controller init failed: %s", esp_err_to_name(ret)); return; } ret = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT); if (ret != ESP_OK) { ESP_LOGE("BT", "BT controller enable failed: %s", esp_err_to_name(ret)); return; } ret = esp_bluedroid_init(); if (ret != ESP_OK) { ESP_LOGE("BT", "Bluedroid init failed: %s", esp_err_to_name(ret)); return; } ret = esp_bluedroid_enable(); if (ret != ESP_OK) { ESP_LOGE("BT", "Bluedroid enable failed: %s", esp_err_to_name(ret)); return; } // 注册回调 esp_bt_gap_register_callback(bt_app_gap_cb); esp_a2d_register_callback(bt_app_a2d_cb); esp_a2d_sink_register_data_callback(bt_app_a2d_data_cb); esp_avrc_ct_register_callback(bt_app_rc_ct_cb); // 设置设备名称 esp_bt_dev_set_device_name("ESP32_A2DP_SINK"); esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); } // 主任务 static void main_task(void *arg) { int btn_state = 1; // 假设默认高电平(上拉) int led_state = 0; while (1) { int new_btn = gpio_get_level(BUTTON_GPIO); if (new_btn != btn_state) { vTaskDelay(pdMS_TO_TICKS(20)); // 消抖 new_btn = gpio_get_level(BUTTON_GPIO); if (new_btn != btn_state) { btn_state = new_btn; if (btn_state == 0) { // 按下 led_state = !led_state; gpio_set_level(LED_GPIO, led_state); // 可添加其他功能,例如断开/重连 } } } vTaskDelay(pdMS_TO_TICKS(10)); } } void app_main(void) { esp_log_level_set("*", ESP_LOG_VERBOSE); i2s_init(); gpio_init(); bt_init(); xTaskCreate(main_task, "main_task", 4096, NULL, 5, NULL); } // ---------------------- 蓝牙回调实现 ---------------------- static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *param) { switch (event) { case ESP_BT_GAP_AUTH_CMPL_EVT: if (param->auth_cmpl.stat == ESP_BT_STATUS_SUCCESS) { ESP_LOGI("GAP", "Authentication success: %s", param->auth_cmpl.device_name); } else { ESP_LOGE("GAP", "Authentication failed, status: %d", param->auth_cmpl.stat); } break; case ESP_BT_GAP_PIN_REQ_EVT: // 简单配对 esp_bt_pin_code_t pin_code = {0}; pin_code[0] = '1'; pin_code[1] = '2'; pin_code[2] = '3'; pin_code[3] = '4'; esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code); break; default: break; } } static void bt_app_a2d_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) { switch (event) { case ESP_A2D_CONNECTION_STATE_EVT: { esp_a2d_connection_state_t state = param->conn_stat.state; ESP_LOGI("A2DP", "Connection state: %d", state); if (state == ESP_A2D_CONNECTION_STATE_CONNECTED) { gpio_set_level(LED_GPIO, 1); // 连接时LED亮 } else if (state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) { gpio_set_level(LED_GPIO, 0); i2s_zero_dma_buffer(I2S_NUM_0); } break; } case ESP_A2D_AUDIO_STATE_EVT: { ESP_LOGI("A2DP", "Audio state: %d", param->audio_stat.state); break; } case ESP_A2D_PROF_STATE_EVT: { if (param->prof_stat.init_state == ESP_A2D_INIT_SUCCESS) { ESP_LOGI("A2DP", "A2DP init ok"); } else { ESP_LOGE("A2DP", "A2DP init failed"); } break; } default: break; } } static void bt_app_a2d_data_cb(const uint8_t *data, uint32_t len) { // 将音频数据写入I2S size_t i2s_bytes_written = 0; i2s_write(I2S_NUM_0, data, len, &i2s_bytes_written, portMAX_DELAY); if (i2s_bytes_written < len) { ESP_LOGW("A2DP", "I2S write underflow, written %d / %d", i2s_bytes_written, len); } } static void bt_app_rc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param) { // 可处理AVRCP命令(如播放/暂停),目前只做日志 ESP_LOGD("AVRCP", "Event: %d", event); } ```

点击这里使用固件生成器

Please Log in or Create an account to join the conversation.

More
3 weeks 1 day ago - 3 weeks 1 day ago #42 by btt
Last edit: 3 weeks 1 day ago by btt.

Please Log in or Create an account to join the conversation.

Time to create page: 0.217 seconds