蓝牙音乐乐谱律动彩灯实现-AI

More
2 weeks 5 days ago - 2 weeks 5 days ago #34 by btt
New Topic
SCH:

AI 自动识别的硬件配置
{
  "chip": "CC2540",
  "peripherals": [
    {
      "type": "usb",
      "model": null,
      "pins": {
        "USB_P": "2",
        "USB_N": "3"
      }
    },
    {
      "type": "reset",
      "model": null,
      "pins": {
        "RESET_N": "20"
      }
    },
    {
      "type": "button",
      "model": null,
      "pins": {
        "RESET_N": "20"
      }
    },
    {
      "type": "crystal",
      "model": "32MHZ",
      "pins": {
        "XOSC_QI": "32",
        "XOSC_QO": "33"
      }
    },
    {
      "type": "crystal",
      "model": "32.768KHZ",
      "pins": {
        "XOSC_QI": "22",
        "XOSC_QO": "23"
      }
    },
    {
      "type": "power",
      "model": null,
      "pins": {
        "AVDD1": "27",
        "AVDD2": "28",
        "AVDD3": "29",
        "AVDD4": "30",
        "AVDD5": "21",
        "AVDD6": "31",
        "DVDD_USB": "10",
        "DVDD2_USB": "24"
      }
    },
    {
      "type": "gpio",
      "model": null,
      "pins": {
        "P0_0": "19",
        "P0_1": "18",
        "P0_2": "17",
        "P0_3": "16",
        "P0_4": "15",
        "P0_5": "14",
        "P0_6": "13",
        "P0_7": "12",
        "P1_0": "11",
        "P1_1": "10",
        "P1_2": "9",
        "P1_3": "8",
        "P1_4": "7",
        "P1_5": "6",
        "P1_6": "5",
        "P1_7": "4",
        "P2_0": "3",
        "P2_1": "38",
        "P2_2": "37",
        "P2_3": "36",
        "P2_4": "35",
        "P2_5": "34"
      }
    }
  ]
}

生成固件:
Code:
```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" #include "esp_log.h" #include "esp_system.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_a2dp_types.h" #include "esp_avrc_api.h" #include "driver/i2s.h" #include "driver/gpio.h" static const char *TAG = "A2DP_SINK"; // ---- 硬件配置 (来自JSON, 适配ESP32, 仅用于参考) ---- // 由于芯片为CC2540, 与实际ESP32不同, 此处根据ESP32常见外设调整 // 复位: 默认复位, 未使用外部引脚 // 按钮: 使用GPIO0 (BOOT按钮) 作为控制 #define BUTTON_GPIO GPIO_NUM_0 // 32MHz 晶振: 使用ESP32内部 // 32.768KHz: 使用内部RTC // I2S audio output (使用内置DAC, GPIO25/26) #define I2S_BCK_IO GPIO_NUM_26 #define I2S_WS_IO GPIO_NUM_25 #define I2S_DO_IO GPIO_NUM_27 // 若使用内置DAC, 仅用DO // ---- 音频输出配置 (I2S 或 内部DAC) ---- #define USE_INTERNAL_DAC 1 // 1: 使用ESP32内置DAC (GPIO25,26), 0: 使用外部I2S #if USE_INTERNAL_DAC // 内置DAC: 使用I2S在DAC模式下, 只要GPIO25/26 #define I2S_PORT I2S_NUM_0 #define I2S_MODE (I2S_MODE_DAC_BUILT_IN | I2S_MODE_TX) #define I2S_BITS I2S_BITS_PER_SAMPLE_16BIT #else #define I2S_PORT I2S_NUM_0 #define I2S_MODE I2S_MODE_MASTER | I2S_MODE_TX #define I2S_BITS I2S_BITS_PER_SAMPLE_16BIT #endif // ---- 函数声明 ---- static void a2dp_app_callback(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param); static void a2dp_data_callback(const uint8_t *data, uint32_t len); static void avrc_connection_callback(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param); static void i2s_init(void); static void i2s_write_data(const uint8_t *data, uint32_t len); // ---- 全局变量 ---- static bool bta2d_connected = false; static QueueHandle_t audio_queue; // ---- 主函数 ---- void app_main(void) { esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); bt_cfg.mode = ESP_BT_MODE_CLASSIC_BT; bt_cfg.bluetooth_mode = ESP_BT_MODE_BTDM; // 经典蓝牙模式 // 初始化蓝牙控制器 esp_err_t ret = esp_bt_controller_init(&bt_cfg); if (ret != ESP_OK) { ESP_LOGE(TAG, "Bluetooth controller initialize failed: %s", esp_err_to_name(ret)); return; } ret = esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT); if (ret != ESP_OK) { ESP_LOGE(TAG, "Bluetooth controller enable failed: %s", esp_err_to_name(ret)); return; } // 初始化Bluedroid ret = esp_bluedroid_init(); if (ret != ESP_OK) { ESP_LOGE(TAG, "Bluedroid initialize failed: %s", esp_err_to_name(ret)); return; } ret = esp_bluedroid_enable(); if (ret != ESP_OK) { ESP_LOGE(TAG, "Bluedroid enable failed: %s", esp_err_to_name(ret)); return; } // 设置设备名称 esp_bt_dev_set_device_name("ESP32_A2DP_SINK"); // 初始化 A2DP Sink esp_a2d_register_data_callback(a2dp_data_callback); esp_a2d_register_callback(a2dp_app_callback); esp_a2d_sink_register_data_callback(a2dp_data_callback); // 已注册, 但明确指定 esp_a2d_sink_init(); // 初始化AVRC esp_avrc_ct_register_callback(avrc_connection_callback); esp_avrc_ct_init(); // 创建音频数据队列 audio_queue = xQueueCreate(10, sizeof(audio_data_t)); // 未定义, 改用直接写入 // 初始化I2S i2s_init(); // 初始化按钮GPIO (用于控制) gpio_config_t io_conf = { .pin_bit_mask = (1ULL << BUTTON_GPIO), .mode = GPIO_MODE_INPUT, .pull_up_en = GPIO_PULLUP_ENABLE, .pull_down_en = GPIO_PULLDOWN_DISABLE, .intr_type = GPIO_INTR_DISABLE }; gpio_config(&io_conf); // 开启蓝牙发现 (可被连接) esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); ESP_LOGI(TAG, "A2DP Sink ready. Connect from phone."); // 主循环 while (1) { // 检测按钮 (用于重置或切换) if (gpio_get_level(BUTTON_GPIO) == 0) { vTaskDelay(pdMS_TO_TICKS(200)); // 去抖动 if (gpio_get_level(BUTTON_GPIO) == 0) { ESP_LOGI(TAG, "Button pressed. Disconnect if connected."); if (bta2d_connected) { esp_a2d_sink_disconnect(esp_bt_dev_get_address()); // 简化 } } } vTaskDelay(pdMS_TO_TICKS(100)); } } // ---- A2DP 应用回调 ---- static void a2dp_app_callback(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) { switch (event) { case ESP_A2D_CONNECTION_STATE_EVT: ESP_LOGI(TAG, "A2DP connection state: %d", param->conn_state.state); if (param->conn_state.state == ESP_A2D_CONNECTION_STATE_CONNECTED) { bta2d_connected = true; ESP_LOGI(TAG, "A2DP connected."); } else if (param->conn_state.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) { bta2d_connected = false; ESP_LOGI(TAG, "A2DP disconnected."); } break; case ESP_A2D_AUDIO_STATE_EVT: ESP_LOGI(TAG, "A2DP audio state: %d", param->audio_state.state); break; case ESP_A2D_AUDIO_CFG_EVT: ESP_LOGI(TAG, "A2DP audio config: codec %d", param->audio_cfg.codec_type); break; default: ESP_LOGW(TAG, "A2DP event: %d", event); break; } } // ---- A2DP 音频数据回调 ---- static void a2dp_data_callback(const uint8_t *data, uint32_t len) { // 将音频数据通过I2S输出 i2s_write_data(data, len); } // ---- AVRC 回调 (简化) ---- static void avrc_connection_callback(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param) { switch (event) { case ESP_AVRC_CT_CONNECTION_STATE_EVT: ESP_LOGI(TAG, "AVRC connection state: %d", param->conn_state.connected); break; default: ESP_LOGW(TAG, "AVRC event: %d", event); break; } } // ---- I2S 初始化 ---- static void i2s_init(void) { i2s_config_t i2s_config = { .mode = I2S_MODE, // 根据宏定义 .sample_rate = 44100, .bits_per_sample = I2S_BITS, .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 = false, .tx_desc_auto_clear = true, .fixed_mclk = 0 }; if (USE_INTERNAL_DAC) { // 配置I2S为DAC模式 i2s_config.mode = (i2s_mode_t)(I2S_MODE_DAC_BUILT_IN); i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT; i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL); // 启用DAC输出 (GPIO25和GPIO26) i2s_set_dac_mode(I2S_DAC_CHANNEL_LEFT_EN); // 仅左声道或双声道 // 注: 内置DAC仅支持单声道, 但此处简化使用左声道 } else { // 外部I2S引脚 i2s_pin_config_t pin_config = { .bck_io_num = I2S_BCK_IO, .ws_io_num = I2S_WS_IO, .data_out_num = I2S_DO_IO, .data_in_num = I2S_PIN_NO_CHANGE }; i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL); i2s_set_pin(I2S_PORT, &pin_config); } ESP_LOGI(TAG, "I2S initialized."); } // ---- I2S 数据写入 ---- static void i2s_write_data(const uint8_t *data, uint32_t len) { size_t bytes_written = 0; esp_err_t ret = i2s_write(I2S_PORT, data, len, &bytes_written, portMAX_DELAY); if (ret != ESP_OK) { ESP_LOGE(TAG, "I2S write error: %s", esp_err_to_name(ret)); } // 可添加错误处理: 若写入不完整, 丢弃剩余数据 if (bytes_written < len) { ESP_LOGW(TAG, "I2S underflow, wrote %d out of %d bytes", bytes_written, len); } } ```
Last edit: 2 weeks 5 days ago by btt.

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

Time to create page: 0.196 seconds