timer.c 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #include "timer.h"
  2. #include <stdio.h>
  3. #include "driver/gptimer.h"
  4. #include "esp_err.h"
  5. #include "esp_log.h"
  6. #include "freertos/FreeRTOS.h"
  7. #include "freertos/queue.h"
  8. static const char *TAG = "TIMER";
  9. static gptimer_handle_t gptimer = NULL;
  10. QueueHandle_t queue;
  11. typedef struct
  12. {
  13. uint64_t event_count;
  14. } queue_callback_element_t;
  15. queue_callback_element_t item;
  16. bool example_timer_on_alarm_cb_v1(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_data)
  17. {
  18. BaseType_t high_task_awoken = pdFALSE;
  19. QueueHandle_t queue = (QueueHandle_t)user_data;
  20. queue_callback_element_t ele = {
  21. .event_count = edata->alarm_value};
  22. xQueueSendFromISR(queue, &ele, &high_task_awoken);
  23. // return whether we need to yield at the end of ISR
  24. return (high_task_awoken == pdTRUE);
  25. }
  26. void yx_timer_init(struct timer_param_s *params)
  27. {
  28. // create queue
  29. queue = xQueueCreate(1, sizeof(queue_callback_element_t));
  30. if (!queue)
  31. {
  32. ESP_LOGE(TAG, "creating queue error");
  33. return;
  34. }
  35. gptimer_config_t timer_config = {
  36. // 初始化参数设置
  37. .clk_src = GPTIMER_CLK_SRC_DEFAULT, // 选择时钟源
  38. .direction = GPTIMER_COUNT_UP, // 向上计数
  39. .resolution_hz = 1 * 1000 * 1000, // 1MHz, 1 tick = 1us 设置定时时间
  40. };
  41. ESP_LOGI(TAG, "Start timer, stop it at alarm event");
  42. ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer)); // 创建一个通用定时器,返回任务句柄
  43. gptimer_event_callbacks_t cbs = {
  44. // 中断回调函数(alrm中断)
  45. .on_alarm = example_timer_on_alarm_cb_v1,
  46. };
  47. ESP_LOGI(TAG, "Enable timer");
  48. ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, queue)); // 第一次调用这个函数需要在调用gptimer_enable之前
  49. //ESP_ERROR_CHECK(gptimer_enable(gptimer)); // 使能定时器中断
  50. ESP_LOGI(TAG, "Start timer, auto-reload at alarm event");
  51. gptimer_alarm_config_t alarm_config = {
  52. .reload_count = 0,
  53. .alarm_count = 1000000 * params->interval, // period = 5s
  54. .flags.auto_reload_on_alarm = true,
  55. };
  56. ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config));
  57. }
  58. void yx_timer_start(struct timer_param_s *params)
  59. {
  60. gptimer_enable(gptimer);
  61. ESP_ERROR_CHECK(gptimer_start(gptimer));
  62. if (xQueueReceive(queue, &item, portMAX_DELAY))
  63. {
  64. if (params->timerCbFunc != NULL)
  65. {
  66. params->timerCbFunc();
  67. }
  68. vQueueDelete(queue);
  69. }
  70. else
  71. {
  72. ESP_LOGW(TAG, "Missed one count event");
  73. }
  74. }
  75. void yx_timer_stop(struct timer_param_s *params)
  76. {
  77. ESP_ERROR_CHECK(gptimer_stop(gptimer));
  78. //gptimer_disable(gptimer);
  79. }