当前位置: 首页 > wzjs >正文

北京网站优化推广分析优化是什么意思?

北京网站优化推广分析,优化是什么意思?,wordpress post模板,中标公告 网站建设1. FreeRTOS 软件定时器 1.1 简介 ​ FreeRTOS 软件定时器是基于任务调度器实现的一种时间管理工具,可用于定时执行回调函数。它不依赖硬件资源,灵活性高,但受调度影响,精度低于硬件定时器 软件定时器与硬件定时器的主要区别如…

1. FreeRTOS 软件定时器

1.1 简介

​ FreeRTOS 软件定时器是基于任务调度器实现的一种时间管理工具,可用于定时执行回调函数。它不依赖硬件资源,灵活性高,但受调度影响,精度低于硬件定时器

软件定时器与硬件定时器的主要区别如下:

软件定时器硬件定时器
依赖 FreeRTOS 任务调度器由 MCU 提供,独立运行
精度受任务调度影响具有更高的精度
不占用硬件资源,可能增加 CPU 负载需占用硬件资源,不增加 CPU 负载

1.2 单次定时器和周期定时器

在 FreeRTOS 中,软件定时器主要有两种类型:一次性定时器和周期性定时器。

  • 一次性定时器(One-shot Timer): 这种定时器在触发一次超时后就会停止,不再执行。适用于只需在特定时间执行一次任务或动作的场景(xAutoReload为pdFALSE 0)。
  • 周期性定时器(Periodic Timer): 这种定时器会在每个超时周期都触发一次,循环执行。适用于需要在固定的时间间隔内重复执行任务或动作的场景(xAutoReload为pdTRUE 1)。

1.3 必要宏定义

要使用软件定时器,必须 使能软件定时器功能配置相关参数FreeRTOSConfig.h文件中相关配置,如下:

/* 使能软件定时器相关 */
#define configUSE_TIMERS  1  /* 1: 启用 FreeRTOS 软件定时器功能 */
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES - 1)  /* 软件定时器任务的优先级 */
#define configTIMER_QUEUE_LENGTH 5  /* 软件定时器队列长度(存放定时器事件的队列深度) */
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2)  /* 定时器任务的栈大小 */

详细介绍

  • configTIMER_TASK_PRIORITY 该任务的优先级越高,软件定时器的回调执行越及时,但过高的优先级可能影响其他任务的执行

  • configTIMER_QUEUE_LENGTH 由于其他优先级任务会可能会抢占软件定时器服务任务的执行,所以定义软件定时器服务队列来存储待执行的命令软件定时器命令队列的最大长度(存放定时器操作请求,如 xTimerStart()xTimerStop() 等)

  • configTIMER_TASK_STACK_DEPTH 该任务负责 检测定时器超时,并执行定时器回调函数,需要一定的栈空间

1.4 软件定时器与定时器服务任务的关系

​ 在学习 FreeRTOS 的软件定时器时,容易混淆 “定时器”“定时器服务任务” 之间的关系。实际上,FreeRTOS 采用 单个定时器服务任务 来统一管理 所有的软件定时器。所有 xTimerCreate() 创建的软件定时器都由一个单独的定时器服务任务管理,定时器本身不是一个独立的任务

FreeRTOS 定时器管理机制:软件定时器(xTimerCreate()只是一个数据结构,存储了定时器的周期、回调函数等信息,并不是真正的任务需要由定时器服务任务来管理和执行

1.5 相关 API 函数

API 函数描述
xTimerCreate()动态创建一个新的软件定时器对象
xTimerCreateStatic()静态创建一个新的软件定时器对象
xTimerStart()启动定时器(从零开始计时)
xTimerStop()停止定时器(不会自动重新开始)
xTimerChangePeriod()修改定时器的周期
xTimerReset()重置定时器(重新开始计时)
xTimerDelete()删除定时器
xTimerIsTimerActive()判断定时器是否在运行
pvTimerGetTimerID()获取定时器的 ID
xTimerPendFunctionCall()将一个函数发送到定时器服务任务的执行队列中,执行一次

这些 API 函数中的 xTicksToWait 参数含义为:调用任务在定时器服务任务队列已满的情况下,为等待队列空间空出而保持阻塞状态的时间量。

1.6 实验

  • start_task:用来创建 task1 任务,并创建周期性定时器。
  • 定时器1:创建 scan_keypad 函数,软件定时器周期回调执行,用来扫描键盘进行消抖。
  • 定时器2:创建 timer2_callback 函数,回调执行周期为 1 秒。
  • task1:用于按键状态判断,对软件定时器2进行开启、停止、修改回调周期操作;将一个函数加入定时器服务任务,执行一次。

1 ) 启动任务配置

/* 启动任务配置 */
#define TASK_START_STACK_SIZE 128
#define TASK_START_PRIORITY 1
TaskHandle_t Task_start_Handle; // 如果后续不需要操作这个任务(删除,挂起等),可以省略这句
StackType_t start_task_stack[TASK_START_STACK_SIZE];
StaticTask_t start_task_tcb;
void task_start(void *pvParameters);/* 任务1配置 */
#define TASK1_STACK_SIZE 128
#define TASK1_PRIORITY 2
TaskHandle_t Task1_Handler;
void task1(void *pvParameters);/* 软件定时器配置 */
#define TIMER_TASK_STAK_SIZE configTIMER_TASK_STACK_DEPTH
StaticTask_t timer_task_tcb;
StackType_t timer_task_stack[TIMER_TASK_STAK_SIZE];
TimerHandle_t timer1, timer2;void FreeRTOS_start()
{Task_start_Handle = xTaskCreateStatic((TaskFunction_t)task_start,                    // 任务函数指针(char *)"task_start",                          // 任务名称(configSTACK_DEPTH_TYPE)TASK_START_STACK_SIZE, // 任务栈大小(void *)NULL,                                  // 传递给任务函数的参数(UBaseType_t)TASK_START_PRIORITY,              // 任务优先级(StackType_t *)start_task_stack,               // 任务栈指针(用户手动分配)(StaticTask_t *)&start_task_tcb);              // 任务控制块(TCB)指针(用户手动分配)/* 启动任务调度器:自动创建空闲任务 */vTaskStartScheduler();
}void task_start(void *pvParameters)
{/* 进入临界区:保护临界区里的代码不会被打断 */taskENTER_CRITICAL();/* 创建任务 */xTaskCreate((TaskFunction_t)task1,(char *)"task1",(configSTACK_DEPTH_TYPE)TASK1_STACK_SIZE,(void *)NULL,(UBaseType_t)TASK1_PRIORITY,(TaskHandle_t *)&Task1_Handler);timer1 = xTimerCreate((char *)"timer1",(TickType_t)10,(BaseType_t)pdTRUE,(void *)0,scan_keypad);timer2 = xTimerCreate((char *)"timer2",(TickType_t)1000,(BaseType_t)pdTRUE,(void *)0,timer2_callback);if (timer1 != NULL && timer2 != NULL)printf("软件定时器创建成功\r\n");elseprintf("软件定时器创建失败\r\n");xTimerStart(timer1, portMAX_DELAY);/* 启动任务只需要执行一次即可,用完就删除自己 */vTaskDelete(NULL);/* 退出临界区 */taskEXIT_CRITICAL();
}

2 ) 按键扫描函数(这里为4*4矩阵键盘)

// 键盘消抖扫描函数
void scan_keypad(TimerHandle_t xTimer)
{// 依次扫描每一行for (int row = 0; row < 4; row++){// 将当前行置为低电平,其他行置为高电平HAL_GPIO_WritePin(ROW_GPIO_PORT, ROW1_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin(ROW_GPIO_PORT, ROW2_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin(ROW_GPIO_PORT, ROW3_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin(ROW_GPIO_PORT, ROW4_PIN, GPIO_PIN_SET);HAL_GPIO_WritePin(ROW_GPIO_PORT, (row == 0) ? ROW1_PIN : (row == 1) ? ROW2_PIN: (row == 2)   ? ROW3_PIN: ROW4_PIN,GPIO_PIN_RESET);// 检查每一列的状态for (int col = 0; col < 4; col++){key[(row * 4) + col].state = HAL_GPIO_ReadPin(COL_GPIO_PORT, (col == 0) ? COL1_PIN : (col == 1) ? COL2_PIN: (col == 2)   ? COL3_PIN: COL4_PIN);}}for (int i = 0; i < 16; i++){switch (key[i].judge){case 0:{if (key[i].state == 0){key[i].judge = 1;}}break;case 1:{if (key[i].state == 0){key[i].judge = 2;}}break;case 2:{if (key[i].state == 1){key[i].flag = 1;key[i].judge = 0;}break;}}}
}

3 ) task1

void task1(void *pvParameters)
{BaseType_t err = pdFAIL;while (1){if (key[0].flag){err = xTimerStart(timer2, portMAX_DELAY);if (err == pdTRUE)printf("开启软件定时器2成功 \r\n");elseprintf("开启软件定时器2失败 \r\n");key[0].flag = 0;}if (key[1].flag){err = xTimerStop(timer2, portMAX_DELAY);if (err == pdTRUE)printf("关闭软件定时器2成功 \r\n");elseprintf("关闭软件定时器2失败 \r\n");key[1].flag = 0;}if (key[2].flag){err = xTimerChangePeriod(timer2,(TickType_t) 500 ,portMAX_DELAY);if (err == pdTRUE)printf("修改软件定时器2回调周期成功 \r\n");elseprintf("修改软件定时器2回调周期失败 \r\n");key[2].flag = 0;}if (key[3].flag){err = xTimerPendFunctionCall((PendedFunction_t)fun,NULL,0,portMAX_DELAY);if (err == pdTRUE)printf("将函数 fun 发送到定时器服务任务中执行成功 \r\n");elseprintf("将函数 fun 发送到定时器服务任务中执行中失败 \r\n");key[3].flag = 0;}vTaskDelay(100);}
}

4 ) 发送到定时器服务任务中的函数

void fun(void);
void fun(){printf("fun runing...\r\n");
}

5 ) timer2 回调函数

void timer2_callback(TimerHandle_t xTimer)
{static unsigned int time = 0;printf("timer2 运行次数为: %d \r\n", ++time);
}

文章转载自:

http://kr29Pkzh.dqgbx.cn
http://jfLMTLOV.dqgbx.cn
http://sU661LoI.dqgbx.cn
http://2lxzmm6Y.dqgbx.cn
http://saLG1hrX.dqgbx.cn
http://x48snToF.dqgbx.cn
http://ybmDGiQV.dqgbx.cn
http://po9mBfZY.dqgbx.cn
http://cAcPRx5O.dqgbx.cn
http://z2p028kT.dqgbx.cn
http://hAHBNcS2.dqgbx.cn
http://BAeLrBFd.dqgbx.cn
http://WRqU7DfW.dqgbx.cn
http://Kk80bEzg.dqgbx.cn
http://WQBZett8.dqgbx.cn
http://fX357iPR.dqgbx.cn
http://bVvtKNVb.dqgbx.cn
http://JXi1Va0y.dqgbx.cn
http://AOchLuDS.dqgbx.cn
http://hbKE2PBB.dqgbx.cn
http://dRTPdFvZ.dqgbx.cn
http://6bx1OcLv.dqgbx.cn
http://Tnc4nhCb.dqgbx.cn
http://VneyNQNB.dqgbx.cn
http://OyjraqbY.dqgbx.cn
http://va2ZINxD.dqgbx.cn
http://YAXli8Lp.dqgbx.cn
http://M7Qmo7jA.dqgbx.cn
http://7BEsLtgx.dqgbx.cn
http://IQ2huvfb.dqgbx.cn
http://www.dtcms.com/wzjs/720484.html

相关文章:

  • 企业网站管理系统联系我们怎么添加建设银行网站钓鱼
  • 乐视网站建设目标中国建设银行网站忘记密码
  • 郴州网站小程序临清网站建设公司
  • 网站图片用什么格式韩国做美食网站有哪些
  • 网站设计小结seo优化教程自学网
  • 网站首页排名seo搜索优化雄安投资建设集团有限公司网站
  • 网站建设主要产品作品设计思路范文
  • 网站域名不想实名认证淮南市建设工程质量监督中心网站
  • 网站开发协议企业网站建设用标语
  • 重庆网站建设mlfartwordpress主题显示不了
  • 张家港做网站排名热搜关键词查询
  • 网站如何seo临沂seo代理商
  • 优化推广优化网站设计有哪些方法
  • 国外网页设计欣赏网站平面图用什么软件做
  • 深圳自助网站建设上海公司名字
  • 除尘环保设备网站模板wordpress导出全站链接
  • 视频网站很难建设吗wordpress下载的主题怎么用
  • 建设互联网地方垂直网站重庆做汉堡的餐饮公司网站
  • 施工建设集团网站苏州建站模板搭建
  • 手绘风网站wordpress 同步qq空间
  • 网站维护一般需要多久时间打开网址跳转到国外网站
  • 九一制作厂网站app营销型网站有哪些建设流程
  • 牛商网营销型网站多少钱个人建网站的详细步骤
  • 推广培训班中文域名网站好不好优化
  • 那个网站做的调查准确wordpress联系我们
  • 跨国网站浏览器惠州软件开发
  • 帮别人做网站需要什么能力做网站把自己做死
  • 宜春做网站的公司哪家好游戏软件开发需要学什么专业
  • 广西建设监理协会官网站网站建设的目标人群是什么
  • 石家庄网站做网站wordpress 不显示图片