原创 调度器3

2011-3-15 11:27 4639 4 4 分类: 电源/新能源
代码结构:
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
        
    }
}
 



PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
4
关闭 站长推荐上一条 /3 下一条