一、示范 1.简介:使用~esp-idfexamplesperipheralstimer_group例程;使用前将此工程复制到自己创建的工程文件夹中; 2.功能:定时器组[0]的定时器0的每隔3s打印一次;定时器组[1]的定时器0的每隔5s打印一次; 二、代码 1.
- /* General Purpose Timer example
- This example code is in the Public Domain (or CC0 licensed, at your option.)
- Unless required by applicable law or agreed to in writing, this
- software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- CONDITIONS OF ANY KIND, either express or implied.
- */
- #include
- #include "freertos/FreeRTOS.h"
- #include "freertos/task.h"
- #include "freertos/queue.h"
- #include "driver/timer.h"
- #define TIMER_DIVIDER (16) // Hardware timer clock divider
- #define TIMER_SCALE (TIMER_BASE_CLK / TIMER_DIVIDER) // convert counter value to seconds
- //按照定时器定义的结构体:定时器组,中定时器,报警时间(也就是定时器事件后发生中断),是否有自动重装
- typedef struct {
- int timer_group;
- int timer_idx;
- int alarm_interval;
- bool auto_reload;
- } example_timer_info_t;
- /**
- * [url=home.php?mod=space&uid=2666770]@Brief[/url] A sample structure to pass events from the timer ISR to task
- *
- */
- //定义的一个示例结构体,除了包含定时器的参数外,还定义了一个用于存储定时器中计数器数值的变量
- typedef struct {
- example_timer_info_t info;
- uint64_t timer_counter_value;
- } example_timer_event_t;
- static xQueueHandle s_timer_queue;
- /*
- * A simple helper function to print the raw timer counter value
- * and the counter value converted to seconds
- */
- static void inline print_timer_counter(uint64_t counter_value)
- {
- printf("Counter: 0x%08x%08xrn", (uint32_t) (counter_value >> 32),
- (uint32_t) (counter_value));
- printf("Time : %.8f srn", (double) counter_value / TIMER_SCALE);
- }
- static bool IRAM_ATTR timer_group_isr_callback(void *args)
- {
- BaseType_t high_task_awoken = pdFALSE;
- example_timer_info_t *info = (example_timer_info_t *) args;
- uint64_t timer_counter_value = timer_group_get_counter_value_in_isr(info->timer_group, info->timer_idx);
- /* Prepare basic event data that will be then sent back to task */
- //将定时器中断响应的定时器赋予结构体变量evt
- example_timer_event_t evt = {
- .info.timer_group = info->timer_group,
- .info.timer_idx = info->timer_idx,
- .info.auto_reload = info->auto_reload,
- .info.alarm_interval = info->alarm_interval,
- .timer_counter_value = timer_counter_value
- };
- //判断定时器组,中的定时器,是否有自动重载
- if (!info->auto_reload) {
- timer_counter_value += info->alarm_interval * TIMER_SCALE;
- //重新设置定时器组,中定时器,的时间间隔(定时器自身的时间间隔)
- timer_group_set_alarm_value_in_isr(info->timer_group, info->timer_idx, timer_counter_value);
- }
- /* Now just send the event data back to the main program task */
- //发送事件消息,消息存储在结构体evt中;注意:最后的参数提醒查看技术手册
- xQueueSendFromISR(s_timer_queue, &evt, &high_task_awoken);
- return high_task_awoken == pdTRUE; // return whether we need to yield at the end of ISR
- }
- /**
- * @brief Initialize selected timer of timer group
- *
- * [url=home.php?mod=space&uid=3142012]@param[/url] group Timer Group number, index from 0
- * @param timer timer ID, index from 0
- * @param auto_reload whether auto-reload on alarm event
- * @param timer_interval_sec interval of alarm
- */
- static void example_tg_timer_init(int group, int timer, bool auto_reload, int timer_interval_sec)
- {
- /****************************************一、配置定时器结构体timer_config_t**************************************/
- /* Select and initialize basic parameters of the timer */
- timer_config_t config = {
- .divider = TIMER_DIVIDER, //定时器预分频;esp32-c3的APB_CLK=80MHz,80MHz/TIMER_DIVIDER(16)=5MHz
- .counter_dir = TIMER_COUNT_UP, //计数器向上计数,从0开始
- .counter_en = TIMER_PAUSE, //计数器暂时中止
- .alarm_en = TIMER_ALARM_EN, //定时器警报使能
- .auto_reload = auto_reload, //1:定时器硬件在警报事件后自动重装载;0:则相反
- }; // default clock source is APB
- /****************************************二、timer_init函数中参数的定义******************************************/
- /*
- * 函数功能:Initializes and configure the timer.
- * 参数1:group_num Timer group number, 0 for TIMERG0 or 1 for TIMERG1
- * 参数2:timer_num Timer index, 0 for hw_timer[0] & 1 for hw_timer[1] 【一组定时器包含:普通定时器,看门狗定时器】
- * 参数3:config Pointer to timer initialization parameters.
- */
- timer_init(group, timer, &config); //定义定时器的工作方式,实现定时器初始化
- /****************************************三、定时器计数器器值配置************************************************/
- /* Timer's counter will initially start from value below.
- Also, if auto_reload is set, this value will be automatically reload on alarm */
- timer_set_counter_value(group, timer, 0); //配置定时器组(group),定时器x(timer)的计数器的值
- /***************************************四、定时器警报值设置、并使能中断ISR**************************************/
- /* Configure the alarm value and the interrupt on alarm. */
- //【timer_interval_sec值有上层调用函数提供;TIMER_SCALE=TIMER_BASE_CLK / TIMER_DIVIDER=APB_CLK_FREQ/TIMER_DIVIDER=80MHz/16=5MHz】
- timer_set_alarm_value(group, timer, timer_interval_sec * TIMER_SCALE);
-
- timer_enable_intr(group, timer);//使能定时器组(group)、定时器x(timer)中断
- /****************************************五、为对应的定时器添加ISR中断回调函数**************************************/
- example_timer_info_t *timer_info = calloc(1, sizeof(example_timer_info_t));
- timer_info->timer_group = group;
- timer_info->timer_idx = timer;
- timer_info->auto_reload = auto_reload;
- timer_info->alarm_interval = timer_interval_sec;
- timer_isr_callback_add(group, timer, timer_group_isr_callback, timer_info, 0);//???
- /****************************************六、启动定时器*************************************************************/
- timer_start(group, timer);//启动定时器组(group)、定时器x(timer)计数器
- }
- void app_main(void)
- {
- s_timer_queue = xQueueCreate(10, sizeof(example_timer_event_t));
- //函数的意思:配置定时器组0,中的定时器0,自动重装,间隔是3s
- example_tg_timer_init(TIMER_GROUP_0, TIMER_0, true, 3);
- //函数的意思:配置定时器组1,中的定时器0,无自动重装,间隔是5s
- example_tg_timer_init(TIMER_GROUP_1, TIMER_0, false, 5);
- while (1) {
- example_timer_event_t evt;
- //等待队列事件,时间是永远等待
- xQueueReceive(s_timer_queue, &evt, portMAX_DELAY);
- /* Print information that the timer reported an event */
- //判定定时器组是否有自动重装
- if (evt.info.auto_reload) {
- printf("Timer Group with auto reloadn");
- } else {
- printf("Timer Group without auto reloadn");
- }
- printf("Group[%d], timer[%d] alarm eventn", evt.info.timer_group, evt.info.timer_idx);
- /* Print the timer values passed by event */
- printf("------- EVENT TIME --------n");
- print_timer_counter(evt.timer_counter_value);
- /* Print the timer values as visible by this task */
- printf("-------- TASK TIME --------n");
- uint64_t task_counter_value;
- //获取定时器组,中定时器,的计数器的值;
- timer_get_counter_value(evt.info.timer_group, evt.info.timer_idx, &task_counter_value);
- print_timer_counter(task_counter_value);
- }
- }
复制代码
2.硬件连接好之后;在ESP-IDF命令工具中编译、下载,打开对应串口工具,查看打印数据; 三、结果 1.串口打印数据
四、ESP32-C3-DevKitM-1模块中的定时器解释 1.ESP32-C3的定时器简介 |