📄 easy_icc.lst
字号:
0243 2422 CLR R2
0244 2433 CLR R3
0245 92300067 STS MotorDelayTime+1,R3
0247 92200066 STS MotorDelayTime,R2
0249 C007 RJMP 0x0251
(0259) while(MotorDelayTime<50)
(0260) {
(0261) if(GetOverheat()||GetLimit())break;
024A 99CA SBIC 0x19,2
024B C004 RJMP 0x0250
024C 9BCC SBIS 0x19,4
024D C002 RJMP 0x0250
024E 99CB SBIC 0x19,3
024F C001 RJMP 0x0251
0250 C008 RJMP 0x0259
0251 91800066 LDS R24,MotorDelayTime
0253 91900067 LDS R25,MotorDelayTime+1
0255 3382 CPI R24,0x32
0256 E0E0 LDI R30,0
0257 079E CPC R25,R30
0258 F388 BCS 0x024A
(0262) }
(0263) }
0259 9508 RET
(0264) }
(0265)
(0266) void ProtectMotor() //过热、限位信号保护
(0267) {
(0268) if(GetOverheat()) StopMotor();
_ProtectMotor:
025A 9BCA SBIS 0x19,2
025B C001 RJMP 0x025D
025C DFD9 RCALL _StopMotor
(0269)
(0270) if(GetLimitClose())
025D D01A RCALL _GetLimitClose
025E 2300 TST R16
025F F051 BEQ 0x026A
(0271) { //开信号时关限位不停
(0272) if(GetLocalOpen()||GetRemoteOpen()||MotorFlag == OPEN)return;
0260 9B9F SBIS 0x13,7
0261 C006 RJMP 0x0268
0262 9B85 SBIS 0x10,5
0263 C004 RJMP 0x0268
0264 91800065 LDS R24,MotorFlag
0266 3081 CPI R24,1
0267 F409 BNE 0x0269
0268 C00E RJMP 0x0277
(0273) StopMotor();
0269 DFCC RCALL _StopMotor
(0274) }
(0275)
(0276) if(GetLimitOpen())
026A D02D RCALL _GetLimitOpen
026B 2300 TST R16
026C F051 BEQ 0x0277
(0277) { //关信号时开限位不停
(0278) if(GetLocalClose()||GetRemoteClose()||MotorFlag == CLOSE)return;
026D 9B9E SBIS 0x13,6
026E C006 RJMP 0x0275
026F 9B84 SBIS 0x10,4
0270 C004 RJMP 0x0275
0271 91800065 LDS R24,MotorFlag
0273 3082 CPI R24,2
0274 F409 BNE 0x0276
0275 C001 RJMP 0x0277
(0279) StopMotor();
0276 DFBF RCALL _StopMotor
(0280) }
0277 9508 RET
(0281)
(0282) }
(0283)
(0284)
(0285) uchar GetLimitClose(void)
(0286) {
(0287) if(limit_direction == 1)
_GetLimitClose:
0278 9180007E LDS R24,limit_direction
027A 3081 CPI R24,1
027B F441 BNE 0x0284
(0288) {
(0289) return GetLimit1();
027C 99CC SBIC 0x19,4
027D C003 RJMP 0x0281
027E E001 LDI R16,1
027F E010 LDI R17,0
0280 C002 RJMP 0x0283
0281 2700 CLR R16
0282 2711 CLR R17
0283 C013 RJMP 0x0297
(0290) }
(0291) else if((limit_direction == 0))
0284 9020007E LDS R2,limit_direction
0286 2022 TST R2
0287 F441 BNE 0x0290
(0292) {
(0293) return GetLimit2();
0288 99CB SBIC 0x19,3
0289 C003 RJMP 0x028D
028A E001 LDI R16,1
028B E010 LDI R17,0
028C C002 RJMP 0x028F
028D 2700 CLR R16
028E 2711 CLR R17
028F C007 RJMP 0x0297
(0294) }
(0295) else
(0296) {
(0297) return GetLimit1();
0290 99CC SBIC 0x19,4
0291 C003 RJMP 0x0295
0292 E001 LDI R16,1
0293 E010 LDI R17,0
0294 C002 RJMP 0x0297
0295 2700 CLR R16
0296 2711 CLR R17
0297 9508 RET
(0298) }
(0299) }
(0300)
(0301) uchar GetLimitOpen(void)
(0302) {
(0303) if(limit_direction == 1)
_GetLimitOpen:
0298 9180007E LDS R24,limit_direction
029A 3081 CPI R24,1
029B F441 BNE 0x02A4
(0304) {
(0305) return GetLimit2();
029C 99CB SBIC 0x19,3
029D C003 RJMP 0x02A1
029E E001 LDI R16,1
029F E010 LDI R17,0
02A0 C002 RJMP 0x02A3
02A1 2700 CLR R16
02A2 2711 CLR R17
02A3 C013 RJMP 0x02B7
(0306) }
(0307) else if((limit_direction == 0))
02A4 9020007E LDS R2,limit_direction
02A6 2022 TST R2
02A7 F441 BNE 0x02B0
(0308) {
(0309) return GetLimit1();
02A8 99CC SBIC 0x19,4
02A9 C003 RJMP 0x02AD
02AA E001 LDI R16,1
02AB E010 LDI R17,0
02AC C002 RJMP 0x02AF
02AD 2700 CLR R16
02AE 2711 CLR R17
02AF C007 RJMP 0x02B7
(0310) }
(0311) else
(0312) {
(0313) return GetLimit2();
02B0 99CB SBIC 0x19,3
02B1 C003 RJMP 0x02B5
02B2 E001 LDI R16,1
02B3 E010 LDI R17,0
02B4 C002 RJMP 0x02B7
02B5 2700 CLR R16
02B6 2711 CLR R17
02B7 9508 RET
_SCH_Dispatch_Tasks:
Index --> R20
02B8 940E053D CALL push_gset1
FILE: E:\_ING\文档\_STQ\easy-STQ-20080712\schedule.c
(0001)
(0002) ///////////////////////////////////////////////////////////////
(0003) /**************************************************************
(0004)
(0005) 公司名称: 扬州恒博科技
(0006) 模块名 : 点动型STQ执行机构主控程序
(0007) 创建人 : 章俭文
(0008) 日期 : 2008/08/19
(0009) 功能描述: 完成对本地旋钮和远程开关量的控制功能
(0010) 其它说明: 编译环境为ICCAVR V6.31A
(0011) 版本 : V1.0
(0012)
(0013) **************************************************************/
(0014) ///////////////////////////////////////////////////////////////
(0015)
(0016) #define SCHEDULE_GLOBAL
(0017) #include "schedule.h"
(0018)
(0019)
(0020) static void SCH_Updata(void);
(0021)
(0022)
(0023) // 在任一时刻要求的任务最大数目
(0024) #define SCH_MAX_TASKS (3)
(0025)
(0026) // 任务队列
(0027) sTask SCH_tasks_G[SCH_MAX_TASKS];
(0028)
(0029) // 错误代码
(0030) #define ERROR_SCH_TOO_MANY_TASKS (1)
(0031) #define ERROR_SCH_CANNOT_DELETE_TASK (2)
(0032)
(0033) #define RETURN_NORMAL 0
(0034) #define RETURN_ERROR 1
(0035)
(0036)
(0037)
(0038)
(0039) /*---------------------------------------------------------*-
(0040) * 函数名称: SCH_Dispatch_Tasks()
(0041) * 入 口:
(0042) * 出 口:
(0043) * 函数功能: 调度函数,当一个任务()需要运行时,此函数将运行它,
(0044) *
(0045) * 说 明: 这个函数必须被主循环(重复)调用
(0046) -*---------------------------------------------------------*/
(0047)
(0048) void SCH_Dispatch_Tasks(void)
(0049) {
(0050) unsigned char Index;
(0051)
(0052) // 调度(运行)下一个任务(如果有任务就绪)
(0053) for (Index=0; Index<SCH_MAX_TASKS; Index++)
02BA 2744 CLR R20
02BB C032 RJMP 0x02EE
(0054) {
(0055) if (SCH_tasks_G[Index].RunMe > 0)
02BC E087 LDI R24,7
02BD 9F84 MUL R24,R20
02BE 01F0 MOVW R30,R0
02BF E68F LDI R24,0x6F
02C0 E090 LDI R25,0
02C1 0FE8 ADD R30,R24
02C2 1FF9 ADC R31,R25
02C3 8020 LDD R2,Z+0
02C4 2433 CLR R3
02C5 1432 CP R3,R2
02C6 F530 BCC 0x02ED
(0056) {
(0057) // 运行任务
(0058) (*SCH_tasks_G[Index].pTask)();
02C7 E087 LDI R24,7
02C8 9F84 MUL R24,R20
02C9 01F0 MOVW R30,R0
02CA E689 LDI R24,0x69
02CB E090 LDI R25,0
02CC 0FE8 ADD R30,R24
02CD 1FF9 ADC R31,R25
02CE 81A0 LDD R26,Z+0
02CF 81B1 LDD R27,Z+1
02D0 01FD MOVW R30,R26
02D1 940E0554 CALL xicall
(0059)
(0060) // 复位 / 降低RunMe标志
(0061) SCH_tasks_G[Index].RunMe -= 1;
02D3 E087 LDI R24,7
02D4 9F84 MUL R24,R20
02D5 0110 MOVW R2,R0
02D6 E68F LDI R24,0x6F
02D7 E090 LDI R25,0
02D8 0E28 ADD R2,R24
02D9 1E39 ADC R3,R25
02DA 01F1 MOVW R30,R2
02DB 8180 LDD R24,Z+0
02DC 5081 SUBI R24,1
02DD 8380 STD Z+0,R24
(0062)
(0063) // 如果这个是'单次'任务,将它从队列中删除
(0064) if (SCH_tasks_G[Index].Period == 0)
02DE E087 LDI R24,7
02DF 9F84 MUL R24,R20
02E0 01F0 MOVW R30,R0
02E1 E68D LDI R24,0x6D
02E2 E090 LDI R25,0
02E3 0FE8 ADD R30,R24
02E4 1FF9 ADC R31,R25
02E5 8020 LDD R2,Z+0
02E6 8031 LDD R3,Z+1
02E7 2022 TST R2
02E8 F421 BNE 0x02ED
02E9 2033 TST R3
02EA F411 BNE 0x02ED
(0065) {
(0066) SCH_Delete_Task(Index);
02EB 2F04 MOV R16,R20
02EC D049 RCALL _SCH_Delete_Task
02ED 9543 INC R20
02EE 3043 CPI R20,3
02EF F408 BCC 0x02F1
02F0 CFCB RJMP 0x02BC
02F1 940E0540 CALL pop_gset1
02F3 9508 RET
_SCH_Add_Task:
Index --> R20
PERIOD --> Y+2
DELAY --> R18
pFunction --> R16
02F4 940E053D CALL push_gset1
(0067) }
(0068) }
(0069) }
(0070) }
(0071)
(0072)
(0073)
(0074) /*---------------------------------------------------------*-
(0075) * 函数名称: SCH_Add_Task()
(0076) * 入 口: (*pFunction)任务指针,(DELAY)到第一次运行间隔时标,
(0077) * (PERIOD)每次运行的间隔时标
(0078) *
(0079) * 出 口: 返回SCH_MAX_TASKS表示任务队列已满
(0080) * 返回(Index)=任务位置
(0081) *
(0082) * 函数功能: 用来添加任务到任务队列上,以保证它们在需要的时
(0083) * 候被调用
(0084) *
(0085) * 说 明: 使任务函数每隔一定间隔或在用户的延迟之后执行.
(0086) -*---------------------------------------------------------*/
(0087)
(0088) unsigned char SCH_Add_Task(void (*pFunction)(), // 任务指针
(0089) const unsigned int DELAY, // 延迟Delay个时标后函数将第一次运行
(0090) const unsigned int PERIOD) // 连续的运行之间的间隔(时标)
(0091) {
(0092) unsigned char Index = 0; // 首先在队列中找到一个空隙
02F6 2744 CLR R20
02F7 C001 RJMP 0x02F9
(0093)
(0094) while ((SCH_tasks_G[Index].pTask != 0) && (Index < SCH_MAX_TASKS))
(0095) {
(0096) Index++;
02F8 9543 INC R20
02F9 E087 LDI R24,7
02FA 9F84 MUL R24,R20
02FB 01F0 MOVW R30,R0
02FC E689 LDI R24,0x69
02FD E090 LDI R25,0
02FE 0FE8 ADD R30,R24
02FF 1FF9 ADC R31,R25
0300 8020 LDD R2,Z+0
0301 8031 LDD R3,Z+1
0302 2022 TST R2
0303 F411 BNE 0x0306
0304 2033 TST R3
0305 F011 BEQ 0x0308
0306 3043 CPI R20,3
0307 F380 BCS 0x02F8
(0097) }
(0098) if (Index == SCH_MAX_TASKS)
0308 3043 CPI R20,3
0309 F411 BNE 0x030C
(0099) {
(0100) return SCH_MAX_TASKS; // 同时返回错误代码
030A E003 LDI R16,3
030B C027 RJMP 0x0333
(0101) }
(0102)
(0103) // 如果能运行到这里,则说明任务队列中有空间
(0104) SCH_tasks_G[Index].pTask = pFunction;
030C E087 LDI R24,7
030D 9F84 MUL R24,R20
030E 01F0 MOVW R30,R0
030F E689 LDI R24,0x69
0310 E090 LDI R25,0
0311 0FE8 ADD R30,R24
0312 1FF9 ADC R31,R25
0313 8311 STD Z+1,R17
0314 8300 STD Z+0,R16
(0105) SCH_tasks_G[Index].Delay = DELAY;
0315 E087 LDI R24,7
0316 9F84 MUL R24,R20
0317 01F0 MOVW R30,R0
0318 E68B LDI R24,0x6B
0319 E090 LDI R25,0
031A 0FE8 ADD R30,R24
031B 1FF9 ADC R31,R25
031C 8331 STD Z+1,R19
031D 8320 STD Z+0,R18
(0106) SCH_tasks_G[Index].Period = PERIOD;
031E E087 LDI R24,7
031F 9F84 MUL R24,R20
0320 01F0 MOVW R30,R0
0321 E68D LDI R24,0x6D
0322 E090 LDI R25,0
0323 0FE8 ADD R30,R24
0324 1FF9 ADC R31,R25
0325 800A LDD R0,Y+2
0326 801B LDD R1,Y+3
0327 8211 STD Z+1,R1
0328 8200 STD Z+0,R0
(0107) SCH_tasks_G[Index].RunMe = 0;
0329 E087 LDI R24,7
032A 9F84 MUL R24,R20
032B 01F0 MOVW R30,R0
032C E68F LDI R24,0x6F
032D E090 LDI R25,0
032E 0FE8 ADD R30,R24
032F 1FF9 ADC R31,R25
0330 2422 CLR R2
0331 8220 STD Z+0,R2
(0108) return Index; // 返回任务的位置(以便以后删除)
0332 2F04 MOV R16,R20
0333 940E0540 CALL pop_gset1
0335 9508 RET
_SCH_Delete_Task:
Return_code --> R20
TASK_INDEX --> R16
0336 940E053D CALL push_gset1
(0109)
(0110) }
(0111)
(0112)
(0113)
(0114) /*---------------------------------------------------------*-
(0115) * 函数名称: SCH_Delete_Task()
(0116) * 入 口: TASK_INDEX -任务索引.由SCH_Add_task()提供
(0117) *
(0118) * 出 口: 返回值: RETURN_ERROR(或)RETURN_NORMAL
(0119) *
(0120) * 函数功能: 从调度器删除任务.
(0121) *
(0122) * 说 明: 请注意:并不是从存储器中删除相关的函数,仅仅是不再
(0123) * 由调度器调用这个任务.
(0124) -*---------------------------------------------------------*/
(0125)
(0126) uchar SCH_Delete_Task(const unsigned char TASK_INDEX)
(0127) {
(0128) uchar Return_code; //返回错误代码
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -