#include <Arduino_FreeRTOS.h>
#include <timers.h>
#include <task.h>
// Định nghĩa các khoảng thời gian cho các timer tính bằng mili giây, chuyển đổi thành ticks
#define mainONE_SHOT_TIMER_PERIOD pdMS_TO_TICKS(3333)
#define mainAUTO_RELOAD_TIMER_PERIOD pdMS_TO_TICKS(500)
// Biến lưu trữ handle của timer cho timer one-shot và auto-reload
TimerHandle_t xAutoReloadTimer, xOneShotTimer;
BaseType_t xTimer1Started, xTimer2Started;
// Khai báo nguyên mẫu hàm cho các callback của timer
static void prvOneShotTimerCallback(TimerHandle_t xTimer);
static void prvAutoReloadTimerCallback(TimerHandle_t xTimer);
// Khai báo nguyên mẫu hàm cho các task
void vChangeTimerPeriodTask(void *pvParameters);
void vResetTimerTask(void *pvParameters);
void setup() {
Serial.begin(9600); // Bật giao tiếp serial với baud rate là 9600
// Tạo timer one-shot
xOneShotTimer = xTimerCreate(
"OneShot", // Tên của timer (không được sử dụng bởi FreeRTOS)
mainONE_SHOT_TIMER_PERIOD, // Thời gian chạy của timer tính bằng ticks
pdFALSE, // Không tự động khởi động lại sau khi hết thời gian
0, // Không sử dụng timer id trong ví dụ này
prvOneShotTimerCallback // Hàm callback được gọi khi timer kết thúc
);
// Tạo timer auto-reload
xAutoReloadTimer = xTimerCreate(
"AutoReload", // Tên của timer (không được sử dụng bởi FreeRTOS)
mainAUTO_RELOAD_TIMER_PERIOD, // Thời gian chạy của timer tính bằng ticks
pdTRUE, // Tự động khởi động lại sau mỗi chu kỳ
0, // Không sử dụng timer id trong ví dụ này
prvAutoReloadTimerCallback // Hàm callback được gọi khi timer kết thúc
);
// Kiểm tra xem các timer đã được tạo thành công chưa
if ((xOneShotTimer != NULL) && (xAutoReloadTimer != NULL)) {
// Khởi động timer one-shot và timer auto-reload
xTimer1Started = xTimerStart(xOneShotTimer, 0);
xTimer2Started = xTimerStart(xAutoReloadTimer, 0);
// Kiểm tra xem việc khởi động timer đã thành công hay chưa
if ((xTimer1Started == pdPASS) && (xTimer2Started == pdPASS)) {
// Tạo task để thay đổi thời gian chu kỳ của timer auto-reload
xTaskCreate(vChangeTimerPeriodTask, "ChangeTimerPeriod", 100, NULL, 1, NULL);
// Tạo task để reset lại timer
xTaskCreate(vResetTimerTask, "ResetTimerTask", 100, NULL, 1, NULL);
// Khởi động bộ lập lịch của FreeRTOS
vTaskStartScheduler();
}
}
}
void loop() {
// Không có mã nguồn bổ sung trong hàm loop vì mọi task được quản lý bởi FreeRTOS
}
// Callback function cho timer one-shot
static void prvOneShotTimerCallback(TimerHandle_t xTimer) {
TickType_t xTimeNow;
xTimeNow = xTaskGetTickCount(); // Lấy số tick hiện tại
Serial.print("One-shot timer callback executing ");
Serial.println(xTimeNow / 31); // In ra serial monitor thời điểm callback được gọi
}
// Callback function cho timer auto-reload
static void prvAutoReloadTimerCallback(TimerHandle_t xTimer) {
TickType_t xTimeNow;
xTimeNow = xTaskGetTickCount(); // Lấy số tick hiện tại
Serial.print("Auto-reload timer callback executing ");
Serial.println(xTimeNow / 31); // In ra serial monitor thời điểm callback được gọi
}
// Task để thay đổi thời gian chu kỳ của timer auto-reload
void vChangeTimerPeriodTask(void *pvParameters) {
TickType_t xNewPeriod;
while(1) {
vTaskDelay(pdMS_TO_TICKS(10000)); // Chờ 10 giây
xNewPeriod = pdMS_TO_TICKS(1000); // Đổi thời gian chu kỳ thành 1000 ms
xTimerChangePeriod(xAutoReloadTimer, xNewPeriod, 0);
Serial.println("Changed auto-reload timer period to 1000 ms");
}
}
// Task để reset lại timer
void vResetTimerTask(void *pvParameters) {
while(1) {
vTaskDelay(pdMS_TO_TICKS(15000)); // Chờ 15 giây
xTimerReset(xAutoReloadTimer, 0);
Serial.println("Auto-reload timer reset");
}
}