用合作式時間觸發的方法對C51進行編程,模擬調試的時候可以通過,在線編譯就出錯。編譯器用的是星研的star51ph。請高手指點問題出在哪里?
/*==============================================================
1ms時標的合作式調度器(多個合作式任務)
作者:shadow.hu
時間:2008-4-23
===============================================================*/
#include<reg52.h>
#define uchar unsigned char
#define ushort unsigned short
#define SCH_MAX_TASKS 5
#define SCHTASKS (1)
#define INTERRPT_Timer_2_Overflow 5
#define ERROR_SCH_TOO_MANY_TASKS 6
#define ERROR_SCH_CANOT_DELETE_TASK 1
#define RETURN_ERROR 0
#define RETURN_NORMAL 1
#define SCH_REPORT_ERRORS
#ifdef SCH_REPORT_ERRORS
#define Error_Port P1
#endif
typedef data struct
{
void (code *pTask)(void);
ushort Delay;
ushort Period;
ushort RunMe;
}sTask;
sTask SCH_tasks_G[SCH_MAX_TASKS];
void SCH_Init_T2(void);
uchar SCH_Add_Task(void (code * pFunction)(),const ushort Delay, ushort PERIOD);
void SCH_Dispatch_Tasks(void);
void SCH_Start(void);
bit SCH_Delete_Task(const ushort TASK_INDEX);
void SCH_Go_To_Sleep(void);
void SCH_Report_Status(void);//報告系統狀況
void LED_Flash_Init(void);
void LED_Flash_Update(void);
uchar Error_code_G = 0;
uchar LED_State_G = 0;
sbit LED_pin = P1^7;
//Error_code_G = ERROR_SCH_TOO_MANY_TASKS;
//Error_code_G = ERROR_SCH_WAITING_FOR_SLAVE_TO_ACK;
//Error_code_G = ERROR_SCH_WAITING_FOR_START_COMAND_FROM_MASTER;
//Error_code_G = ERROR_SCH_ONE_OR_MORE_SLAVES_DID_NOT_START;
//Error_code_G = ERROR_SCH_LOST_SLAVE;
//Error_code_G = ERROR_SCH_CAN_BUS_ERROR;
//Error_code_G = ERROR_I2C_WRITE_BYTE_AT24C64;
void main(void)
{
SCH_Init_T2();
LED_Flash_Init();
SCH_Add_Task(LED_Flash_Update,0,1000);
SCH_Start();
while(1)
{
SCH_Dispatch_Tasks();
}
}
void SCH_Update(void) interrupt INTERRPT_Timer_2_Overflow
{
//刷新任務隊列
uchar Index;
TF2 = 0;
for(Index = 0;Index < SCH_MAX_TASKS;Index++)
{
if(SCH_tasks_G[Index].pTask)
{
if(SCH_tasks_G[Index].Delay == 0)
{
//任務需要運行
SCH_tasks_G[Index].RunMe += 1;
if(SCH_tasks_G[Index].Period)
{
//調度周期性的任務再次運行
SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period;
}
}
else
{
//還沒有準備好運行,延遲減1
SCH_tasks_G[Index].Delay -= 1;
}
}
}
}
void SCH_Init_T2(void)
{
uchar i;
for(i=0;i<SCH_MAX_TASKS;i++)
{
SCH_Delete_Task(i);
}
Error_code_G = 0;
T2CON = 0x04;
TMOD = 0x00;
TH2 = 0xfc;
RCAP2H = 0xfc;
TL2 = 0x18;
RCAP2L = 0x18;
ET2 = 1;
TR2 = 1;
}
uchar SCH_Add_Task(void (code * pFunction)(),const ushort DELAY, ushort PERIOD)
{
uchar Index = 0;
while((SCH_tasks_G[Index].pTask != 0)&&(Index < SCH_MAX_TASKS))
{
Index++;
}
if(Index == SCH_MAX_TASKS)
{
Error_code_G = ERROR_SCH_TOO_MANY_TASKS;
return SCH_MAX_TASKS;
}
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;//返回任務的位置
}
void SCH_Dispatch_Tasks(void)
{
uchar 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);
}
}
SCH_Report_Status();//報告系統狀況
SCH_Go_To_Sleep();
}
void SCH_Start(void)
{
EA = 1;
}
bit SCH_Delete_Task(const ushort TASK_INDEX)
{
bit Return_code;
if(SCH_tasks_G[TASK_INDEX].pTask == 0)
{
Error_code_G = ERROR_SCH_CANOT_DELETE_TASK;
Return_code = RETURN_ERROR;
}
else
{
Return_code = RETURN_NORMAL;
}
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 Return_code;
}
void SCH_Go_To_Sleep()
{
PCON |= 0x01;
}
void SCH_Report_Status(void)
{
/* #ifdef SCH_REPORT_ERRORS
if(Error_code_G != Last_error_code_G)
{
Error_Port = 255 - Error_code_G;
Last_error_code_G = Error_code_G;
if(Error_code_G != 0)
{
Error_tick_count_G = 60000;
}
else
{
Error_tick_count_G = 0;
}
}
else
{
if(Error_tick_count_G != 0)
{
if(--Error_count_G == 0)
{
Error_code_G = 0;
}
}
}
#endif */
}
void LED_Flash_Update(void)
{
if(LED_State_G == 1)
{
LED_State_G = 0;
LED_pin = 0;
}
else
{
LED_State_G = 1;
LED_pin = 1;
}
}
void LED_Flash_Init(void)
{
LED_State_G= 0;
}
歡迎光臨 (http://www.raoushi.com/bbs/) | Powered by Discuz! X3.1 |