AI8051U单片机的 伪多任务 极简框架

实现功能
- 每个任务都有一个预定的周期
- 每个任务都有一个与之关联的计数器
- 递增的计数器作为系统时间
- 比较式任务调度
- 伪非阻塞式任务运行

先看框架
- // 定义任务函数
- void task1();
- void task2();
- void task3();
-
- // 定义任务周期(单位:毫秒)
- #define TASK1_PERIOD 100
- #define TASK2_PERIOD 50
- #define TASK3_PERIOD 200
-
- // 定义任务计数器
- volatile unsigned int task1_counter = 0;
- volatile unsigned int task2_counter = 0;
- volatile unsigned int task3_counter = 0;
-
- // 主循环
- void main() {
- // 初始化计数器
- task1_counter = TASK1_PERIOD;
- task2_counter = TASK2_PERIOD;
- task3_counter = TASK3_PERIOD;
-
- // 主循环
- while (1) {
- // 模拟一个循环中的任务调度
- taskScheduler();
- }
- }
-
- // 任务调度函数
- void taskScheduler() {
- static unsigned int system_tick = 0; // 系统计数器
-
- // 更新系统计数器
- system_tick++;
-
- // 检查任务1是否准备好执行
- if (system_tick >= task1_counter) {
- task1_counter += TASK1_PERIOD;
- task1();
- }
-
- // 检查任务2是否准备好执行
- if (system_tick >= task2_counter) {
- task2_counter += TASK2_PERIOD;
- task2();
- }
-
- // 检查任务3是否准备好执行
- if (system_tick >= task3_counter) {
- task3_counter += TASK3_PERIOD;
- task3();
- }
- }
-
- // 任务1
- void task1() {
- // 执行任务1的代码
- // 例如控制LED闪烁
- // ...
- }
-
- // 任务2
- void task2() {
- // 执行任务2的代码
- // 例如读取传感器数据
- // ...
- }
-
- // 任务3
- void task3() {
- // 执行任务3的代码
- // 例如更新显示屏显示
- // ...
- }
复制代码
再看实测演示
测试代码
- #include <STC8051U.H>
- #include "intrins.h"
- #include "stc32_stc8_usb.h"
- #include "ST7735.h"
- #include <stdio.h>
- #include "AHT25.h"
- #include "key.h"
- #include "delay.h"
-
- #define FOSC 24000000UL //ISP 下载时需将工作频率设置为 24MHz
- char *USER_DEVICEDESC = NULL;
- char *USER_PRODUCTDESC = NULL;
- char *USER_STCISPCMD = "@STCISP#"; //不停电自动 ISP 下载命令
-
- #define POWER_IO P10
-
- int num_A = 0;
- int num_M = 0;
- int num_B = 0;
-
- char buf[30] = {0};
-
- volatile float tem;
- volatile float hum;
-
- #define POWER_ON POWER_IO = 1;
- #define POWER_OFF POWER_IO = 0;
-
- // 任务调度函数
- void taskScheduler();
-
- // 定义任务函数
- void task1(); //按键检测
- void task2(); //读温湿度
- void task3(); //更新显示
-
- // 定义任务周期(单位:毫秒)
- #define TASK1_PERIOD 50
- #define TASK2_PERIOD 500
- #define TASK3_PERIOD 200
-
- // 定义任务计数器
- volatile unsigned int task1_counter = 0;
- volatile unsigned int task2_counter = 0;
- volatile unsigned int task3_counter = 0;
-
- void main()
- {
- EAXFR = 1;
- WTST = 0X00;
- CKCON = 0X00;
-
- //POWER_IO 0: 关机 1:开机 推挽输出
- P1M0 |= 0x01;
- P1M1 &= ~0x01;
-
- POWER_ON
-
- //POWER_KEY 0:按键没按下,即充电开机 1:按开机 下拉输入
- P4M0 &= ~0x04;
- P4M1 &= ~0x04;
- P4PD |= 0x04;
-
-
- //tft 推挽输出
- P3M0 |= 0xc0;
- P3M1 &= ~0xc0;
- P1M0 |= 0xa0;
- P1M1 &= ~0xa0;
-
- //KEY_A KEY_M KEY_B 下拉输入
- P1M0 &= ~0x1c;
- P1M1 |= 0x1c;
- P1PD |= 0x1c;
-
- //SCL 推挽输出
- P2M0 |= 0x10;
- P2M1 &= ~0x10;
- //SDA 准双向IO口
- P2M0 &= ~0x08;
- P2M1 &= ~0x08;
-
- //USB_CDC
- P3M0 &= ~0x03; //P3.0/P3.1 和 USB 的 D-/D+共用 PIN 脚,
- P3M1 |= 0x03; //需要将 P3.0/P3.1 设置为高阻输入模式
- IRC48MCR = 0x80; //使能内部 48M 的 USB 专用 IRC
- while (!(IRC48MCR & 0x01));
- USBCLK = 0x00; //设置 USB 时钟源为内部 48M 的 USB 专用 IRC
- USBCON = 0x90; //使能 USB 功能
- usb_init(); //调用 USB CDC 初始化库函数
- IE2 |= 0x80; //使能 USB 中断
- EA = 1;
-
- ST7735_Init();
-
- // 初始化计数器
- task1_counter = TASK1_PERIOD;
- task2_counter = TASK2_PERIOD;
- task3_counter = TASK3_PERIOD;
-
- while(1)
- {
- taskScheduler();
- m_delay_ms(1);
- }
- }
-
-
- // 任务调度函数
- void taskScheduler() {
-
- static unsigned long int system_tick = 0; // 系统计数器 32位 49.7天溢出
-
- // 更新系统计数器
- system_tick++;
-
- // 检查任务1是否准备好执行
- if (system_tick >= task1_counter) {
- task1_counter += TASK1_PERIOD;
- task1();
- }
-
- // 检查任务2是否准备好执行
- if (system_tick >= task2_counter) {
- task2_counter += TASK2_PERIOD;
- task2();
- }
-
- // 检查任务3是否准备好执行
- if (system_tick >= task3_counter) {
- task3_counter += TASK3_PERIOD;
- task3();
- }
-
- }
-
- // 任务1
- void task1() {
- // 执行任务1的代码
- static unsigned char key_value;
- key_value = KEY_Scan(0);
- switch(key_value) {
- case A_PRES:
- num_A++;
- break;
- case M_PRES:
- num_M++;
- break;
- case B_PRES:
- num_B++;
- break;
- case POWER_PRES:
- POWER_OFF break;
- default:
- break;
- }
- }
-
- // 任务2
- void task2() {
- // 执行任务2的代码
- AHT10_Read(tem,hum);
- }
-
- // 任务3
- void task3() {
- // 执行任务3的代码
- sprintf(buf,"T:%.2f %d",tem,num_A);
- ST7735_WriteString(10,10,buf, Font_11x18,ST7735_GREEN,ST7735_BLACK);
- sprintf(buf,"H:%.2f %d",hum,num_B);
- ST7735_WriteString(10,40,buf, Font_11x18,ST7735_RED,ST7735_BLACK);
- }
复制代码

实验结果

待优化
|