YangHY 发表于 2026-1-14 19:46:46

新建task.c文件:

#include "task.h"


//========================================================================
//                               本地变量声明
//========================================================================

static TASK_COMPONENTS Task_Comps[]=
{

          {0, 300, 300, LED0_Blink},      /* task 1 Period: 300ms 调用1次 */
          {0, 600, 600, LED1_Blink},      /* task 1 Period: 600ms 调用1次*/
          {0, 900, 900, LED2_Blink},      /* task 1 Period: 900ms 调用1次*/
      {0, 10, 10, KEY_Task},          /* task 1 Period:10ms调用1次 */

    /* Add new task here */
};


u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps);

//========================================================================
// 函数: Task_Handler_Callback
// 描述: 任务标记回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Marks_Handler_Callback(void)
{
    u8 i;
    for(i=0; i<Tasks_Max; i++)
    {
      if(Task_Comps.TIMCount)      /* If the time is not 0 */
      {
            Task_Comps.TIMCount--;   /* Time counter decrement */
            if(Task_Comps.TIMCount == 0) /* If time arrives */
            {
                /*Resume the timer value and try again */
                Task_Comps.TIMCount = Task_Comps.TRITime;
                Task_Comps.Run = 1;      /* The task can be run */
            }
      }
    }
}

//========================================================================
// 函数: Task_Pro_Handler_Callback
// 描述: 任务处理回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Pro_Handler_Callback(void)
{
    u8 i;
    for(i=0; i<Tasks_Max; i++)
    {
      if(Task_Comps.Run) /* If task can be run */
      {
            Task_Comps.Run = 0;      /* Flag clear 0 */
            Task_Comps.TaskHook();   /* Run task */
      }
    }
}

YangHY 发表于 2026-1-14 19:48:51

接着建立task.h文件:

#ifndef __TASK_H
#define __TASK_H

#include "config.h"                        //调用头文件

//========================================================================
//                               本地变量声明
//========================================================================

typedef struct
{
        u8 Run;               //任务状态:Run/Stop
        u16 TIMCount;         //定时计数器
        u16 TRITime;          //重载计数器
        void (*TaskHook) (void); //任务函数
} TASK_COMPONENTS;      

//========================================================================
//                           外部函数和变量声明
//========================================================================

void Task_Marks_Handler_Callback(void);
void Task_Pro_Handler_Callback(void);




#endif

YangHY 发表于 2026-1-14 20:07:57

这里是参考STC的例子来讲解

其实是蛮容易错的,值得反复聆听

接着把有关按键和LED的归类为io.c:

#include "io.h"

u8 State1 = 0;                                        //LED1初始状态
u8 State2 = 0;                                        //LED2初始状态
u8 State3 = 0;                                        //LED3初始状态

u16 Key_Vol = 0; //按键按下持续时间

void LED0_Blink (void)
{
                State1= !State1;
                P00 = State1;
       
}
       

void LED1_Blink (void)
{
                State2= !State2;
                P01 = State2;
}

void LED2_Blink (void)
{
                State3= !State3;
                P02 = State3;

}

void KEY_Task (void)   //按键单击任务,属于IO口
{
        if(P32 == 0)
        {
                Key_Vol++;
                if(Key_Vol == 5)
                {
                                //P32按键按下任务
                        printf("P32按键单击\r\n");
               
                }
               
        }
        else
        {
                Key_Vol = 0;
        }

}

YangHY 发表于 2026-1-14 20:08:56

马上创建对应的io.h:

#ifndef __IO_H
#define __IO_H

#include "config.h"                        //调用头文件

void LED0_Blink (void);//函数声明
void LED1_Blink (void);//函数声明
void LED2_Blink (void);//函数声明

void KEY_Task (void); ////函数声明按键单击任务,属于IO口


#endif

YangHY 发表于 2026-1-14 20:15:15

对应的task.c 也要改写:

#include "task.h"


//========================================================================
//                               本地变量定义
//========================================================================

static TASK_COMPONENTS Task_Comps[]=
{

          {0, 300, 300, LED0_Blink},      /* task 1 Period: 300ms 调用1次 */
          {0, 600, 600, LED1_Blink},      /* task 1 Period: 600ms 调用1次*/
          {0, 900, 900, LED2_Blink},      /* task 1 Period: 900ms 调用1次*/
      {0, 10, 10, KEY_Task},          /* task 1 Period:10ms调用1次 */

    /* Add new task here */
};


u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps);

//========================================================================
// 函数: Task_Handler_Callback
// 描述: 任务标记回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Marks_Handler_Callback(void)
{
    u8 i;
    for(i=0; i<Tasks_Max; i++)
    {
      if(Task_Comps.TIMCount)      /* If the time is not 0 */
      {
            Task_Comps.TIMCount--;   /* Time counter decrement */
            if(Task_Comps.TIMCount == 0) /* If time arrives */
            {
                /*Resume the timer value and try again */
                Task_Comps.TIMCount = Task_Comps.TRITime;
                Task_Comps.Run = 1;      /* The task can be run */
            }
      }
    }
}

//========================================================================
// 函数: Task_Pro_Handler_Callback
// 描述: 任务处理回调函数.
// 参数: None.
// 返回: None.
// 版本: V1.0, 2012-10-22
//========================================================================
void Task_Pro_Handler_Callback(void)
{
    u8 i;
    for(i=0; i<Tasks_Max; i++)
    {
      if(Task_Comps.Run) /* If task can be run */
      {
            Task_Comps.Run = 0;      /* Flag clear 0 */
            Task_Comps.TaskHook();   /* Run task */
      }
    }
}

YangHY 发表于 2026-1-14 20:25:46

这样的简单结构性数组周期性任务调度

要好好理解:

下面介绍虚拟设备:

YangHY 发表于 2026-1-14 20:27:33

没有课后作业,主要是认真阅读结构体数组的周期性任务程序结构

这个其实难度蛮大

YangHY 发表于 2026-1-15 21:40:46

今天继续复习第九集 数码管

YangHY 发表于 2026-1-15 21:44:10

数码管种类很多

数码管也叫LED数码管,内部是由多个发光二极管封装在一起组成,他们可以有很多种颜色,很多种外形,很多种样式,但是本质来说他们都是通过点亮内部的LED来显示的只要面板做好了,理论可以显示任意的字符或者图案。

YangHY 发表于 2026-1-15 21:46:04

以这种最普通的数码管来说,一个我们称之为1位数码管,两个"8"就是2位数码管:以此类惟

可以显示的内容:

页: 55 56 57 58 59 60 61 62 63 64 [65] 66 67 68 69 70 71 72 73 74
查看完整版本: 第一课 序言《AI8051U的特点》