关于BCD码的减法程序,如果用非压缩BCD数比较简单,下面我只介绍一下四位压缩BCD数的减法程序,我们这里假定被减数大于减数,我这里设定被减数位6723-4545=2178,结果保存在了寄存器R4R5中
汇编如下
ORG 00H
START: MOV SP,#60H
;我这里设定的是R4R5为被减数,R6R7为减数,且 R4R5>R6R7
;R5,R7中存放压缩BCD数的低两位,R4,R6中存放压缩BCD数的高两位
MOV R4,#67H
MOV R5,#23H
MOV R6,#45H
MOV R7,#45H
LCALL CLEAR
;提取压缩BCD数的低两位,被减数和减数分别存放在R5和R7中,结果放在R5中
;把一个寄存器里的两位压缩BCD数分别取出放在两个寄存器中,其中被减数放在R0,R1中,减数放在R2,R3中
D1: CLR A
MOV A,R5
SWAP A
ANL A,#0FH
MOV R0,A
CLR A
MOV A,R5
ANL A,#0FH
MOV R1,A
D2: CLR A
MOV A,R7
SWAP A
ANL A,#0FH
MOV R2,A
CLR A
MOV A,R7
ANL A,#0FH
MOV R3,A
MOV R5,#00H
LSUB1: CLR A
CLR C
MOV A,R1
SUBB A,R3
JC N1 ;无借位则执行下一句
MOV R5,A
LJMP LSUB2
;有借位的话
N1: CLR C
DEC R0
SUBB A,#6
ANL A,#0FH
MOV R5,A
LSUB2: CLR A
CLR C
MOV A,R0
SUBB A,R2
JC N2 ;无借位则执行下一句
SWAP A
ADD A,R5
MOV R5,A
JMP T2
;有借位的话
N2: CLR C
SUBB A,#6
ANL A,#0FH
SWAP A
ADD A,R5
MOV R5,A
;对于这位向R4寄存器中的高两位借位的为的问题作如下处理
CLR A
CLR C
MOV A,R4
ANL A,#0FH
SUBB A,#1
JC L1
DEC R4
LJMP T2
L1: CLR C
CLR A
MOV A,R4
CLR C
CLR A
SUBB A,#7
MOV R4,A
T2:
LCALL CLEAR
;开始高两位的减法,被减数和减数的高两位分别放在R4 和R6中,结果的高两位放在R4中
C1: CLR A
MOV A,R4
SWAP A
ANL A,#0FH
MOV R0,A
CLR A
MOV A,R4
ANL A,#0FH
MOV R1,A
C2: CLR A
MOV A,R6
SWAP A
ANL A,#0FH
MOV R2,A
CLR A
MOV A,R6
ANL A,#0FH
MOV R3,A
MOV R4,#00H
HSUB1: CLR A
CLR C
MOV A,R1
SUBB A,R3
JC M1 ;无借位则执行下一句
MOV R4,A
JMP HSUB2
;有借位的话
M1: CLR C
DEC R0
SUBB A,#6
ANL A,#0FH
MOV R4,A
HSUB2: CLR A
CLR C
MOV A,R0
SUBB A,R2
; // JC N2 ;无借位则执行下一句
SWAP A
ADD A,R4
MOV R4,A
LJMP ENDD
CLEAR: MOV R0,#0
MOV R1,#0
MOV R2,#0
MOV R3,#0
RET
ENDD: NOP
END
1.我采用一个25Mhz的oscillator 代替crystal,发现系统还是经常发生不能唤醒
2.设置内部clkfMSTR=fRTC=32.768 kHz, fRCLK=32.768 kHz
fFMICLK=fHCLK=fPCLK=32.768 kHz,
这种办法,仍然不能100%唤醒,
我设置方法: 每次进入待机前设置clk函数 SysClkRTCConfig(),中断后回调 SysClkConfig()函数,还有什么我没有考虑全的?
void SysClkConfig(void)
{
SCU_MCLKSourceConfig(SCU_MCLK_OSC);
// Set the PLL's multipliers and dividers
SCU_PLLFactorsConfig(BSP_PLL_N, BSP_PLL_M, BSP_PLL_P);
SCU_PLLCmd(ENABLE); // Enable the PLL
SCU_RCLKDivisorConfig(SCU_RCLK_Div1); // Set RCLK, the CPU clock's main divider
SCU_PCLKDivisorConfig(SCU_PCLK_Div1); // Set APBDIV, the PCLK divider
SCU_FMICLKDivisorConfig(SCU_FMICLK_Div2);
SCU_MCLKSourceConfig(SCU_MCLK_PLL); // Select the PLL output as CPU clock
}
void SysClkRTCConfig(void)
{
//SCU_MCLKSourceConfig(SCU_MCLK_RTC);
// Set the PLL's multipliers and dividers
// SCU_PLLFactorsConfig(BSP_PLL_N, BSP_PLL_M, BSP_PLL_P);
SCU_PLLCmd(DISABLE); // Enable the PLL
SCU_MCLKSourceConfig(SCU_MCLK_RTC);
SCU_RCLKDivisorConfig(SCU_RCLK_Div1); // Set RCLK, the CPU clock's main divider ,RClk=Fmstr
SCU_PCLKDivisorConfig(SCU_PCLK_Div1); // Set APBDIV, the PCLK divider
SCU_FMICLKDivisorConfig(SCU_FMICLK_Div1);
SCU_MCLKSourceConfig(SCU_MCLK_RTC);
//SCU_MCLKSourceConfig(SCU_MCLK_PLL); // Select the PLL output as CPU clock
}