wave_gen_example_main.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. /* Wave Generator Example
  2. This example code is in the Public Domain (or CC0 licensed, at your option.)
  3. DAC output channel, waveform, wave frequency can be customized in menuconfig.
  4. If any questions about this example or more information is needed, please read README.md before your start.
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <math.h>
  9. #include <assert.h>
  10. #include "freertos/FreeRTOS.h"
  11. #include "freertos/task.h"
  12. #include "freertos/queue.h"
  13. #include "driver/gpio.h"
  14. #include "driver/dac.h"
  15. #include "driver/gptimer.h"
  16. #include "esp_log.h"
  17. /* The timer ISR has an execution time of 5.5 micro-seconds(us).
  18. Therefore, a timer period less than 5.5 us will cause trigger the interrupt watchdog.
  19. 7 us is a safe interval that will not trigger the watchdog. No need to customize it.
  20. */
  21. #define TIMER_INTR_US 7 // Execution time of each ISR interval in micro-seconds
  22. #define POINT_ARR_LEN 200 // Length of points array
  23. #define AMP_DAC 255 // Amplitude of DAC voltage. If it's more than 256 will causes dac_output_voltage() output 0.
  24. #define VDD 3300 // VDD is 3.3V, 3300mV
  25. #define CONST_PERIOD_2_PI 6.2832
  26. #define DAC_CHAN CONFIG_EXAMPLE_DAC_CHANNEL // DAC_CHANNEL_1 (GPIO25) by default
  27. #define FREQ CONFIG_EXAMPLE_WAVE_FREQUENCY // 3kHz by default
  28. #define OUTPUT_POINT_NUM (int)(1000000 / (TIMER_INTR_US * FREQ) + 0.5) // The number of output wave points.
  29. _Static_assert(OUTPUT_POINT_NUM <= POINT_ARR_LEN, "The CONFIG_EXAMPLE_WAVE_FREQUENCY is too low and using too long buffer.");
  30. static int raw_val[POINT_ARR_LEN]; // Used to store raw values
  31. static int volt_val[POINT_ARR_LEN]; // Used to store voltage values(in mV)
  32. static const char *TAG = "wave_gen";
  33. static int g_index = 0;
  34. /* Timer interrupt service routine */
  35. static bool IRAM_ATTR on_timer_alarm_cb(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
  36. {
  37. int *head = (int *)user_data;
  38. /* DAC output ISR has an execution time of 4.4 us*/
  39. if (g_index >= OUTPUT_POINT_NUM) {
  40. g_index = 0;
  41. }
  42. dac_output_voltage(DAC_CHAN, *(head + g_index));
  43. g_index++;
  44. return false;
  45. }
  46. static void prepare_data(int pnt_num)
  47. {
  48. for (int i = 0; i < pnt_num; i ++) {
  49. #ifdef CONFIG_EXAMPLE_WAVEFORM_SINE
  50. raw_val[i] = (int)((sin( i * CONST_PERIOD_2_PI / pnt_num) + 1) * (double)(AMP_DAC) / 2 + 0.5);
  51. #elif CONFIG_EXAMPLE_WAVEFORM_TRIANGLE
  52. raw_val[i] = (i > (pnt_num / 2)) ? (2 * AMP_DAC * (pnt_num - i) / pnt_num) : (2 * AMP_DAC * i / pnt_num);
  53. #elif CONFIG_EXAMPLE_WAVEFORM_SAWTOOTH
  54. raw_val[i] = (i == pnt_num) ? 0 : (i * AMP_DAC / pnt_num);
  55. #elif CONFIG_EXAMPLE_WAVEFORM_SQUARE
  56. raw_val[i] = (i < (pnt_num / 2)) ? AMP_DAC : 0;
  57. #endif
  58. volt_val[i] = (int)(VDD * raw_val[i] / (float)AMP_DAC);
  59. }
  60. }
  61. static void log_info(void)
  62. {
  63. ESP_LOGI(TAG, "DAC output channel: %d", DAC_CHAN);
  64. if (DAC_CHAN == DAC_CHANNEL_1) {
  65. ESP_LOGI(TAG, "GPIO:%d", GPIO_NUM_25);
  66. } else {
  67. ESP_LOGI(TAG, "GPIO:%d", GPIO_NUM_26);
  68. }
  69. #ifdef CONFIG_EXAMPLE_WAVEFORM_SINE
  70. ESP_LOGI(TAG, "Waveform: SINE");
  71. #elif CONFIG_EXAMPLE_WAVEFORM_TRIANGLE
  72. ESP_LOGI(TAG, "Waveform: TRIANGLE");
  73. #elif CONFIG_EXAMPLE_WAVEFORM_SAWTOOTH
  74. ESP_LOGI(TAG, "Waveform: SAWTOOTH");
  75. #elif CONFIG_EXAMPLE_WAVEFORM_SQUARE
  76. ESP_LOGI(TAG, "Waveform: SQUARE");
  77. #endif
  78. ESP_LOGI(TAG, "Frequency(Hz): %d", FREQ);
  79. ESP_LOGI(TAG, "Output points num: %d\n", OUTPUT_POINT_NUM);
  80. }
  81. void app_main(void)
  82. {
  83. g_index = 0;
  84. gptimer_handle_t gptimer = NULL;
  85. gptimer_config_t timer_config = {
  86. .clk_src = GPTIMER_CLK_SRC_DEFAULT,
  87. .direction = GPTIMER_COUNT_UP,
  88. .resolution_hz = 1000000, // 1MHz, 1 tick = 1us
  89. };
  90. ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer));
  91. ESP_ERROR_CHECK(dac_output_enable(DAC_CHAN));
  92. log_info();
  93. prepare_data(OUTPUT_POINT_NUM);
  94. gptimer_alarm_config_t alarm_config = {
  95. .reload_count = 0,
  96. .alarm_count = TIMER_INTR_US,
  97. .flags.auto_reload_on_alarm = true,
  98. };
  99. gptimer_event_callbacks_t cbs = {
  100. .on_alarm = on_timer_alarm_cb,
  101. };
  102. ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, raw_val));
  103. ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config));
  104. ESP_ERROR_CHECK(gptimer_enable(gptimer));
  105. ESP_ERROR_CHECK(gptimer_start(gptimer));
  106. while (1) {
  107. vTaskDelay(10);
  108. #if CONFIG_EXAMPLE_LOG_VOLTAGE
  109. if (g_index < OUTPUT_POINT_NUM) {
  110. ESP_LOGI(TAG, "Output voltage(mV): %d", volt_val[g_index]);
  111. ESP_LOGD(TAG, "g_index: %d\n", g_index);
  112. }
  113. #endif
  114. }
  115. }