;利用复位进行超低功耗计数,50uA待机电流,较低的计数频率可用
;每次复位对内部计数器加一,并通过串口把三位计数内存数据发送到计算机
;然后进入POWERDOWN模式
;如果按住KEY1再复位,则对内存计数器清零
;期间点亮P1.1外接的LED,使用89S51,11.0592M晶振测试通过
TIMES DATA 30H;计数器,低位在前,高位在后
KEY1 BIT P1.3
ORG 0000H
SJMP MAIN
ORG 0030H
MAIN:
CLR P1.1
MOV TMOD,#20h ;T1为常数自动重装入的8位定时计数器,既波特率发生器,T0为16位的定时计数器
MOV PCON,#80h ;SMOD=1
MOV TH1,#0FFH ;初始化波特率,11.0592下,且SMOD=1加倍情况下,0FFH=57600,0FDH=19200 ,0FAH=9600
MOV SCON,#50h ;Standard UART settings
SETB TR1 ;T1开始工作
SETB EA ;开全部中断
PD:
ACALL JISHU
ACALL QL
ACALL SEND
SETB P1.1
;进入掉电模式
MOV PCON,#02H
;到此是执行的最后一条语句
QL:
JB KEY1,QLRET
MOV TIMES,#00H
MOV TIMES+1,#00H
MOV TIMES+2,#00H
QLRET:
RET
JISHU: ;计数器小程序,每ACALL一次,计数器TIMES加一,低位在前高位在后
push acc
JS1:
inc TIMES
MOV A,TIMES
JNZ JSRET
INC TIMES+1
MOV A,TIMES+1
JNZ JSRET
INC TIMES+2
MOV A,TIMES+2
JNZ JSRET
INC TIMES+3
JSRET:
pop acc
RET
SEND:;向串口发送R0开始的内存数据,长度由下面的判断语句决定
CLR ES
push 00H
push ACC
mov r0,#30h
LP1:
MOV A,@R0
MOV SBUF,A
JNB TI,$
CLR TI
INC R0
CJNE R0,#33H,LP1
pop ACC
pop 00H
SETB ES
RET
END
不过要求复位时间尽量短,因为复位高电平时单片机功耗还是很大的哦!
补充:
;遭遇程序跑飞,养狗看门啦!
;
;上一个程序是用复位实现计数,经查89S52具有外中断唤醒功能,于是又编辑了一个以外中断INT0进行计数的超低功耗计数器,但是调试过程中发现,使用POWERDOWN模式时多次发生程序无反应现象,不用POWERDOWN模式就没事,判断可能程序在POWERDOWN模式恢复时造成某些SFR数据异常?这方面我没有经验,还请高手释疑!为了解决跑飞问题,于是启用看门狗,发生跑飞就立即复位到正常程序中,可通过P1.4外接LED指示是否看门狗起作用了。
;
;利用中断进行超低功耗计数50uA,不高的计数频率可用
;每次中断唤醒CPU对内部计数器加一,并通过串口把三位计数内存数据发送到计算机
;然后进入POWERDOWN模式
;如果按住KEY1再复位,则对内存计数器清零
;期间点亮P1.1外接的LED
;由于POWERDOWN模式唤醒后,有时程序有跑飞现象,所以引入看门狗,并在P1.4指示看门狗是否动作
TIMES DATA 30H;计数器,低位在前,高位在后
KEY1 BIT P1.3
ORG 0000H
SJMP MAIN
ORG 0003H ;外部中断P3.2脚INT0入口地址
AJMP INT ;转入外部中断服务子程序(解码程序)
ORG 0030H
MAIN:
ACALL SEDOG
JBC 00H,PDZ
SETB 00H
PDZ:
MOV C,00H
MOV P1.4,C
MOV SP,#40H
MOV TMOD,#20h ;T1为常数自动重装入的8位定时计数器,既波特率发生器,T0为16位的定时计数器
MOV PCON,#80h ;SMOD=1
MOV TH1,#0FFH ;初始化波特率,11.0592下,且SMOD=1加倍情况下,0FFH=57600,0FDH=19200 ,0FAH=9600
MOV SCON,#50h ;Standard UART settings
SETB TR1 ;T1开始工作
SETB IT0 ;设定INT0的触发方式为脉冲负边沿触发
SETB EX0 ;打开INT0中断请求
SETB EA ;开全部中断
PD:
NOP
NOP
NOP
NOP
ACALL SEDOG
;进入掉电模式
MOV PCON,#02H
;到此是执行的最后一条语句
NOP
NOP
NOP
NOP
SJMP PD
SEDOG:
MOV 0A6H,#1EH
MOV 0A6H,#0E1H
RET
INT:
CLR EA
CLR P1.1
MOV TMOD,#20h ;T1为常数自动重装入的8位定时计数器,既波特率发生器,T0为16位的定时计数器
MOV PCON,#80h ;SMOD=1
MOV TH1,#0FFH ;初始化波特率,11.0592下,且SMOD=1加倍情况下,0FFH=57600,0FDH=19200 ,0FAH=9600
MOV SCON,#50h ;Standard UART settings
SETB TR1 ;T1开始工作
SETB IT0 ;设定INT0的触发方式为脉冲负边沿触发
ACALL JISHU
ACALL QL
ACALL SEND
SETB P1.1
CLR IE0
SETB EA
RETI
QL:
JB KEY1,QLRET
MOV TIMES,#00H
MOV TIMES+1,#00H
MOV TIMES+2,#00H
QLRET:
RET
JISHU: ;计数器小程序,每ACALL一次,计数器TIMES加一,低位在前高位在后
push acc
JS1:
inc TIMES
MOV A,TIMES
JNZ JSRET
INC TIMES+1
MOV A,TIMES+1
JNZ JSRET
INC TIMES+2
MOV A,TIMES+2
JNZ JSRET
INC TIMES+3
JSRET:
pop acc
RET
SEND:;向串口发送R0开始的内存数据,长度由下面的判断语句决定
push 00H
push ACC
mov r0,#30h
LP1:
MOV A,@R0
MOV SBUF,A
JNB TI,$
CLR TI
INC R0
CJNE R0,#33H,LP1
pop ACC
pop 00H
RET
END