ESP32 FreeRtos 队列传输单种类数据
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "esp_log.h"
#include "driver/timer.h"
 
#define TIMER_DIVIDER         16  
#define TIMER_SCALE           (TIMER_BASE_CLK / TIMER_DIVIDER/ 1000)  //分频
#define TIMER_INTERVAL0_SEC   (1) //计数值,如果为1,则1ms进入中断;如果为10,则10ms进入中断
#define TEST_WITH_RELOAD      1  
 
typedef struct {
    uint64_t timer_minute_count;
    uint64_t timer_second_count;
} timer_event_t;
 
timer_event_t g_timer_event;
 
xQueueHandle timer_queue;
 
 
unsigned int timer_counter = 0;
 
void IRAM_ATTR timer_group0_isr(void *para) //中断函数
{
    timer_spinlock_take(TIMER_GROUP_0);
    int timer_idx = (int) para;
 
    // /* Prepare basic event data
    //    that will be then sent back to the main program task */
    timer_counter++;
    timer_event_t evt;
    xQueueSendFromISR(timer_queue, &evt, NULL); //每次进入中断都会向设置好的队列发送消息
 
    timer_group_clr_intr_status_in_isr(TIMER_GROUP_0, TIMER_0);
 
    /* After the alarm has been triggered
      we need enable it again, so it is triggered the next time */
    timer_group_enable_alarm_in_isr(TIMER_GROUP_0, timer_idx);
 
    /* Now just send the event data back to the main program task */
    timer_spinlock_give(TIMER_GROUP_0);
}
 
static void example_tg0_timer_init(int timer_idx,
                                   bool auto_reload, double timer_interval_sec)
{
    /* Select and initialize basic parameters of the timer */
    timer_config_t config = {
        .divider = TIMER_DIVIDER,
        .counter_dir = TIMER_COUNT_UP,
        .counter_en = TIMER_PAUSE,
        .alarm_en = TIMER_ALARM_EN,
        .auto_reload = auto_reload,
    }; // default clock source is APB
    timer_init(TIMER_GROUP_0, timer_idx, &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(TIMER_GROUP_0, timer_idx, 0x00000000ULL);
 
    /* Configure the alarm value and the interrupt on alarm. */
    timer_set_alarm_value(TIMER_GROUP_0, timer_idx, timer_interval_sec * TIMER_SCALE);
    timer_enable_intr(TIMER_GROUP_0, timer_idx);
    timer_isr_register(TIMER_GROUP_0, timer_idx, timer_group0_isr,
                       (void *) timer_idx, ESP_INTR_FLAG_IRAM, NULL);
 
    timer_start(TIMER_GROUP_0, timer_idx);
}
 
static void timer_example_evt_task(void *arg)
{
    while (1) {
        timer_event_t evt;
        xQueueReceive(timer_queue, &evt, portMAX_DELAY);
        g_timer_event.timer_minute_count ++;
        //60s 计算一次 刷新时间
        if(g_timer_event.timer_minute_count >= 60000){
            g_timer_event.timer_minute_count = 0;
            printf("One minute receive ...\n");
        }
        g_timer_event.timer_second_count ++;
        //1s计算一次
        if(g_timer_event.timer_second_count >= 1000){
            g_timer_event.timer_second_count = 0;
            printf("One second receive ...\n");
        }
    }
}
 
void ds_timer_init(void)
{
    g_timer_event.timer_minute_count = 0;
    g_timer_event.timer_second_count = 0;
    timer_queue = xQueueCreate(10, sizeof(timer_event_t));
    example_tg0_timer_init(TIMER_0, TEST_WITH_RELOAD, TIMER_INTERVAL0_SEC);
    xTaskCreate(timer_example_evt_task, "timer_evt_task", 2048, NULL, 5, NULL);
}
 
 
 
void app_main(void)
{
    ds_timer_init();
 
    while(1){
        printf("system run ...\n");
        vTaskDelay(1000 / portTICK_PERIOD_MS);
 
        if(timer_counter >= 1000)
        {
            timer_counter = 0;
            printf("ESP32 Demo Timer Task run ...\n");
        }
    }
}
主要是验证了ESP32中的消息队列机制,配置好定时器后,在每次定时中断中向消息队列发送消息,在消息队列接收端接收消息并打印触发信息。作为一个小demo方便后续开发查阅。
运行结果:

 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号