⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sch.c

📁 该代码为基于AVR单片机的时间调度软件开发模板
💻 C
字号:
/*------------------------------------------------------------------*-
版权说明:
		1、此程序应称作“时间触发多任务调度器”。
		
		2、程序摘自《时间触发嵌入式系统设计模式
			使用8051系统微控制器开发可靠应用》。
			在本站好书推荐中有对此书的说明。
			
		3、原作者在书中对版权进行了说明:
			只要购买了本书就可以使用书中源程序。
			
		4、在项目中多次用到此程序,感觉很不错。
			此处提供的调度器程序是我简化过的。

移植说明:
		1、代码全部用标准C语言编写,可以方便的插
			入到项目中。
			
		2、内核唯一需要硬件支持的是定时器,需要开
			一个定时器,为内核提供调度周期信号。

-*------------------------------------------------------------------*/

#include "AFA.h"

s_task SCH_task_array[SCH_MAX_TASKS];						/*定义任务队列					*/


/*------------------------------------------------------------------*-
	SCH_Init_Time()
	调度器初始化
	
	1、准备调度器数据结构并且设置定时器以所需的
		频率中断。
	2、必须在使用调度器之前调用这个函数。
-*------------------------------------------------------------------*/
void SCH_Init_Time(void) {

	uint8 i;
	
	for (i = 0; i < SCH_MAX_TASKS; i++) {					/*清空任务队列					*/
		SCH_Delete_Task(i);
		}

	OCR1A = 1250;											/*计数周期为10mS,F=1M*/
	TIMSK1 = 0x02;											/*比较中断A允许					*/
	SREG = 0x80;
	TCCR1A = 0x00;
	TCCR1B = 0x08;											/*运行于CTC模式					*/
	TCCR1B |= 0x02;											/*设置8分频						*/
}

/*------------------------------------------------------------------*-
	SCH_Start()
	启动调度器
	
	1、启动调度器,也就允许调度器运行。
	2、主要是允许中,因为任务状态是在中断中
		刷新的。
-*------------------------------------------------------------------*/
void SCH_Start(void) {

	SEI();													/*开全局中断					*/
}

/*------------------------------------------------------------------*-
	SCH_Add_Task()
	任务添加
	
	1、将任务添加到任务队列中,并设置执行条件。
	2、任务添加成功将返回,任务被添加的位置。
	3、任务添加失败将返回0。
	4、变量说明:
		pFunction	函数指针,指向要添加的函数。
		delay		任务运行等待时间。
		period		任务运行周期时间,此处用于需要
					周期性运行的任务。
					如只要运行一次,则此值应为0
-*------------------------------------------------------------------*/
uint8 SCH_Add_Task(void (* pFunction)(), uint16 delay, uint16 period) {
	
	static uint8 i = 0;
	
	while ((SCH_task_array[i].task != 0) && (i < SCH_MAX_TASKS)) {
		i++;
		}
	if (i == SCH_MAX_TASKS) {								/*检查任务队列溢出				*/
		return 0;											/*溢出处理						*/
		}
	SCH_task_array[i].task		= pFunction;				/*加载任务						*/
	SCH_task_array[i].delay		= delay;
	SCH_task_array[i].period	= period;
	SCH_task_array[i].run		= 0x00;
	
	return i;												/*返回任务ID号					*/
}

/*------------------------------------------------------------------*-
	SCH_Update()
	任务刷新
	
	1、定时器T1,A组比较中断。
	2、对任务定时时间进行刷新。
	3、任务定时时间到,设置任务运行标志。
-*------------------------------------------------------------------*/
#pragma interrupt_handler SCH_Update: 12
void SCH_Update(void) {

	static uint8 i;

	for (i = 0; i < SCH_MAX_TASKS; i ++) {
		if (SCH_task_array[i].task) {						/*检测任务是否存在				*/
			if (SCH_task_array[i].delay != 0) {				/*刷新任务等待时间				*/
				SCH_task_array[i].delay --;
				}
			if (SCH_task_array[i].delay == 0) {				/*任务时间是否到				*/
				SCH_task_array[i].run += 1;					/*设置运行标志					*/
				
				if (SCH_task_array[i].period) {				/*是否为循环任务				*/
					SCH_task_array[i].delay = SCH_task_array[i].period;
					}										/*重载任务定时器				*/
				}
			}
		}
}

/*------------------------------------------------------------------*-
	SCH_Dispatch_Tasks()
	任务调度
	
	1、调度程序,当任务需要运行时,由本程序调用。
	2、这个函数必须重复运行。
-*------------------------------------------------------------------*/
void SCH_Dispatch_Tasks(void)   {
	
	static uint8 i;
	
	for (i = 0; i < SCH_MAX_TASKS; i++) {					/*查询任务队列					*/
		if (SCH_task_array[i].run > 0) {
			(*SCH_task_array[i].task)();					/*运行任务						*/
			SCH_task_array[i].run --;						/*运行标志自减					*/
			
			if (SCH_task_array[i].period == 0) {			/*删除单周期任务				*/
				SCH_Delete_Task(i);
				}
			}
		}
}

/*------------------------------------------------------------------*-
	SCH_Delete_Task()
	任务删除
	
	1、删除指定任务。
	2、要删除任务的ID,此ID在任务添加时给出。
-*------------------------------------------------------------------*/
void SCH_Delete_Task(uint8 task_id) {
	
	SCH_task_array[task_id].task	= 0x00;					/*清除任务						*/
	SCH_task_array[task_id].delay	= 0x00;
	SCH_task_array[task_id].period	= 0x00;
	SCH_task_array[task_id].run		= 0x00;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -