Simulator_Test/main/dac_continuous_example_timer.c

110 lines
4.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: CC0-1.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
#include "driver/gptimer.h"
#include "driver/dac_oneshot.h"
#include "esp_log.h"
#include "dac_continuous_example.h"
#define EXAMPLE_TIMER_RESOLUTION 1000000 // 1MHz1个tick = 1us
#define EXAMPLE_WAVE_FREQ_HZ 50 // 默认波形频率50Hz不能太高
#define EXAMPLE_CONVERT_FREQ_HZ (EXAMPLE_ARRAY_LEN * EXAMPLE_WAVE_FREQ_HZ) // DAC转换波形数组中每个数据的频率
#define EXAMPLE_TIMER_ALARM_COUNT (EXAMPLE_TIMER_RESOLUTION / EXAMPLE_CONVERT_FREQ_HZ) // 触发定时器报警回调的计数值
static const char *TAG = "dac continuous(timer)";
static const char wav_name[DAC_WAVE_MAX][15] = {"sine", "triangle", "sawtooth", "square"};
static dac_oneshot_handle_t chan0_handle;
static dac_oneshot_handle_t chan1_handle;
extern uint8_t sin_wav[EXAMPLE_ARRAY_LEN]; // 用于存储正弦波值
extern uint8_t tri_wav[EXAMPLE_ARRAY_LEN]; // 用于存储三角波值
extern uint8_t saw_wav[EXAMPLE_ARRAY_LEN]; // 用于存储锯齿波值
extern uint8_t squ_wav[EXAMPLE_ARRAY_LEN]; // 用于存储方波值
/* 定时器中断服务例程 */
static bool IRAM_ATTR on_timer_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
{
static uint32_t point_cnt = 0; // 用于计算一个波形的输出点数
static uint32_t index = 0; // 波形缓冲区的当前索引
static dac_example_wave_type_t wav_sel = DAC_SINE_WAVE; // 从正弦波开始
// 每CONFIG_EXAMPLE_WAVE_PERIOD_SEC秒切换波形
if (point_cnt < EXAMPLE_CONVERT_FREQ_HZ * CONFIG_EXAMPLE_WAVE_PERIOD_SEC) {
switch (wav_sel) {
case DAC_SINE_WAVE:
ESP_ERROR_CHECK(dac_oneshot_output_voltage(chan0_handle, sin_wav[index]));
ESP_ERROR_CHECK(dac_oneshot_output_voltage(chan1_handle, sin_wav[index]));
break;
case DAC_TRIANGLE_WAVE:
ESP_ERROR_CHECK(dac_oneshot_output_voltage(chan0_handle, tri_wav[index]));
ESP_ERROR_CHECK(dac_oneshot_output_voltage(chan1_handle, tri_wav[index]));
break;
case DAC_SAWTOOTH_WAVE:
ESP_ERROR_CHECK(dac_oneshot_output_voltage(chan0_handle, saw_wav[index]));
ESP_ERROR_CHECK(dac_oneshot_output_voltage(chan1_handle, saw_wav[index]));
break;
case DAC_SQUARE_WAVE:
ESP_ERROR_CHECK(dac_oneshot_output_voltage(chan0_handle, squ_wav[index]));
ESP_ERROR_CHECK(dac_oneshot_output_voltage(chan1_handle, squ_wav[index]));
break;
default:
break;
}
point_cnt++;
index++;
index %= EXAMPLE_ARRAY_LEN;
} else {
wav_sel++;
wav_sel %= DAC_WAVE_MAX;
point_cnt = 0;
index = 0;
ESP_EARLY_LOGI(TAG, "%s wave start", wav_name[wav_sel]);
}
return false;
}
void example_dac_continuous_by_timer(void)
{
gptimer_handle_t gptimer = NULL;
gptimer_config_t timer_config = {
.clk_src = GPTIMER_CLK_SRC_DEFAULT,
.direction = GPTIMER_COUNT_UP,
.resolution_hz = EXAMPLE_TIMER_RESOLUTION, // 1MHz1个tick = 1us
};
ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer));
dac_oneshot_config_t dac0_cfg = {
.chan_id = DAC_CHAN_0,
};
ESP_ERROR_CHECK(dac_oneshot_new_channel(&dac0_cfg, &chan0_handle));
dac_oneshot_config_t dac1_cfg = {
.chan_id = DAC_CHAN_1,
};
ESP_ERROR_CHECK(dac_oneshot_new_channel(&dac1_cfg, &chan1_handle));
example_log_info(EXAMPLE_CONVERT_FREQ_HZ, EXAMPLE_WAVE_FREQ_HZ);
gptimer_alarm_config_t alarm_config = {
.reload_count = 0,
.alarm_count = EXAMPLE_TIMER_ALARM_COUNT,
.flags.auto_reload_on_alarm = true,
};
gptimer_event_callbacks_t cbs = {
.on_alarm = on_timer_alarm_cb,
};
ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, NULL));
ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config));
ESP_ERROR_CHECK(gptimer_enable(gptimer));
ESP_ERROR_CHECK(gptimer_start(gptimer));
}