打卡Ai8051U视频教程第八集-定时器周期性调度任务

基于1MS的时钟中断
void Timer0_Isr(void) interrupt 1 //1MS执行一次
{
Task_Marks_Handler_Callback(); //系统计时
}
如何建造.C 和.H文件

首先,是CONFIG.H头文件
#ifndef __CONFIG_H
#define __CONFIG_H
#include "ai8051u.h" //调用头文件
#include "stc32_stc8_usb.h" //调用头文件
#include "intrins.h" //d调用头文件
#define u8 unsigned char //8位无符号变量(0-255)
#define u16 unsigned int //16位无符号变量(0-65535)
void Sys_init(void); //函数声明
void Timer0_Init(void); //1毫秒@24.000MHz
#endif
接着设置输出端口方式,和定时器1MS
#include "config.h"
void Sys_init(void)
{
WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXFR = 1; //扩展寄存器(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
P0M1 = 0x00; P0M0 = 0x00;
P1M1 = 0x00; P1M0 = 0x00;
P2M1 = 0x00; P2M0 = 0x00;
P3M1 = 0x00; P3M0 = 0x00;
P4M1 = 0x00; P4M0 = 0x00;
P5M1 = 0x00; P5M0 = 0x00;
P6M1 = 0x00; P6M0 = 0x00;
P7M1 = 0x00; P7M0 = 0x00;
}
void Timer0_Init(void) //1毫秒@24.000MHz
{
TM0PS = 0x00; //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x30; //设置定时初始值
TH0 = 0xF8; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
}
再就是设置IO口功能
头文件
#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);
#endif
设置IO状态
#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)
{
if( P32 == 0 )
{
Key_Vol++;
if( Key_Vol==5 )
{
//按键按下的任务
printf( "按键单击\r\n" );
}
}
else
{
Key_Vol = 0;
}
}
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
扫描结构和数组,实现
task.c程序
#include "task.h"
#include "io.h"
static TASK_COMPONENTS Task_Comps[]=
{
//状态 计数 周期 函数
{0, 300, 300, LED0_Blink}, /* task 1 Period: 300ms /
{0, 600, 600, LED1_Blink}, / task 1 Period: 600ms /
{0, 900, 900, LED2_Blink}, / task 1 Period: 600ms /
{0, 10, 10, KEY_Task}, / task 1 Period: 600ms */
};
u8 Tasks_Max = sizeof(Task_Comps)/sizeof(Task_Comps[0]);
//========================================================================
// 函数: 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[i].TIMCount) /* If the time is not 0 /
{
Task_Comps[i].TIMCount--; / Time counter decrement /
if(Task_Comps[i].TIMCount == 0) / If time arrives */
{
/*Resume the timer value and try again /
Task_Comps[i].TIMCount = Task_Comps[i].TRITime;
Task_Comps[i].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[i].Run) /* If task can be run /
{
Task_Comps[i].Run = 0; / Flag clear 0 /
Task_Comps[i].TaskHook(); / Run task */
}
}
}
都准备好了,开始主程序
#include "config.h"
#include "task.h"
#include "io.h"
char *USER_DEVICEDESC = NULL;
char *USER_PRODUCTDESC = NULL;
char *USER_STCISPCMD = "@STCISP#";
void main(void)
{
Sys_init(); //系统初始化
usb_init(); //USB CDC 接口配置
IE2 |= 0x80; //使能USB中断
Timer0_Init(); //定时器初始化
EA = 1; //IE |= 0X80;
P40 = 0;
while (DeviceState != DEVSTATE_CONFIGURED); //等待USB完成配置
while(1)
{
if (bUsbOutReady) //如果接收到了数据
{
//USB_SendData(UsbOutBuffer,OutNumber); //发送数据缓冲区,长度(接收数据原样返回, 用于测试)
usb_OUT_done(); //
}
Task_Pro_Handler_Callback(); //执行功能函数
}
}
void Timer0_Isr(void) interrupt 1 //1MS执行一次
{
Task_Marks_Handler_Callback(); //系统计时
}