📄 schedule.s
字号:
.module schedule.c
.area text(rom, con, rel)
.dbfile D:\_文档~1\easy-STQ-20080712\schedule.c
.dbfunc e SCH_Dispatch_Tasks _SCH_Dispatch_Tasks fV
; Index -> R20
.even
_SCH_Dispatch_Tasks::
xcall push_gset1
.dbline -1
.dbline 35
;
; #define SCHEDULE_GLOBAL
; #include "schedule.h"
;
;
; static void SCH_Updata(void);
;
;
; // 在任一时刻要求的任务最大数目
; #define SCH_MAX_TASKS (3)
;
; // 任务队列
; sTask SCH_tasks_G[SCH_MAX_TASKS];
;
; // 错误代码
; #define ERROR_SCH_TOO_MANY_TASKS (1)
; #define ERROR_SCH_CANNOT_DELETE_TASK (2)
;
; #define RETURN_NORMAL 0
; #define RETURN_ERROR 1
;
;
;
;
; /*---------------------------------------------------------*-
; * 函数名称: SCH_Dispatch_Tasks()
; * 入 口:
; * 出 口:
; * 函数功能: 调度函数,当一个任务()需要运行时,此函数将运行它,
; *
; * 说 明: 这个函数必须被主循环(重复)调用
; -*---------------------------------------------------------*/
;
; void SCH_Dispatch_Tasks(void)
; {
.dbline 39
; unsigned char Index;
;
; // 调度(运行)下一个任务(如果有任务就绪)
; for (Index=0; Index<SCH_MAX_TASKS; Index++)
clr R20
xjmp L8
L5:
.dbline 40
; {
.dbline 41
; if (SCH_tasks_G[Index].RunMe > 0)
ldi R24,7
mul R24,R20
movw R30,R0
ldi R24,<_SCH_tasks_G+6
ldi R25,>_SCH_tasks_G+6
add R30,R24
adc R31,R25
ldd R2,z+0
clr R3
cp R3,R2
brsh L9
.dbline 42
; {
.dbline 44
; // 运行任务
; (*SCH_tasks_G[Index].pTask)();
ldi R24,7
mul R24,R20
movw R30,R0
ldi R24,<_SCH_tasks_G
ldi R25,>_SCH_tasks_G
add R30,R24
adc R31,R25
ldd R26,z+0
ldd R27,z+1
movw R30,R26
xcall xicall
.dbline 47
;
; // 复位 / 降低RunMe标志
; SCH_tasks_G[Index].RunMe -= 1;
ldi R24,7
mul R24,R20
movw R2,R0
ldi R24,<_SCH_tasks_G+6
ldi R25,>_SCH_tasks_G+6
add R2,R24
adc R3,R25
movw R30,R2
ldd R24,z+0
subi R24,1
std z+0,R24
.dbline 50
;
; // 如果这个是'单次'任务,将它从队列中删除
; if (SCH_tasks_G[Index].Period == 0)
ldi R24,7
mul R24,R20
movw R30,R0
ldi R24,<_SCH_tasks_G+4
ldi R25,>_SCH_tasks_G+4
add R30,R24
adc R31,R25
ldd R2,z+0
ldd R3,z+1
tst R2
brne L13
tst R3
brne L13
X0:
.dbline 51
; {
.dbline 52
; SCH_Delete_Task(Index);
mov R16,R20
xcall _SCH_Delete_Task
.dbline 53
; }
L13:
.dbline 54
; }
L9:
.dbline 55
L6:
.dbline 39
inc R20
L8:
.dbline 39
cpi R20,3
brsh X1
xjmp L5
X1:
.dbline -2
L4:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r Index 20 c
.dbend
.dbfunc e SCH_Add_Task _SCH_Add_Task fc
; Index -> R20
; PERIOD -> y+2
; DELAY -> R18,R19
; pFunction -> R16,R17
.even
_SCH_Add_Task::
xcall push_gset1
.dbline -1
.dbline 77
; }
; }
;
;
;
; /*---------------------------------------------------------*-
; * 函数名称: SCH_Add_Task()
; * 入 口: (*pFunction)任务指针,(DELAY)到第一次运行间隔时标,
; * (PERIOD)每次运行的间隔时标
; *
; * 出 口: 返回SCH_MAX_TASKS表示任务队列已满
; * 返回(Index)=任务位置
; *
; * 函数功能: 用来添加任务到任务队列上,以保证它们在需要的时
; * 候被调用
; *
; * 说 明: 使任务函数每隔一定间隔或在用户的延迟之后执行.
; -*---------------------------------------------------------*/
;
; unsigned char SCH_Add_Task(void (*pFunction)(), // 任务指针
; const unsigned int DELAY, // 延迟Delay个时标后函数将第一次运行
; const unsigned int PERIOD) // 连续的运行之间的间隔(时标)
; {
.dbline 78
; unsigned char Index = 0; // 首先在队列中找到一个空隙
clr R20
xjmp L18
L17:
.dbline 81
.dbline 82
inc R20
.dbline 83
L18:
.dbline 80
;
; while ((SCH_tasks_G[Index].pTask != 0) && (Index < SCH_MAX_TASKS))
ldi R24,7
mul R24,R20
movw R30,R0
ldi R24,<_SCH_tasks_G
ldi R25,>_SCH_tasks_G
add R30,R24
adc R31,R25
ldd R2,z+0
ldd R3,z+1
tst R2
brne X2
tst R3
breq L20
X2:
cpi R20,3
brlo L17
L20:
.dbline 84
; {
; Index++;
; }
; if (Index == SCH_MAX_TASKS)
cpi R20,3
brne L21
.dbline 85
; {
.dbline 86
; return SCH_MAX_TASKS; // 同时返回错误代码
ldi R16,3
xjmp L16
L21:
.dbline 90
; }
;
; // 如果能运行到这里,则说明任务队列中有空间
; SCH_tasks_G[Index].pTask = pFunction;
ldi R24,7
mul R24,R20
movw R30,R0
ldi R24,<_SCH_tasks_G
ldi R25,>_SCH_tasks_G
add R30,R24
adc R31,R25
std z+1,R17
std z+0,R16
.dbline 91
; SCH_tasks_G[Index].Delay = DELAY;
ldi R24,7
mul R24,R20
movw R30,R0
ldi R24,<_SCH_tasks_G+2
ldi R25,>_SCH_tasks_G+2
add R30,R24
adc R31,R25
std z+1,R19
std z+0,R18
.dbline 92
; SCH_tasks_G[Index].Period = PERIOD;
ldi R24,7
mul R24,R20
movw R30,R0
ldi R24,<_SCH_tasks_G+4
ldi R25,>_SCH_tasks_G+4
add R30,R24
adc R31,R25
ldd R0,y+2
ldd R1,y+3
std z+1,R1
std z+0,R0
.dbline 93
; SCH_tasks_G[Index].RunMe = 0;
ldi R24,7
mul R24,R20
movw R30,R0
ldi R24,<_SCH_tasks_G+6
ldi R25,>_SCH_tasks_G+6
add R30,R24
adc R31,R25
clr R2
std z+0,R2
.dbline 94
; return Index; // 返回任务的位置(以便以后删除)
mov R16,R20
.dbline -2
L16:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r Index 20 c
.dbsym l PERIOD 2 ki
.dbsym r DELAY 18 ki
.dbsym r pFunction 16 pfV
.dbend
.dbfunc e SCH_Delete_Task _SCH_Delete_Task fc
; Return_code -> R20
; TASK_INDEX -> R16
.even
_SCH_Delete_Task::
xcall push_gset1
.dbline -1
.dbline 113
;
; }
;
;
;
; /*---------------------------------------------------------*-
; * 函数名称: SCH_Delete_Task()
; * 入 口: TASK_INDEX -任务索引.由SCH_Add_task()提供
; *
; * 出 口: 返回值: RETURN_ERROR(或)RETURN_NORMAL
; *
; * 函数功能: 从调度器删除任务.
; *
; * 说 明: 请注意:并不是从存储器中删除相关的函数,仅仅是不再
; * 由调度器调用这个任务.
; -*---------------------------------------------------------*/
;
; uchar SCH_Delete_Task(const unsigned char TASK_INDEX)
; {
.dbline 116
; uchar Return_code; //返回错误代码
;
; if (SCH_tasks_G[TASK_INDEX].pTask == 0)
ldi R24,7
mul R24,R16
movw R30,R0
ldi R24,<_SCH_tasks_G
ldi R25,>_SCH_tasks_G
add R30,R24
adc R31,R25
ldd R2,z+0
ldd R3,z+1
tst R2
brne L27
tst R3
brne L27
X3:
.dbline 117
; {
.dbline 118
; Return_code = RETURN_ERROR;
ldi R20,1
.dbline 119
; }
xjmp L28
L27:
.dbline 121
; else
; {
.dbline 122
; Return_code = RETURN_NORMAL;
clr R20
.dbline 123
; }
L28:
.dbline 126
;
; // 删除任务
; SCH_tasks_G[TASK_INDEX].pTask = 0x00;
ldi R24,7
mul R24,R16
movw R30,R0
ldi R24,<_SCH_tasks_G
ldi R25,>_SCH_tasks_G
add R30,R24
adc R31,R25
clr R2
clr R3
std z+1,R3
std z+0,R2
.dbline 127
; SCH_tasks_G[TASK_INDEX].Delay = 0;
ldi R24,7
mul R24,R16
movw R30,R0
ldi R24,<_SCH_tasks_G+2
ldi R25,>_SCH_tasks_G+2
add R30,R24
adc R31,R25
std z+1,R3
std z+0,R2
.dbline 128
; SCH_tasks_G[TASK_INDEX].Period = 0;
ldi R24,7
mul R24,R16
movw R30,R0
ldi R24,<_SCH_tasks_G+4
ldi R25,>_SCH_tasks_G+4
add R30,R24
adc R31,R25
std z+1,R3
std z+0,R2
.dbline 129
; SCH_tasks_G[TASK_INDEX].RunMe = 0;
ldi R24,7
mul R24,R16
movw R30,R0
ldi R24,<_SCH_tasks_G+6
ldi R25,>_SCH_tasks_G+6
add R30,R24
adc R31,R25
std z+0,R2
.dbline 131
;
; return Return_code;
mov R16,R20
.dbline -2
L26:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r Return_code 20 c
.dbsym r TASK_INDEX 16 kc
.dbend
.dbfunc s SCH_Updata _SCH_Updata fV
; Index -> R16
.even
_SCH_Updata:
.dbline -1
.dbline 146
; }
;
;
; /*---------------------------------------------------------*-
; * 函数名称: SCH_Update()
; * 入 口:
; * 出 口:
; * 函数功能: 在调度器的中断服务程序中运行
; *
; * 说 明: "刷新"函数,确定某个任务需要运行时,将这个任务的
; * RunMe标志加1,然后该任务将由调度程序执行.
; -*---------------------------------------------------------*/
;
; static void SCH_Updata(void)
; {
.dbline 148
; unsigned char Index;
; for (Index=0; Index < SCH_MAX_TASKS; Index++)
clr R16
xjmp L36
L33:
.dbline 149
; {
.dbline 151
; // 检测这里是否有任务?
; if (SCH_tasks_G[Index].pTask != 0)
ldi R24,7
mul R24,R16
movw R30,R0
ldi R24,<_SCH_tasks_G
ldi R25,>_SCH_tasks_G
add R30,R24
adc R31,R25
ldd R2,z+0
ldd R3,z+1
tst R2
brne X4
tst R3
brne X7
xjmp L37
X7:
X4:
.dbline 152
; {
.dbline 153
; if (SCH_tasks_G[Index].Delay == 0)
ldi R24,7
mul R24,R16
movw R30,R0
ldi R24,<_SCH_tasks_G+2
ldi R25,>_SCH_tasks_G+2
add R30,R24
adc R31,R25
ldd R2,z+0
ldd R3,z+1
tst R2
breq X8
xjmp L39
X8:
tst R3
breq X9
xjmp L39
X9:
X5:
.dbline 154
; {
.dbline 155
; SCH_tasks_G[Index].RunMe += 1; // RunMer标志加1
ldi R24,7
mul R24,R16
movw R2,R0
ldi R24,<_SCH_tasks_G+6
ldi R25,>_SCH_tasks_G+6
add R2,R24
adc R3,R25
movw R30,R2
ldd R24,z+0
subi R24,255 ; addi 1
std z+0,R24
.dbline 156
; if (SCH_tasks_G[Index].Period != 0)
ldi R24,7
mul R24,R16
movw R30,R0
ldi R24,<_SCH_tasks_G+4
ldi R25,>_SCH_tasks_G+4
add R30,R24
adc R31,R25
ldd R2,z+0
ldd R3,z+1
tst R2
brne X6
tst R3
breq L40
X6:
.dbline 157
; {
.dbline 159
; // 调度定期的任务再次运行
; SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period;
ldi R24,7
mul R24,R16
ldi R24,<_SCH_tasks_G+4
ldi R25,>_SCH_tasks_G+4
movw R30,R0
add R30,R24
adc R31,R25
ldd R2,z+0
ldd R3,z+1
ldi R24,<_SCH_tasks_G+2
ldi R25,>_SCH_tasks_G+2
movw R30,R0
add R30,R24
adc R31,R25
std z+1,R3
std z+0,R2
.dbline 160
; }
.dbline 161
; }
xjmp L40
L39:
.dbline 163
; else
; {
.dbline 165
; // 还没有准备好运行,延迟减1
; SCH_tasks_G[Index].Delay -= 1;
ldi R24,7
mul R24,R16
movw R2,R0
ldi R24,<_SCH_tasks_G+2
ldi R25,>_SCH_tasks_G+2
add R2,R24
adc R3,R25
movw R30,R2
ldd R24,z+0
ldd R25,z+1
sbiw R24,1
std z+1,R25
std z+0,R24
.dbline 166
; }
L40:
.dbline 167
; }
L37:
.dbline 168
L34:
.dbline 148
inc R16
L36:
.dbline 148
cpi R16,3
brsh X10
xjmp L33
X10:
.dbline -2
L32:
.dbline 0 ; func end
ret
.dbsym r Index 16 c
.dbend
.dbfunc e InitTimer1 _InitTimer1 fV
; i -> R20
.even
_InitTimer1::
xcall push_gset1
.dbline -1
.dbline 181
; }
; }
;
;
; /*---------------------------------------------------------*-
; * 函数名称: SCH_Init_Timer2()
; * 入 口:
; * 出 口:
; * 函数功能: 准备调度器数据结构并且设置定时器以所需的频率中断
; *
; * 说 明: 调度器初始化化函数,必须在使用调度器之前调用它
; -*---------------------------------------------------------*/
; void InitTimer1(void) //8MHz,10ms,64分频
; {
.dbline 184
; uchar i;
;
; for (i=0; i<SCH_MAX_TASKS; i++)
clr R20
xjmp L53
L50:
.dbline 185
.dbline 186
mov R16,R20
xcall _SCH_Delete_Task
.dbline 187
L51:
.dbline 184
inc R20
L53:
.dbline 184
cpi R20,3
brlo L50
.dbline 189
; {
; SCH_Delete_Task(i);
; }
;
; TCCR1B = 0x00; //stop
clr R2
out 0x2e,R2
.dbline 190
; TCNT1H = 0xFB; //setup
ldi R24,251
out 0x2d,R24
.dbline 191
; TCNT1L = 0x1E;
ldi R24,30
out 0x2c,R24
.dbline 192
; OCR1AH = 0x04;
ldi R24,4
out 0x2b,R24
.dbline 193
; OCR1AL = 0xE2;
ldi R24,226
out 0x2a,R24
.dbline 194
; OCR1BH = 0x04;
ldi R24,4
out 0x29,R24
.dbline 195
; OCR1BL = 0xE2;
ldi R24,226
out 0x28,R24
.dbline 196
; ICR1H = 0x04;
ldi R24,4
out 0x27,R24
.dbline 197
; ICR1L = 0xE2;
ldi R24,226
out 0x26,R24
.dbline 198
; TCCR1A = 0x00;
out 0x2f,R2
.dbline 199
; TCCR1B = 0x03; //start Timer
ldi R24,3
out 0x2e,R24
.dbline -2
L49:
xcall pop_gset1
.dbline 0 ; func end
ret
.dbsym r i 20 c
.dbend
.area vector(rom, abs)
.org 32
jmp _SCH_Update_Server
.area text(rom, con, rel)
.dbfile D:\_文档~1\easy-STQ-20080712\schedule.c
.dbfunc e SCH_Update_Server _SCH_Update_Server fV
.even
_SCH_Update_Server::
xcall push_lset
.dbline -1
.dbline 214
; }
;
;
; /*---------------------------------------------------------*-
; * 函数名称: SCH_Update_Server()
; * 入 口:
; * 出 口:
; * 函数功能: 调度器的中断服务程序
; *
; * 说 明: "刷新"函数,确定某个任务需要运行时,将这个任务的
; * RunMe标志加1,然后该任务将由调度程序执行.
; -*---------------------------------------------------------*/
; #pragma interrupt_handler SCH_Update_Server:9 //定时器溢出中断
; void SCH_Update_Server(void)
; {
.dbline 215
; TCNT1H = 0xFB; //reload counter value
ldi R24,251
out 0x2d,R24
.dbline 216
; TCNT1L = 0x1E;
ldi R24,30
out 0x2c,R24
.dbline 218
;
; TimeTick++;
lds R24,_TimeTick
subi R24,255 ; addi 1
sts _TimeTick,R24
.dbline 219
; MotorDelayTime++;
lds R24,_MotorDelayTime
lds R25,_MotorDelayTime+1
adiw R24,1
sts _MotorDelayTime+1,R25
sts _MotorDelayTime,R24
.dbline 222
;
;
; if(TimeTick%100 == 0) //1s喂狗
ldi R17,100
lds R16,_TimeTick
xcall mod8u
tst R16
brne L55
.dbline 223
; {
.dbline 224
; if(TimeTick == 200)TimeTick = 0;
lds R24,_TimeTick
cpi R24,200
brne L57
.dbline 224
clr R2
sts _TimeTick,R2
L57:
.dbline 225
; OutWdServer();
xcall _OutWdServer
.dbline 226
; }
L55:
.dbline 229
;
;
; SCH_Updata();
xcall _SCH_Updata
.dbline -2
L54:
xcall pop_lset
.dbline 0 ; func end
reti
.dbend
.dbfunc e SCH_Start _SCH_Start fV
.even
_SCH_Start::
.dbline -1
.dbline 245
;
; }
;
;
; /*---------------------------------------------------------*-
; * 函数名称: SCH_Start()
; * 入 口:
; * 出 口:
; * 函数功能: 通过允许中断来启动调度器
; *
; * 说 明: 在添加了所有定期的任务之后调用,从而使任务保持同步.
; * 注意:应该只使能调度器中断
; -*---------------------------------------------------------*/
;
; void SCH_Start(void)
; {
.dbline 246
; SEI();
sei
.dbline -2
L59:
.dbline 0 ; func end
ret
.dbend
.area bss(ram, con, rel)
.dbfile D:\_文档~1\easy-STQ-20080712\schedule.c
_SCH_tasks_G::
.blkb 21
.dbstruct 0 7 .3
.dbfield 0 pTask pfV
.dbfield 2 Delay i
.dbfield 4 Period i
.dbfield 6 RunMe c
.dbend
.dbsym e SCH_tasks_G _SCH_tasks_G A[21:3]S[.3]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -