注:本篇文章部分基于上一篇数码管的文章,如果有关于数码管显示函数不懂的可以先看一下上一篇文章: 51单片机数码管显示函数
另外,关于定时器与中断系统的更多详细介绍,可以看一下我一年半前写的文章(当时讲解是基于C语言的):定时器与中断系统
目录
源代码
cpp
ORG 00H
SMGPTR DATA 30H
DISDATA DATA 31H
//DISDATA: 31H - 36H (DATA Arr)
SMGBIN DATA 40H
TEMP1 DATA 41H
TEMP2 DATA 42H
TEMP3 DATA 43H
SEC DATA 50H
COUNT1 DATA 51H
COUNT2 DATA 52H
COUNT3 DATA 53H
LJMP START
;ORG 000BH
;LJMP T0M2_ISR
;LJMP T0M1_ISR
ORG 001BH
;LJMP T1M1_ISR
LJMP T1M2_ISR
ORG 30H
START:
MOV SEC,#0
MOV COUNT1,#0
MOV COUNT2,#0
MOV COUNT3,#0
;LCALL T0M1_INIT
;LCALL T1M1_INIT
;LCALL T0M2_INIT
LCALL T1M2_INIT
LOOP:
MOV A,SEC
MOV B,#10
DIV AB
MOV DISDATA+0,A
MOV DISDATA+1,B
LCALL DISPLAY
SJMP LOOP
SJMP START
/////////////////////////////////////////////////////////
//TIMER0 MODE1
T0M1_INIT:
MOV TMOD,#01H
MOV TH0,#(65535-50000)/256
MOV TL0,#(65535-50000)MOD 256
SETB EA
SETB ET0
SETB TR0
RET
T0M1_ISR:
MOV TH0,#(65535-50000)/256
MOV TL0,#(65536-50000)MOD 256
INC COUNT1
MOV R1,COUNT1
CJNE R1,#4,T0M1_NEXT //50ms*4=200ms
MOV COUNT1,#0
INC COUNT2
MOV R1,COUNT2
CJNE R1,#5,T0M1_NEXT //200ms*5=1s
MOV COUNT2,#0
INC SEC
MOV R1,SEC
CJNE R1,#100,T0M1_NEXT
MOV SEC,#0
T0M1_NEXT:RETI
/////////////////////////////////////////////////////////
//TIMER1 MODE1
T1M1_INIT:
MOV TMOD,#10H
MOV TH1,#(65535-50000)/256
MOV TL1,#(65535-50000)MOD 256
SETB EA
SETB ET1
SETB TR1
RET
T1M1_ISR:
MOV TH1,#(65535-50000)/256
MOV TL1,#(65536-50000)MOD 256
INC COUNT1
MOV R1,COUNT1
CJNE R1,#4,T1M1_NEXT //50ms*4=200ms
MOV COUNT1,#0
INC COUNT2
MOV R1,COUNT2
CJNE R1,#5,T1M1_NEXT //200ms*5=1s
MOV COUNT2,#0
INC SEC
MOV R1,SEC
CJNE R1,#100,T1M1_NEXT
MOV SEC,#0
T1M1_NEXT:RETI
/////////////////////////////////////////////////////////
//TIMER0 MODE2
T0M2_INIT:
MOV TMOD,#02H
MOV TH0,#256-200
MOV TL0,#256-200
SETB EA
SETB ET0
SETB TR0
RET
T0M2_ISR:
INC COUNT1
MOV R1,COUNT1
CJNE R1,#100,T0M2_NEXT //0.2ms*100 = 20ms
MOV COUNT1,#0
INC COUNT2
MOV R1,COUNT2
CJNE R1,#10,T0M2_NEXT //20ms*10=200ms
MOV COUNT2,#0
INC COUNT3
MOV R1,COUNT3
CJNE R1,#5,T0M2_NEXT //200ms*5=1s
MOV COUNT3,#0
INC SEC
MOV R1,SEC
CJNE R1,#100,T0M2_NEXT
MOV SEC,#0
T0M2_NEXT:RETI
/////////////////////////////////////////////////////////
//TIMER1 MODE2
T1M2_INIT:
MOV TMOD,#20H
MOV TH1,#256-200
MOV TL1,#256-200
SETB EA
SETB ET1
SETB TR1
RET
T1M2_ISR:
INC COUNT1
MOV R1,COUNT1
CJNE R1,#100,T1M2_NEXT //0.2ms*100 = 20ms
MOV COUNT1,#0
INC COUNT2
MOV R1,COUNT2
CJNE R1,#10,T1M2_NEXT //20ms*10=200ms
MOV COUNT2,#0
INC COUNT3
MOV R1,COUNT3
CJNE R1,#5,T1M2_NEXT //200ms*5=1s
MOV COUNT3,#0
INC SEC
MOV R1,SEC
CJNE R1,#100,T1M2_NEXT
MOV SEC,#0
T1M2_NEXT:RETI
/////////////////////////////////////////////////////////
DISPLAY:
MOV SMGBIN,#01111111B
MOV SMGPTR,#0
DIS1:
MOV A,SMGBIN
RL A
MOV SMGBIN,A
MOV P2,SMGBIN //BIT CHOICE
MOV A,SMGPTR
ADD A,#DISDATA
MOV R0, A
MOV TEMP1,@R0 //DATA CHOICE
MOV DPTR,#TAB
MOV A,TEMP1
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
INC SMGPTR
MOV A,SMGPTR
CJNE A,#6,DIS1
RET
/////////////////////////
DELAY:MOV R5,#1 //1ms
DELAY3:MOV R6,#2
DELAY2:MOV R7,#248
DELAY1:DJNZ R7,DELAY1
DJNZ R6,DELAY2
DJNZ R5,DELAY3
RET
////////////////////////
TAB:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END
代码作用就是每1s实现让SEC+1,并且显示在数码管上,这里相较于上期文章有点修改,就是DELAY函数的时间从10ms改成了1ms,尽量使得对中断的干扰没有那么大
电路图

代码框架
讲使用之前先讲一下框架,主要框架就是
ORG 00H
//变量定义
LJMP START
//中断向量地址(四选一)
;ORG 000BH
;LJMP T0M2_ISR
;LJMP T0M1_ISR
ORG 001BH
;LJMP T1M1_ISR
LJMP T1M2_ISR
ORG 30H
START:
//初始化变量
MOV SEC,#0
MOV COUNT1,#0
MOV COUNT2,#0
MOV COUNT3,#0
//初始化定时器(四选一)
;LCALL T0M1_INIT
;LCALL T1M1_INIT
;LCALL T0M2_INIT
LCALL T1M2_INIT
LOOP:
//取出数字并且显示
MOV A,SEC
MOV B,#10
DIV AB
MOV DISDATA+0,A
MOV DISDATA+1,B
LCALL DISPLAY
SJMP LOOP
SJMP START
//下面是各种函数定义
代码使用
代码使用主要配置两个部分
第一部分

这里的配置是ORG 000BH对应定时器0(包含定时器0模式1和2) ,然后ORG001BH对应定时器1(包含定时器1模式1和2),写完定时器起始地址之后立刻接上中断函数的名字
例如上面就是调用定时器1模式2,所以用ORG 001BH接上LJMP T1M2_ISR(定时器1模式2的中断函数)
假设我需要调用定时器1模式1,就用ORG 000BH后面接上LJMP T0M1_ISR(定时器0模式2的中断函数)
当然,要注意,如果确定了一个中断函数和模式,整段代码就只能使用这个中断函数和模式,否则定时器就没有办法正常使用
第二部分
第二部分就是在LOOP循环前的初始化部分调用一下选择的定时器及模式初始化函数

比如这里就是调用初始化定时器1模式2的函数
函数说明

这是定时器0模式1的函数,主要分为初始化函数和中断处理函数两个部分,中断处理函数就是每50ms进入这个函数,然后执行计数,这里设置的就是50ms*4*5=1s就加一次SEC,这样我们就可以在主函数中用数码管显示SEC,实现的效果就是每秒SEC+1并且显示到数码管上的效果
当然,我们也可以在中断处理函数里调用别的函数,比如我们在这里调用函数

这里调用的函数就是在200ms计数之后,就可以实现200ms执行一次这个函数,比如每200ms控制LED开关之类的作用,当然,这里的时间间隔也可以自己控制,实现更多的功能,比如下面
功能拓展
拓展电路图

如图,在P3.0和P3.1分别接了LED1和LED2,并且LED共阳极,通过控制P3.0和P3.1让LED闪烁,这里的拓展功能是使用上面的函数,用定时器1工作方式2实现两个LED轮流发光,同时保留秒表每秒+1的作用
LED轮闪函数


这里通过判断LEDMODE来判断状态,如果LEDMODE为1就执行模式1并且把LEDMODE置为0,如果LEDMODE为0就执行模式2并且把LEDMODE置为1,如此循环,实现LED的循环闪烁
基础配置
同上面讲述的时候说的,配置主要两个部分,一是选择中断地址,二是选择初始化函数

调用LED闪烁函数
要求每200ms实现LED闪烁变换,就在中断处理函数200ms位置调用LED_CHANGE函数

如此即可....
拓展部分总代码
cpp
ORG 00H
SMGPTR DATA 30H
DISDATA DATA 31H
//DISDATA: 31H - 36H (DATA Arr)
SMGBIN DATA 40H
TEMP1 DATA 41H
TEMP2 DATA 42H
TEMP3 DATA 43H
SEC DATA 50H
COUNT1 DATA 51H
COUNT2 DATA 52H
COUNT3 DATA 53H
LEDMODE DATA 54H
LJMP START
ORG 001BH
LJMP T1M2_ISR
ORG 30H
START:
MOV SEC,#0
MOV COUNT1,#0
MOV COUNT2,#0
MOV COUNT3,#0
LCALL T1M2_INIT
LOOP:
MOV A,SEC
MOV B,#10
DIV AB
MOV DISDATA+0,A
MOV DISDATA+1,B
LCALL DISPLAY
SJMP LOOP
SJMP START
/////////////////////////////////////////////////////////
LED_CHANGE:
MOV A,LEDMODE
CJNE A,#1,LEDMODE2
LEDMODE1://LEDMODE==1
SETB P3.0
CLR P3.1
MOV LEDMODE,#0
SJMP LED_EXIT
LEDMODE2://LEDMODE==0
SETB P3.1
CLR P3.0
MOV LEDMODE,#1
LED_EXIT:
RET
/////////////////////////////////////////////////////////
//TIMER1 MODE2
T1M2_INIT:
MOV TMOD,#20H
MOV TH1,#256-200
MOV TL1,#256-200
SETB EA
SETB ET1
SETB TR1
RET
T1M2_ISR:
INC COUNT1
MOV R1,COUNT1
CJNE R1,#100,T1M2_NEXT //0.2ms*100 = 20ms
MOV COUNT1,#0
INC COUNT2
MOV R1,COUNT2
CJNE R1,#10,T1M2_NEXT //20ms*10=200ms
MOV COUNT2,#0
LCALL LED_CHANGE
INC COUNT3
MOV R1,COUNT3
CJNE R1,#5,T1M2_NEXT //200ms*5=1s
MOV COUNT3,#0
INC SEC
MOV R1,SEC
CJNE R1,#100,T1M2_NEXT
MOV SEC,#0
T1M2_NEXT:RETI
/////////////////////////////////////////////////////////
DISPLAY:
MOV SMGBIN,#01111111B
MOV SMGPTR,#0
DIS1:
MOV A,SMGBIN
RL A
MOV SMGBIN,A
MOV P2,SMGBIN //BIT CHOICE
MOV A,SMGPTR
ADD A,#DISDATA
MOV R0, A
MOV TEMP1,@R0 //DATA CHOICE
MOV DPTR,#TAB
MOV A,TEMP1
MOVC A,@A+DPTR
MOV P0,A
LCALL DELAY
INC SMGPTR
MOV A,SMGPTR
CJNE A,#6,DIS1
RET
/////////////////////////
DELAY:MOV R5,#1 //1ms
DELAY3:MOV R6,#2
DELAY2:MOV R7,#248
DELAY1:DJNZ R7,DELAY1
DJNZ R6,DELAY2
DJNZ R5,DELAY3
RET
////////////////////////
TAB:DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH
END
拓展部分实现效果
LED以200ms周期循环闪烁,定时器1s加一
