一、声明
这个程序主要就是看一下两个vTaskDelay();函数还有vTaskDelayUtil();这两个函数各有什么功能
这个程序是根据我的03程序来修改的
我修改后的程序08,示例代码temp:11
二、两个Delay
vTaskDelay();这个函数就是前面的do_sth();这个函数执行运行了多长的时间,后面就再延时五个vTaskDelay();的5个Tick时长,使用vTaskDelay函数比mdelay这种死循环的延时函数好一些,不会一直占用CPU的内存
如果想要运行的时间是一个周期的话,那么就要使用vTaskDelayUntil();
使用这个函数就是要首先获取一下起始时间的时间点T1,然后用T1+15=T2,所以下一次执行任务就从T2时刻开始。而在T1~T2这个时间段之间,有一部分是do_sth();所使用的时间,剩下的时间就是vTaskUntil(); 所以这样达到的一个效果就是周期性
在vTaskDelay();执行到T2时刻的时候,这个时候T2就会被唤醒,这个时候preTime就会记录下这个T2的时刻,并且让程序进入就绪态,就是可以接着执行do_sth();这个程序
三、CubeMx的配置
基础配置
外设配置
只使用到了OLED PB7——SDA PB6——SCL
四、Keil5的配置
测试vTaskDelay();函数的时间
t1-t2的值就是500ms减去do_task()这个函数所消耗的时间,也就是vTaskDelayUtil();这个函数延时的时间。又因为,mdelay(cnt & 0x3)这个函数的延时是随机的,所以t1-t2的值是在变化的
这里面没有使用默认任务,所以可以把默认任务屏蔽掉
#include "driver_lcd.h"//OLED显示的头文件只需要包含这个
#include "driver_timer.h"//这个里面使用了延时函数
/* USER CODE BEGIN FunctionPrototypes */
/* 定义函数需要的结构体 */
struct TaskPrintInfo{
uint8_t x;
uint8_t y;
char name[16];
};
/* 给下面三个任务设置三个全局变量 */
static struct TaskPrintInfo g_Task1Info ={0,0,"Task1"};
static struct TaskPrintInfo g_Task2Info ={0,3,"Task2"};
static struct TaskPrintInfo g_Task3Info ={0,6,"Task3"};
/* 保护LCD打印的时候不被打断 */
static int g_LCDCanUse =1;
/* 创建这个函数 */
void LcdPrintTask(void *params)
{
struct TaskPrintInfo *pInfo=params;
uint32_t cnt=0;
int len;
BaseType_t preTime;
preTime=xTaskGetTickCount();//获取初始时间点
/* 测量消耗的时间*/
uint64_t t1,t2;
while(1)
{
/* 打印信息 */
if(g_LCDCanUse==1)
{
g_LCDCanUse=0;
len =LCD_PrintString(pInfo->x,pInfo->y,pInfo->name);
len +=LCD_PrintString(len,pInfo->y,":");
LCD_PrintSignedVal(len,pInfo->y,cnt++);
g_LCDCanUse=1;
mdelay(cnt & 0x3);//这个是添加一个死循环
}
t1=system_get_ns();
// vTaskDelay(500);//500ms=500 000 000ns
vTaskDelayUntil(&preTime,500);
t2=system_get_ns();
LCD_ClearLine(pInfo->x,pInfo->y+2);//先把原来打印的那一行清除掉
LCD_PrintSignedVal(pInfo->x, pInfo->y+2, t2-t1);
}
}
/* USER CODE END FunctionPrototypes */
void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
// 在创建任务这里添加初始化aOLED和清屏的指令
LCD_Init();
LCD_Clear();
/* USER CODE END Init */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* creation of defaultTask */
// defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
/* 使用同一个函数创建不同的任务 */
xTaskCreate(LcdPrintTask,"task1",128,&g_Task1Info,osPriorityNormal,NULL);
// xTaskCreate(LcdPrintTask,"task2",128,&g_Task2Info,osPriorityNormal,NULL);
// xTaskCreate(LcdPrintTask,"task3",128,&g_Task3Info,osPriorityNormal,NULL);
/* USER CODE BEGIN RTOS_EVENTS */
/* add events, ... */
/* USER CODE END RTOS_EVENTS */
}