【RTOS】在Arduino上跑个系统吧(多任务并行)【二】
2017-04-022.7万
AI 快速预览详细
本文介绍了如何在Arduino上使用FreeRTOS实现多任务并行。通过具体的代码示例和Proteus仿真,展示了三个任务的创建与调度过程。每个任务有不同的优先级和栈大小配置,实现了LED闪烁和串口打印的功能。
|
为了观看实验效果,这里我使用Proteus进行仿真 代码部分用三种颜色显示不用的任务 仿真文件: ![]() Proteus_ArduinoUno.zip来看一下代码吧------------------------------------------------------------- #include <FreeRTOS_AVR.h> const uint8_t LED_PIN_1 = 13;//定义第一个led const uint8_t LED_PIN_2 = 12;//定义第二个led volatile uint32_t count = 0;//计数用的变量 //------------------------------------------------------------------------------ //创建任务vLEDFlashTask_1,(必须按照这样的格式) //**程序效果:每200ms闪烁一次led1,占空比1/3** static void vLEDFlashTask_1(void *pvParameters) { pinMode(LED_PIN_1, OUTPUT);//配置IO模式 // 每200ms闪烁一次. for (;;) {//直接死循环,就是这么任性(因为RTOS会自动调度,不用担心) // 点亮 digitalWrite(LED_PIN_1, HIGH); // 等待50ms vTaskDelay((50L * configTICK_RATE_HZ) / 1000L); // 熄灭 digitalWrite(LED_PIN_1, LOW); // 等待150ms vTaskDelay((150L * configTICK_RATE_HZ) / 1000L); } } //------------------------------------------------------------------------------ //创建任务vLEDFlashTask_2,(必须按照这样的格式) //**程序效果:每200ms闪烁一次led2,占空比50%** static void vLEDFlashTask_2(void *pvParameters) { pinMode(LED_PIN_2, OUTPUT);//配置IO模式 // 每200ms闪烁一次. for (;;) {//直接死循环,就是这么任性(因为RTOS会自动调度,不用担心) // 点亮 digitalWrite(LED_PIN_2, HIGH); // 等待100ms vTaskDelay((100L * configTICK_RATE_HZ) / 1000L); // 熄灭 digitalWrite(LED_PIN_2, LOW); // 等待100ms vTaskDelay((100L * configTICK_RATE_HZ) / 1000L); } } //------------------------------------------------------------------------------ //创建任务vPrintTask,(必须按照这样的格式) //**程序效果:每1s打印一次当前的count的值** static void vPrintTask(void *pvParameters) { while (1) {//直接死循环,就是这么任性(因为RTOS会自动调度,不用担心) // 等待1000ms vTaskDelay(configTICK_RATE_HZ); // 打印当前的计数Count Serial.print(F("Count: ")); Serial.println(count); // Zero count. count = 0; } } //------------------------------------------------------------------------------ void setup() { Serial.begin(9600); // 等待Leonardo响应 while(!Serial) {} //======创建函数解读=================================================================================== // xTaskCreate(vLEDFlashTask_1,//对应任务的名称,比如这里的是vLEDFlashTask_1 // "Task1", //这个名字没有实际用途,主要用来识别(just for human) // configMINIMAL_STACK_SIZE + 50, //栈的大小,栈简单的来说是数据的存放,栈越大,越不会溢出,但同时占用资源也越多,需要根据任务的实际需要来调整 // NULL, // tskIDLE_PRIORITY + 2, //任务的优先级,这里的是2,需要说明的是0是优先级最低,最高优先级有上限,和芯片的资源以及RTOS本身有关 // NULL); // // 补充:configMINIMAL_STACK_SIZE,指loop()的栈(Task)大小,其他的任务在此基础上增加栈(Task)大小 // 补充:tskIDLE_PRIORITY,指loop()的优先级,其他任务需要在此基础上提高优先级 //==================================================================================================== // 创建vLEDFlashTask_1 xTaskCreate(vLEDFlashTask_1, "Task1", configMINIMAL_STACK_SIZE + 50, NULL, tskIDLE_PRIORITY + 3, NULL); // 创建vLEDFlashTask_2 xTaskCreate(vLEDFlashTask_2, "Task2", configMINIMAL_STACK_SIZE + 50, NULL, tskIDLE_PRIORITY + 2, NULL); // 创建vPrintTask xTaskCreate(vPrintTask, "Task3", configMINIMAL_STACK_SIZE + 100, NULL, tskIDLE_PRIORITY + 1, NULL); // 启动 FreeRTOS vTaskStartScheduler(); while(1); } //------------------------------------------------------------------------------ void loop() { while(1) { noInterrupts(); count++;//每次+1 //loop()中不要写其他程序了,全部以任务的形式创建好,在setup()中配置后,RTOS会根据各自任务的优先级,调度运行 interrupts(); } } --------------------------------------------------------------------------------------------------------------------- 实验效果 ![]() 1:任务1,led每200ms闪烁一次,占空比1/3 2:任务2,led每200ms闪烁一次,占空比1/2 3:任务3,串口每1000ms打印一次count的值 代码 Blink1_Blink2_Print.zip |







[库的安装和示例]
【RTOS】在Arduino上跑个系统吧(多任务并行)【一】
https://mc.dfrobot.com.cn/thread-24089-1-1.html
[进阶程序解读]
【RTOS】在Arduino上跑个系统吧(多任务并行)【二】
https://mc.dfrobot.com.cn/thread-24100-1-1.html
.
.
.