唯创知音WTN6040 ESP32 使用RMT外设驱动

前言

前期在唯创知音WTN6040 esp32驱动代码这篇文章中介绍了驱动 WTN6040 的原理及demo,使用的是延时方案,
实际测试后发现这种方式偶尔会延时不精准,导致功能异常,
于是就有了下面这种方式 —— 使用 ESP32 原生的 RMT 外设更精准的控制时间。

部分代码

此方式驱动需要进行编码然后发送,分为4个文件,篇幅会很长,仅放一部分
完整的使用代码:ESP32 RMT WTN6040 Driver

/**
 * @file wtn6040.c
 * @brief wtn6040 driver
 * @author William
 * @version v0.2
*/

#include "wtn6040.h"
#include "bsp_board.h"
#include "driver/rmt_tx.h"
#include "wtn6_encoder.h"

#define RMT_WTN6_RESOLUTION_HZ     1000000 // 1MHz resolution, 1 tick = 1us
#define WTN6040_DATA_IO (GPIO_RMT_AUDIO)

static const char *TAG = "wtn6040";

rmt_channel_handle_t tx_channel = NULL;
rmt_encoder_handle_t wtn6_encoder = NULL;
// this function won't send frames in a loop
rmt_transmit_config_t transmit_config = {
        .loop_count = 0, // no loop
        .flags.eot_level = 1,
};

/**
 * @brief WTN6040一线串口通信底层函数,必须严格按照时序操作
 * @param byte: 一线语音地址或指令,如 00H -> 播放第0段语音
*/
static void wtn6040_1_line(const uint8_t byte)
{
//    ESP_LOGI(TAG, "Write byte is: 0x%02X.", byte);
    ESP_ERROR_CHECK(rmt_transmit(tx_channel, wtn6_encoder, &byte, sizeof(byte), &transmit_config));
}

/**
 * @brief 初始化 wtn6040 一线通数据引脚初始化
*/
esp_err_t wtn6040_init(void)
{
    ESP_LOGI(TAG, "create RMT TX channel");
    rmt_tx_channel_config_t tx_channel_cfg = {
            .clk_src = RMT_CLK_SRC_DEFAULT,
            .resolution_hz = RMT_WTN6_RESOLUTION_HZ,
            .mem_block_symbols = 64, // amount of RMT symbols that the channel can store at a time
            .trans_queue_depth = 1,  // number of transactions that allowed to pending in the background, this example won't queue multiple transactions, so queue depth > 1 is sufficient
            .gpio_num = WTN6040_DATA_IO,
    };
    ESP_ERROR_CHECK(rmt_new_tx_channel(&tx_channel_cfg, &tx_channel));

    ESP_LOGI(TAG, "Install wtn6 encoder");
    wtn6_encoder_config_t encoder_config = {
            .resolution = RMT_WTN6_RESOLUTION_HZ,
    };
    ESP_ERROR_CHECK(rmt_new_wtn6_encoder(&encoder_config, &wtn6_encoder));

    ESP_LOGI(TAG, "enable RMT TX channel");
    ESP_ERROR_CHECK(rmt_enable(tx_channel));

    vTaskDelay(pdMS_TO_TICKS(100));
    ESP_LOGI(TAG, "Initialize wtn6040 rmt peripheral OK.");

    return ESP_OK;
}

/**
 * @brief 播放结束或者待机状态发此命令调节音量,E0H音量最小,EFH音量最大,共16级
 * @param vol: range = 0x00~0x0f
*/
void wtn6040_volume_adjust(uint8_t vol)
{
    uint8_t volume;

    if (vol > 0x0F) {
        ESP_LOGE(TAG, "wtn6040 volume must be 0~15, your input is %d, it`s over range!", vol);
        return;
    }

    volume = 0xE0 + vol;
    wtn6040_1_line(volume);
    ESP_LOGI(TAG, "Set volume level %d.", vol);
}

/**
 * @brief 播放指定音频或停止播放
 * @param index: 16位指令/地址
*/
void wtn6040_audio_set(const uint8_t index)
{
    switch (index)
    {
    case AUDIO_MUTE:
        ESP_LOGI(TAG, "Play AUDIO_MUTE.");
        wtn6040_1_line(AUDIO_MUTE);
        break;
    case AUDIO_WELCOME:
        ESP_LOGI(TAG, "Play AUDIO_WELCOME.");
        wtn6040_1_line(AUDIO_WELCOME);
        break;
    case AUDIO_CLICK:
        ESP_LOGI(TAG, "Play AUDIO_CLICK.");
        wtn6040_1_line(AUDIO_CLICK);
        break;
    case AUDIO_SAFE:
        ESP_LOGI(TAG, "Play AUDIO_SAFE.");
        wtn6040_1_line(AUDIO_SAFE);
        break;
    case AUDIO_DANGER:
        ESP_LOGI(TAG, "Play AUDIO_DANGER.");
        wtn6040_1_line(AUDIO_DANGER);
        wtn6040_1_line(CMD_PLAY_CYCLE);
        break;
    case AUDIO_BYE:
        ESP_LOGI(TAG, "Play AUDIO_BYE.");
        wtn6040_1_line(AUDIO_BYE);
        break;

    default:
        ESP_LOGI(TAG, "Stop play audio.");
        wtn6040_1_line(CMD_PLAY_STOP);
        break;
    }
}

void wtn6040_test(void)
{
    ESP_LOGI(TAG, "Running test code about wtn6040 audio control.");

    wtn6040_1_line(CMD_PLAY_SERIES);
    wtn6040_1_line(AUDIO_DANGER);
    wtn6040_1_line(CMD_PLAY_SERIES);
    wtn6040_1_line(AUDIO_WELCOME);
    wtn6040_1_line(CMD_PLAY_SERIES);
    wtn6040_1_line(AUDIO_BYE);
    wtn6040_1_line(CMD_PLAY_SERIES);
    wtn6040_1_line(AUDIO_SAFE);
    wtn6040_1_line(CMD_PLAY_SERIES);
    wtn6040_1_line(AUDIO_CLICK);
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值