软件定时器不同于硬件定时器。
一个软件定时器(或者只是一个“定时器”)允许一个函数在未来的一个设定的时间执行。由计时器执行的函数被称为计时器的回调函数。计时器从启动到执行它的回调函数之间的时间称为计时器的周期。简单地说,计时器的回调函数在计时器的周期到期时执行。
在使用软件计时器之前,必须显式地创建它。
本小节中所讲的函数在使用时需要添加头文件freertos/timers.h

#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "freertos/queue.h"
#include "freertos/timers.h"

void TimerCallBack(TimerHandle_t xTimer) {
	const char *strName;
	strName = pcTimerGetName(xTimer);
	int *id;
	id = (int *)pvTimerGetTimerID(xTimer);
	printf("Timer Name = %s! id = %d\n",strName,*id);
}

int id1 = 1;
int id2 = 2;

void app_main(void) {
	TimerHandle_t xTimer1;
	TimerHandle_t xTimer2;

	xTimer1 = xTimerCreate("Timer1", pdMS_TO_TICKS(1000), pdTRUE, (void*) &id1,
			TimerCallBack);
	xTimer2 = xTimerCreate("Timer2", pdMS_TO_TICKS(2000), pdTRUE, (void*) &id2,
			TimerCallBack);
	xTimerStart(xTimer1, 0);
	xTimerStart(xTimer2, 0);
	vTaskDelay(pdMS_TO_TICKS(6000));
	xTimerChangePeriod(xTimer1,pdMS_TO_TICKS(6000),0);
}

在app_main()要做以下几件事情:
首先要调用xTimerCreate()函数去创建定时器,并给软件定时器传入一个回调函数TimerCallBack()。
创建好两个定时器xTimer1和xTimer2后,调用xTimerStart()函数,软件定时器开始工作
调用xTimerChangePeriod()函数去修改定时器的周期。
在定时器的回调函数TimerCallBack()中:
调用pcTimerGetName()函数返回创建计时器时分配给计时器的人类可读文本名称。
调用pvTimerGetTimerID()函数返回分配给计时器的标识符(ID)。
在这里简单的对上面代码中陌生的函数做一个说明:
xTimerCreate()函数:

创建一个新的软件计时器并返回一个句柄,该句柄用于创建软件计时器引用。 pcTimerName:分配给计时器的纯文本名称
xTimerPeriod:软件定时器的周期
uxAutoReload:设置为pdTRUE可以创建一个自动重新加载计时器。设置为pdFALSE创建一次性的计时器。
pvTimerID:分配给正在创建的计时器的标识符。标识符稍后可以使用vTimerSetTimeId()API函数进行更新。
pxCallbackFunction:计时器过期时要调用的函数。

xTimerStart()函数:

启动计时器运行。xTimerStartFromISR()是一个等效函数,可以从一种中断服务程序。
xTimer:要重置、启动或重新启动的计时器。 xTicksToWait:要延长的时间。

xTimerChangePeriod()函数:

改变软件定时器的周期 xTimer:正在分配新时段的计时器。 xNewPeriod:xTimer参数引用的计时器的新周期。
xTicksToWait:延长的时间

软件定时器_重新启动

#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "freertos/queue.h"
#include "freertos/timers.h"

void TimerCallBack(TimerHandle_t xTimer) {
	const char *strName;
	strName = pcTimerGetName(xTimer);
	int *id;
	id = (int *)pvTimerGetTimerID(xTimer);
	printf("Timer Name = %s! id = %d\n",strName,*id);
}

int id1 = 1;
int id2 = 2;

void app_main(void) {
	TimerHandle_t xTimer1;
	TimerHandle_t xTimer2;
	xTimer1 = xTimerCreate("Timer1", pdMS_TO_TICKS(1000), pdTRUE, (void*) &id1,
			TimerCallBack);
	xTimer2 = xTimerCreate("Timer2", pdMS_TO_TICKS(2000), pdTRUE, (void*) &id2,
			TimerCallBack);
	xTimerStart(xTimer1, 0);
	xTimerStart(xTimer2, 0);
	vTaskDelay(pdMS_TO_TICKS(6000));
	xTimerChangePeriod(xTimer1,pdMS_TO_TICKS(6000),0);
	while (1)
	{
		/* code */	
		vTaskDelay(pdMS_TO_TICKS(1000));
		xTimerReset(xTimer2,0);
	}
	vTaskDelay(pdMS_TO_TICKS(6000));
	xTimerStop(xTimer1, 0);
}

定时器重启xTimerReset()函数

重启软件定时器
xTimer:正在重置、启动或重新启动的计时器。
xTicksToWait:要等待的时间

定时器停止xTimerStop()函数

停止定时器
xTimer:正在重置、启动或重新启动的计时器。
xTicksToWait:要等待的时间

软件定时器_回调函数_02