找回密码
 立即注册
楼主: 王昱顺

最佳入门多线程示例讲解-核心代码简单易懂,仅44行代码

[复制链接]
  • 打卡等级:常住居民II
  • 打卡总天数:82
  • 最近打卡:2024-11-16 13:05:25

10

主题

103

回帖

460

积分

中级会员

积分
460
发表于 2024-3-28 07:48:55 来自手机 | 显示全部楼层
王昱顺 发表于 2024-3-27 23:54
其实是每个case中只能调用一次,多个case可以多次调用delay的,不过调用delay后需要间隔2个数值,比如说c ...

没错,我上传的修改的代码也是这样实现的,让其他人使用时有个参考。如果代码有什么问题,请帮忙指正。

点评

没啥问题了,这个状态机的灵活性不仅仅是多个Delay,还可以通过条件直接指定Task_This[Task]的值,完成不同方向的跳转。类似于goto的效果。甚至于还可以从其他的线程操作另一个线程调到不同的步  详情 回复 发表于 2024-3-28 08:42
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:497
  • 最近打卡:2025-04-30 20:48:13
已绑定手机

151

主题

589

回帖

1196

积分

金牌会员

积分
1196
发表于 2024-3-28 08:37:11 | 显示全部楼层
hais*** 发表于 2024-3-27 23:42
楼主,再次表示感谢,我下载了你的代码。

我看到有一楼提到了每个任务只能调用delay函数一次,你的回复是 ...

改了之后,更好移植了,
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:458
  • 最近打卡:2025-05-01 07:48:22
已绑定手机
已实名认证

110

主题

2218

回帖

5450

积分

版主

积分
5450
发表于 2024-3-28 08:42:42 | 显示全部楼层
hais*** 发表于 2024-3-28 07:48
没错,我上传的修改的代码也是这样实现的,让其他人使用时有个参考。如果代码有什么问题,请帮忙指正。 ...

没啥问题了,这个状态机的灵活性不仅仅是多个Delay,还可以通过条件直接指定Task_This[Task]的值,完成不同方向的跳转。类似于goto的效果。甚至于还可以从其他的线程操作另一个线程调到不同的步
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:82
  • 最近打卡:2024-11-16 13:05:25

10

主题

103

回帖

460

积分

中级会员

积分
460
发表于 2024-3-28 12:39:31 来自手机 | 显示全部楼层
王昱顺 发表于 2024-3-28 08:42
没啥问题了,这个状态机的灵活性不仅仅是多个Delay,还可以通过条件直接指定Task_This[Task]的值,完成不 ...

灵活性和易用性总是有些矛盾,你说的后面两个用法,就要更多的将业务逻辑和这个系统耦合了。就是相对高级的用法了。就像uCOS里的Task之间的处理。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民II
  • 打卡总天数:83
  • 最近打卡:2024-09-30 23:22:51

0

主题

118

回帖

248

积分

中级会员

积分
248
发表于 2024-4-10 14:07:40 | 显示全部楼层
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:394
  • 最近打卡:2025-05-01 03:26:07

16

主题

702

回帖

2470

积分

金牌会员

积分
2470
发表于 2024-4-10 15:51:40 | 显示全部楼层
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:1
  • 最近打卡:2024-04-29 06:31:15

1

主题

1

回帖

25

积分

新手上路

积分
25
发表于 2024-4-29 06:30:55 | 显示全部楼层
这个结构好玩,对MCU没有太大要求。小ROM也可以使用。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:497
  • 最近打卡:2025-04-30 20:48:13
已绑定手机

151

主题

589

回帖

1196

积分

金牌会员

积分
1196
发表于 2024-4-29 08:14:18 | 显示全部楼层
minica*** 发表于 2024-4-29 06:30
这个结构好玩,对MCU没有太大要求。小ROM也可以使用。

是的,这个很不错,
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:419
  • 最近打卡:2025-05-01 07:24:50

4

主题

511

回帖

1991

积分

金牌会员

积分
1991
发表于 2024-6-29 10:17:57 | 显示全部楼层
示例程序,要和坛里的其他版的一样;
有STC8   一份示例程序;
有STC32   一份示例程序;
这样,才好,不然,只有stc32板子的坛友,只能干看,
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:419
  • 最近打卡:2025-05-01 07:24:50

4

主题

511

回帖

1991

积分

金牌会员

积分
1991
发表于 2024-6-29 16:23:10 | 显示全部楼层
本帖最后由 科学*** 于 2024-6-29 16:25 编辑

科学妞妞 发表于 2024-6-29 10:17
示例程序,要和坛里的其他版的一样;
有STC8   一份示例程序;
有STC32   一份示例程序;

#include <STC32G.h>
//#define MAIN_Fosc                24000000L        //定义主时钟

typedef unsigned char u8;                                //unsigned char                 类型用 u8 表示
typedef unsigned int u16;                                //unsigned int                  类型用 u16表示
typedef unsigned long int u32;        //unsigned long int 类型用 u32表示

sbit LED1 = P2^0;                //引脚定义:LED1->P20
sbit LED2 = P2^1;                //引脚定义:LED2->P21

// 多线程功能定义如下:
#define Task_Max 10             // 最大线程数
u8 Task = 0;                    // 全局线程指针
u8 Task_This[Task_Max] = {0};   // 线程状态表
u16 Task_Timer[Task_Max] = {0}; // 线程私有定时器

// 函数声明如下:
void Core_Init(void);           
void Delay(unsigned int Time);
void Get_Delay(void);

//主运行函数如下:
void main(void)
{
    EAXFR = 1;                         // 使能访问 XFR
                CKCON = 0x00;         // 设置外部数据总线速度为最快
                WTST = 0x00;                // 设置程序代码等待参数,等待时间为0个时钟,CPU执行程序速度最快

                P0M1 = 0x00;P0M0 = 0x00;                //设置P0口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
                P1M1 = 0x00;P1M0 = 0x00;                //设置P1口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
                P2M1 = 0x00;P2M0 = 0xFF;                //设置P2口为推挽输出模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
                P3M1 = 0x00;P3M0 = 0x00;                //设置P3口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
                P4M1 = 0x00;P4M0 = 0x00;                //设置P4口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
                P5M1 = 0x00;P5M0 = 0x00;                //设置P5口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
                P6M1 = 0x00;P6M0 = 0x00;                //设置P6口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
                P7M1 = 0x00;P7M0 = 0x00;                //设置P7口为准双向口模式 //00:准双向口 01:推挽输出 10:高阻输入 11:开漏输出
       
                Core_Init();
                EA = 1;                                                //使能总中断       
               
    while (1)
    {
                        Task = 1;// 线程1开始
        switch (Task_This[Task])
        {
        case 0:
            LED1 = ~LED1, Delay(100);
            break;
        case 2:                  // 进入Delay会自动跳下一个数字并进行等待,所以完成延时已经是下下个数字了
            Task_This[Task] = 0; // 回到最初的状态
            break;
        default:
            Get_Delay();
            break;
        }
                       

                                Task = 2;// 线程1开始
        switch (Task_This[Task])
        {
        case 0:
            LED2 = ~LED2, Delay(350);//换一个灯闪烁,并且不同频率
            break;
        case 2:                  // 进入Delay会自动跳下一个数字并进行等待,所以完成延时已经是下下个数字了
            Task_This[Task] = 0; // 回到最初的状态
            break;
        default:
            Get_Delay();
            break;
        }
                }
}

// 初始化定时及核心功能
void Core_Init(void)
{
    AUXR |= 0x80; // 定时器时钟1T模式
    TMOD &= 0xF0; // 设置定时器模式
    TL0 = 0x40;   // 设置定时初始值@24MHz,1ms
    TH0 = 0xA2;   // 设置定时初始值
    TF0 = 0;      // 清除TF0标志
    TR0 = 1;      // 定时器0开始计时
    ET0 = 1;      // 使能定时器0中断
    EA = 1;
}

void Timer0_Isr(void) interrupt 1
{
    u8 xdata i;
    // 遍历所有线程定时器
    for (i = 0; i < Task_Max; i++)
    {
        if (Task_Timer > 0)
        {
            Task_Timer--;
        }
    }
}

// 设置非堵塞定时,刻度1ms
void Delay(unsigned int Time)
{
    Task_Timer[Task] = Time;
    Task_This[Task]++;
}

// 获取当前定时器状态
void Get_Delay(void)
{
    if (Task_Timer[Task] == 0)
    {
        Task_This[Task]++;
    }
}
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-1 19:36 , Processed in 0.214045 second(s), 116 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表