📄 system.asm
字号:
//程序名:system.asm
//完成校时、万年历计算等
.include hardware.inc
.external _SecondAddOne
.RAM
.public Year;
.public MonDayHr;
.public MinSec;
.public Per500msSet;
.var Year //年 b15--if leap year
.var MonDayHr //月日时 b13--b10(month) b9--b5(day) b4--b0(hour)
.var MinSec //分秒 b12--b7(minute) b6--b1(second) b0--500ms
.var Per500msSet //500ms 标志
.CODE
////////////////////////////////////////
// 功能:系统初始化
// 入口:无
// 出口:无
////////////////////////////////////////
.public _System_Initial;
_System_Initial: .PROC
//-----------系统时钟、中断----------//
r1=0
[P_SystemClock]=r1
r1=0
[R_InterruptStatus] = R1
[P_INT_Ctrl]=r1
IRQ OFF
FIQ OFF
//----------------IO口--------------//
R1=0xff00
[P_IOA_Attrib] = R1 //A7--A0 输入
[P_IOA_Dir] = R1 //A15--A8 输出
R1 = 0xff00
[P_IOA_Data] = R1
//--------万年历---------//
R1=2003
[Year]=R1 //2003年 b15--not leap year
R1=0x0420
[MonDayHr]=R1 //1月1日1时
// b13--b10(month) b9--b5(day) b4--b0(hour)
R1=0x0000
[MinSec]=R1 //0分0秒
//b12--b7(minute) b6--b1(second) b0--500ms
[Per500msSet]=R1
//------------------- 中断 --------------------//
r1 = C_IRQ5_2Hz+ C_IRQ3_KEY //2Hz+KeyUp
r1|=[R_InterruptStatus]
[R_InterruptStatus] = R1
[P_INT_Ctrl]=r1
IRQ ON
retf;
.ENDP;
//=============================================//
.public _LightOff;
_LightOff: .proc //熄灭IOA15 LED
r1= 0x8000;
r1 |= [P_IOA_Buffer];
[P_IOA_Buffer] = r1;
retf;
.endp
.public _LightOn; //点亮 IOA15 LED
_LightOn: .proc
r1= 0x7fff;
r1&= [P_IOA_Buffer];
[P_IOA_Buffer] = r1;
retf;
.endp
//----------------------------------------------//
//功能:万年历调整
//入口:500ms标志 [Per500msSet]----0xFFFF,500ms到
//出口:无
//----------------------------------------------//
.public _Calendar_Counter
_Calendar_Counter: .proc
R1 = [Per500msSet]; //500ms标志
JNZ Update_Time;
RETF;
Update_Time:
R1 = 0;
[Per500msSet] = R1;
//minute & second
R1 = [MinSec];
R1 += 1; //秒+1
R2 = R1 AND 0x007E; //是否到60秒?
CMP R2,60*2;
JB _2HzRtc_90;
R1 &= 0x1F80;
R1 += 0x0080;
r4=0xFFFF //分+1,置调整标志
[_SecondAddOne]=r4
CMP R1,60*128; //是否到60分
JB _2HzRtc_90;
r1+=0x0003; //手工校正
//month, day, hour
R2 = [MonDayHr];
R2 += 1; //时+1
R3 = R2 AND 0x001F;
CMP R3,24; //是否到24小时
JB _2HzRtc_80;
R2& = 0x3FE0; //小时清0
R3 = R2 LSR 4;
R3 = R3 LSR 1;
R3 &= 0x001F;
CALL F_GetDaysOfTheMonth; //读本月天数
CMP R3,R1;
JB _2HzRtc_75;
R2 &= 0x3C00;
R2 += 0x0400; //月+1
CMP R2,13*1024; //月超过12?
JB _2HzRtc_75;
R2 = 0x0400; //月置1
//year
R3 = [Year];
R3 += 1; //年+1
R3&=0x7FFF
CMP R3,3099; //3099年
JBE _2HzRtc_70;
R3 = 2001; //2001年
_2HzRtc_70:
CALL F_CalcLeapYear_or_NonLeapYear //计算平闰年,R3---返回值
//闰年(b15=1) 平年(b15=0)
[Year] = R3;
_2HzRtc_75:
R2 += 0x0020; //天+1
_2HzRtc_80:
[MonDayHr] = R2;
_2HzRtc_85:
R1 = 0x0000; //R1 = 0x0000;
_2HzRtc_90:
[MinSec] = R1;
RETF;
//------------------------------------//
TB_DaysOfMonth: //高字节---闰年天数, 低字节---- 平年天数
.DW 31*256+31;
.DW 31*256+31; //1 month
.DW 29*256+28; //2 month
.DW 31*256+31; //3 month
.DW 30*256+30; //4 month
.DW 31*256+31; //5 month
.DW 30*256+30; //6 month
.DW 31*256+31; //7 month
.DW 31*256+31; //8 month
.DW 30*256+30; //9 month
.DW 31*256+31; //10 month
.DW 30*256+30; //11 month
.DW 31*256+31; //12 month
//--------------------------------//
//功能:计算本月天数
//出口:R1---天数
//--------------------------------//
F_GetDaysOfTheMonth:
R1 = [MonDayHr];
R1 = R1 LSR 4;
R1 = R1 LSR 4;
R1 = R1 LSR 2;
R1 &= 0x000F;
BP = R1 + TB_DaysOfMonth;
R1 = [BP];
R4 = 0x8000
TEST R4,[Year]; //平闰年?
JNZ GetDaysOfTheMonth_LeapYear;
GetDaysOfTheMonth_NonLeapYear: //平年
R1 &= 0x00FF;
RETF;
GetDaysOfTheMonth_LeapYear: //闰年
R1 = R1 LSR 4;
R1 = R1 LSR 4;
RETF;
//--------------------------------------------------
//功能:平闰年计算
//闰年条件:1、能被400整除 2、能被4整除,但不能被100整除
//--------------------------------------------------
F_CalcLeapYear_or_NonLeapYear:
R4=R3;
CMP R4,0;
JZ GetDaysOfTheMonth_20;
GetDaysOfTheMonth_10:
CMP R4,400; //判断是否能被400整除
JB GetDaysOfTheMonth_30; //不能被400整除
R4 -= 400;
JNZ GetDaysOfTheMonth_10;
GetDaysOfTheMonth_20: //闰年 能被400整除 或 能被4整除但不能被100整除
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -