关于定时器的研究
刚初学单片机,想做个定时器定时给继电器供电或断电,时间可调,默认2分钟,
8255 pa,pb控制数码管,pc扫描键盘(只要4个键,pc1.2.3为行,pc4为列),做了几天始终做不来,可以显示,但是不能工作。。。。
高手帮忙改下程序
PA XDATA 0D1FFH
PB XDATA 0D2FFH
;PC XDATA 0D5FFH
CON XDATA 0D7FFH
SL EQU 40H
SH EQU 41H
ML EQU 42H
ORG 0000H
LJMP MAIN
ORG 000BH
MAIN:
MOV 30H,#00H
MOV 40H,#00H
MOV 41H,#00H
MOV 42H,#02H
MOV 60H,#1FH
MOV TMOD,#21H ;定时器工作方式;
MOV TH0,#3CH
MOV TL0,#0B0H
SETB EA ;开中断;
SETB ET0
SETB ET1
MOV DPTR,#CON ;控制字设置;
MOV A,#81H
MOVX @DPTR,A
LJMP KEYSCAN
LJMP START
LJMP TIME
;数码管显示函数;
START:
MOV 20H,#00H
MOV DPTR,#0D1FFH ;A选通分个位;
MOV A,#0FEH
MOVX @DPTR,A
MOV DPTR,#0D2FFH ;送PB显示分秒间隔符;
MOV A,#0A0H
MOVX @DPTR,A
MOV DPTR,#0D2FFH ;关闭数码管;
MOV A,0FFH
MOVX @DPTR,A
MOV DPTR,#0D1FFH ;A选通分个位;
MOV A,#0FDH
MOVX @DPTR,A
MOV A,42H ;分个位数赋值给a;
ADD A,20H
MOV DPTR,#TABLE ;取分个位数;
MOVC A,@A+DPTR
MOV 21H,A ;送pb显示分个位;
MOV DPTR,#0D2FFH
MOV A,21H
MOVX @DPTR,A
MOV DPTR,#0D2FFH ;闭数码管;
MOV A,0FFH
MOVX @DPTR,A
MOV DPTR,#0D1FFH ;A选通分秒间隔符;
MOV A,#0FBH
MOVX @DPTR,A
MOV DPTR,#0D2FFH ;送PB显示分秒间隔符;
MOV A,#07FH
MOVX @DPTR,A
MOV DPTR,#0D2FFH ;闭数码管;
MOV A,0FFH
MOVX @DPTR,A
MOV DPTR,#0D1FFH ;A选通秒十位;
MOV A,#0F7H
MOVX @DPTR,A
MOV A,41H ;秒十位数赋值给a;
ADD A,20H
MOV DPTR,#TABLE ;取秒十位数;
MOVC A,@A+DPTR
MOV 21H,A ;送pb显示秒十位;
MOV DPTR,#0D2FFH
MOV A,21H
MOVX @DPTR,A
MOV DPTR,#0D2FFH ;闭数码管;
MOV A,0FFH
MOVX @DPTR,A
MOV DPTR,#0D1FFH ;A选通秒个位;
MOV A,#0EFH
MOVX @DPTR,A
MOV A,40H ;秒个位数赋值给a;
ADD A,20H
MOV DPTR,#TABLE ;取秒个位数;
MOVC A,@A+DPTR
MOV 21H,A ;送pb显示秒个位;
MOV DPTR,#0D2FFH
MOV A,21H
MOVX @DPTR,A
MOV A,40H
JNZ OVER ;sl=0?是,继续,否,over;
MOV A,41H
JNZ OVER ;sH=0?是,继续,否,over;
MOV A,60H
JNZ OVER
CLR TR0 ;定时器关闭;
SETB TR1 ;定时器打开;
SETB P1.2 ;断开继电器;
MOV DPTR,#0D1FFH
MOV A,#00H
MOVX @DPTR,A
MOV DPTR,#0D2FFH
MOV A,#0A0H
MOVX @DPTR,A
OVER:LJMP START
TABLE:DB 0A0H,0BBH,62H,2AH,39H,2CH,24H,0BAH,20H,28H,0A0H
RET
;计时函数;
TIME:
PUSH ACC
PUSH PSW
INC 30H ;20次计数器加1;
MOV A,30H
CJNE A,#20H,GOON ;到20次?是,继续执行,否,跳入GOON;
MIAO:
MOV 30H,#00H
DEC 40H ;秒低位减1;
MOV A,40H
CJNE A,#00H,GOON ;sl=0?是,继续,否,跳入goon;
DEC 41H ;秒高位减1;
MOV A,41H
CJNE A,#00H,GOON ;SH=0?是,继续,否,goon;
DEC 42H ;分减1;
CJNE A,#00H,GOON ;ml=0?是,继续,否goon;
GOON:
MOV TH0,#3CH
MOV TL0,#0B0H
SETB TR0
POP PSW
POP ACC
RETI
;键盘扫描程序;
KEYSCAN:
MOV DPTR,#CON ;控制字设置;
MOV A,#81H
MOVX @DPTR,A
LOOP1: MOV DPTR,#0D5FFH ;拉高PC.4;
MOV A,#10H
MOVX @DPTR,A
MOVX A,@DPTR
ANL A,#0FH ;判断是否有键闭合;
JZ DONE
ACALL DELAY50
MOV A,#10H
ANL A,#0FH
LOOP2:ADD A,#10H
CJNE A,#18H,LOOP3
MOV 42H,#00H
INC 40H
MOV R0,40H
CJNE @R0,#09H,LOOP3
INC 41H
MOV 40H,#00H
MOV R0,40H
LOOP3:CJNE A,#14H,LOOP4
CJNE @R0,#00H,LOOP4
MOV 40H,#09H
LOP: DEC 40H
DEC 41H
LOOP4:CJNE A,#12H,LOOP5
SETB TR0
CLR P1.2 ;继电器;
LOOP5:CJNE A,#11H,LOOP6
CLR TR0
SETB P1.2
LOOP6:MOV A,0D5FFH
MOV P1,A ;P1=PC ;
DONE: RET
DELAY50:MOV R7,#200
D1:MOV R6,#123
D2:DJNZ R6,D2
NOP
DJNZ R7,D1
RET
DELAY100:MOV R7,#400
D5:MOV R6,#123
D6:DJNZ R6,D2
NOP
DJNZ R7,D1
RET
END
[解决办法]
1. 你似乎是想用定时器中断来实现,因为你把定时器中断开了,可以你根本没设置定时器中断向量。
2. 而且你在主函数中直接LJMP,而不是调用子函数,怎么返回呢。
3. 为什么不用KEIL C51来实现呢,这个功能用C来实现很简单,逻辑性也比汇编好的多。
4. 如果你想用汇编实现的话,建议你再好好学一下51汇编和51单片机程序结构吧。
[解决办法]
一般典型的中断程序结构!
ORG 0000H
LJMP MAIN
ORG 00XXH(中断向量)
LJMP TIMEX
ORG XXXXH
MAIN:
...
TEST:
...
GOTO TEST
TIMEX:
...
如果对汇编不熟悉,
那还是先别用中断实现吧.
中断都不知道是怎么回事的话,那再怎么搞还是一头雾水.
[解决办法]
LJMP MAIN ORG 000BH
[解决办法]
楼上说的错误比较明显。先改正了再调试吧,还是嫌输入程序的时候麻烦,不好好按照规矩来写,不加注释,结果就是后来调试的时候一团乱麻啊!!!!