代码结构:
MySch.h 调度器公用头文件。
SCH.c 调度器内核程序。
MySch.c 实际应用主程序
LED_FLASH.c LED_FLASH.h 闪灯例子用户代码
硬件连接: PB0接一个灯
功能: 暂实现一个任务--灯1s间隔闪烁,用户可以自己加任务。(每一个任务消耗 7 bytes RAM)
//MySch.h : header file for the MySch project
//
#ifndef _SCH51_H_
#define _SCH51_H_
#ifndef __AVR_ATmega16__
#define __AVR_ATmega16__
#endif
#define OSC_FREQ (8000000UL)
//#define __MCU_CLOCK_FREQUENCY__ _8.0000_MHz
#include <io.h>
#include <wdt.h>
#include <sleep.h>
#include <Interrupt.h>
#include <sig-avr.h>
#include <inttypes.h>
/////////////////////////////////////////////////////////////////////////////
//MySch
// Misc #defines
#ifndef TRUE
#define FALSE 0
#define TRUE (!FALSE)
#endif
#define RETURN_NORMAL 0
#define RETURN_ERROR 1
///////////////////////////////////////////////////
//函数声明和任务结构体定义
// 定义调度器数据结构
// 每一个任务消耗 7 bytes RAM
typedef struct data
{
//定义函数类型指针,const关键字意思是这是一个指向flash的指针
const void (*pTask)(void);
uint16_t Delay; // 任务第一次被执行前的延迟时间,如果为0则立即执行
uint16_t Period; // 任务的执行间隔时间,如果为0,则只执行一次
uint8_t RunMe; // 任务执行标志为,1 等待执行,0 不需要执行
} sTask; //sTask是结构体变量
#endif
// 调度器内核
// 本文件所有函数
//*****************************************************
void SCH_Init_T0(void);
void SCH_Start(void);
void SCH_Manual_Timer0_Reload(void);
// 调度器对外部接口
void SCH_RUN_Tasks(void);
uint8_t SCH_Add_Task(const void (*pFunction)(void),
uint16_t DELAY,
uint16_t PERIOD);
uint8_t SCH_Delete_Task(uint8_t TASK_INDEX);
// 调度器支持的任务个数,用户在调用调度器的时候必须设置
#define SCH_MAX_TASKS 1
#include "MySch.h"
/////////////////////////////////////////////////////////////////////////////
//SCH.c 调度器内核函数
/*
***********************************************
* void SCH_Init_T0(void)
***********************************************
*/
void SCH_Init_T0(void)
{
TCCR0 = (1<<CS01)|(1<<CS00); //1024分频
uint8_t i;
for (i = 0; i < SCH_MAX_TASKS; i++)
{
SCH_Delete_Task(i); //清空任务组 }
// 定时器0,8位定时,手动重装
TIMSK &= 0xFD; // Clear all T0 bits (T1,2 left unchanged)
// 设置定时器0的初志
SCH_Manual_Timer0_Reload(); //填装函数
// Interrupt Timer 0 enabled
TIMSK |= 0x01;
}
/*
************************************************
* void SCH_Start(void)
***********************************************
*/
void SCH_Start(void)
{
sei(); //开启全局中断
}
/*
************************************************************
*
* void SCH_Update(void) interrupt INTERRUPT_Timer_0_Overflow
*
*************************************************************
*/
SIGNAL(SIG_OVERFLOW0)
{
uint8_t Index;
SCH_Manual_Timer0_Reload();
for ( Index = 0; Index < SCH_MAX_TASKS; Index++ )
{
if (SCH_tasks_G[Index].pTask)
{
//**********************************************************
if (SCH_tasks_G[Index].Delay == 0) //如果延时为0
{
// 给可以被调度的任务设置标志位
// 说明:任务运行标志位不具有存储功能,也就是说,如果在规定的
// 间隔内没有被运行,则机会丧失
SCH_tasks_G[Index].RunMe += 1; // //置位运行标志位
if (SCH_tasks_G[Index].Period)//将任务需要的延时装入
{
SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period;
}
}
//************************************************************
else
{
SCH_tasks_G[Index].Delay -= 1;//延时-1
}
//************************************************************
}
}
}
/*
************************************************************
*
* void SCH_Manual_Timer0_Reload()
*
*************************************************************
*/
void SCH_Manual_Timer0_Reload()
{
// Stop timer
TCNT0=0X83; //64分频下1ms
}
/*
************************************************************
*
* void SCH_RUN_Tasks(void)
*
************************************************************
*/
void SCH_RUN_Tasks(void)
{
uint8_t Index;
// 调度器调度任务
for (Index = 0; Index < SCH_MAX_TASKS; Index++)
{
if (SCH_tasks_G[Index].RunMe > 0)
{
(*SCH_tasks_G[Index].pTask)(); // 运行任务
SCH_tasks_G[Index].RunMe -= 1; // 清除任务标志位
// 如果任务只要求运行一次,则删除任务
if (SCH_tasks_G[Index].Period == 0)
{
SCH_Delete_Task(Index);
}
}
}
}
/*
************************************************************
*
* uchar SCH_Add_Task
*
*************************************************************
*/
uint8_t SCH_Add_Task( const void (*pFunction)(void),
uint16_t DELAY,
uint16_t PERIOD)
{
uint8_t Index = 0;
while ((SCH_tasks_G[Index].pTask != 0) && (Index < SCH_MAX_TASKS))
{
Index++;
}
// Have we reached the end of the list?
if (Index == SCH_MAX_TASKS)
{
// Task list is full
return SCH_MAX_TASKS;
}
// If we're here, there is a space in the task array
SCH_tasks_G[Index].pTask = pFunction;
SCH_tasks_G[Index].Delay = DELAY;
SCH_tasks_G[Index].Period = PERIOD;
SCH_tasks_G[Index].RunMe = 0;
return Index; // return position of task (to allow later deletion)
}
/*
************************************************************
*
* uint8_t SCH_Delete_Task(const uchar TASK_INDEX)
*
*************************************************************
*/
uint8_t SCH_Delete_Task( uint8_t TASK_INDEX)
{
SCH_tasks_G[TASK_INDEX].pTask = 0x0000;
SCH_tasks_G[TASK_INDEX].Delay = 0;
SCH_tasks_G[TASK_INDEX].Period = 0;
SCH_tasks_G[TASK_INDEX].RunMe = 0;
return 0; // return status
}
//MySch.c : source file for the MySch project //
#include "MySch.h"
///////////////////////////////////////////////////////////////////////////// //MySch 主程序 extern const void LED_Flash_Update(void); //用于闪灯,实际中可代替 extern void LED_Flash_Init(void); //用于闪灯,实际中可代替 static void io_init(void) { //{{WIZARD_MAP(General) //}}WIZARD_MAP(General)
//{{WIZARD_MAP(I/O Ports) // PortA PORTA = 0x0; DDRA = 0x0; // PortB PORTB = 0x01; DDRB = 0x01; // PortC PORTC = 0x0; DDRC = 0x0; // PortD PORTD = 0x0; DDRD = 0x0; //}}WIZARD_MAP(I/O Ports)
//{{WIZARD_MAP(Watchdog) // Watchdog Disabled wdt_disable(); //}}WIZARD_MAP(Watchdog)
//{{WIZARD_MAP(Analog Comparator) // Analog Comparator Disabled ACSR = 0x80; //}}WIZARD_MAP(Analog Comparator) }
int main(void) { //{{WIZARD_MAP(Initialization) io_init(); //}}WIZARD_MAP(Initialization) // TODO: Add extra initialization here //{{WIZARD_MAP(Global interrupt) //}}WIZARD_MAP(Global interrupt) SCH_Init_T0(); LED_Flash_Init(); //用于闪灯,实际中可代替 SCH_Add_Task(LED_Flash_Update, 0, 1000); //用于闪灯,实际中可代替LED_Flash_Update SCH_Start(); while(1) { SCH_RUN_Tasks(); // TODO: Add your code here } } |
|
文章评论(0条评论)
登录后参与讨论