1 CURR_NUM EQU 30H ;HEX,进行15~1的倒计时
2 VAR_TIMER EQU 31H ;Soft timer,记录溢出的次数
3 VAR_LED EQU 32H ;Led value,#03FH for red led,#0CFH for green led,记录当前是红灯还是绿灯
4
5 DAT_74164 bit P0.6
6 CLK_74164 bit P0.7
7
8 DIG_1 bit p0.5
9 DIG_2 bit p0.4
10
11 ;*******************************************
12 org 0000H ;
13 jmp MAIN ;跳到0030H,中间留给中断
14
15 org 000BH ;预留的写法000BH:8051中断矢量地址,定时器T0中断的矢量地址
16 jmp interrupt_T0 ;普通的跳转没有写子程序,预留地址:以防还有其它中断程序冲掉其地址,中断程序没有调用过
17 /*什么时候执行中断程序?
18 T0溢出的时候 ~ CPU硬件将主程序自动转到000BH的第一句话:jmp interrupt T0 ~ 执行到RETI
19 不知道到主程序的哪句话T0会溢出即执行中断程序?程序执行的时机不定
20 */
21 ;*******************************************
22 org 0030H ;Start program from 0030H
23 MAIN: ;主程序只显示变量不管怎么改,变量什么时候变?
24 mov P0,#0FFH ;Initialize the port赋初始值
25 mov P1,#0FFH
26 mov P2,#0FFH
27 mov P3,#0FFH
28
29 /*Initilize the var*/
30 mov CURR_NUM,#15 `;给变量赋#15
31 mov VAR_TIMER,#00H ;溢出次数赋0
32 mov VAR_LED,#03FH ;红灯:3F #3FH
33 mov P1,VAR_LED ;把3F赋给p1,亮一下红灯
34
35 /*Initialize T0*/ ;给T0定义一下工作模式:16位定时器
36 mov TMOD,#01H
37 mov TH0,#0B1H ;20ms,load number,赋20ms
38 mov TL0,#0E0H,
39 setb TR0 ;Start T0,开始加一
40 setb ET0 ;Enable T0 inerrupt,开中断方式一
41 setb EA ;Enable interrupt,程序转到#000B
42 ;mov IE,#82H ;#10000010B ;两种不同的方式开中断
43
44 MAIN_LOOP:
45 call DISPLAY_NUM ;Display number,死循环,displaynumber
46 jmp MAIN_LOOP
47
48 ret
49 ;****************************************************
50 interrupt_T0: ;不是调用子程序,在硬件定位的地方直接写中断想做的事,T0溢出的时候执行
51 /*中断程序执行时间不可太长,太长主程序被堵死*/
52 /*中断程序中能不用全局变量就不用全局变量:中断程序应做到放在主程序的任何地方都能正确执行*/
53 /*主程序运行起来,执行过但没有被系统调用过*/
54 push acc ;Pay attention to here,push,pop:备份数据
55 push psw ;类似flag,全局变量,硬件都是默认的全局变量
56
57 ;Reset T0,must be done
58 ;clr TF0 ;auto clear the tag of overflow进入中断后程序自动清零
59 mov TH0,#0B1H ;20ms,reload number,清零后重新赋一个初始值
60 mov TL0,#0E0H
61
62 inc VAR_TIMER ;Add 20ms ;溢出次数加一
63 /*If VAR_TIMER=50,then time for 1s */
64 mov a,VAR_TIMER
65 cjne a,#50,INT_T0_EXIT ;溢出次数有没有到50,到了清零,没到直接结束
66 ;设置为50~20ms为了控制跳变的时间间隔为1s
67 mov VAR_TIMER,#00H
68 call NUM_SUB ;一轮结束,15秒显示结束跳到子函数减一显示14
69
70 INT_T0_EXIT:
71 pop psw
72 pop acc
73
74 reti ;中断返回通过RETI实现,必须加在中断程序的末尾
75 ;****************************************************
76 DISPLAY_NUM:;在执行显示函数的过程中T0在一直往上加,CPU执行显示,
77 ;定时器是单独的硬件每过一个机器周期加一到溢出~调用000B的程序,同时进行互不干扰
78 ;显示中:没有写何时调用程序,但中断来何时来显示执行到哪一行算哪一行,随时来随时停~执行中断
79 ;A<-A/B,
80 mov a,CURR_NUM
81 mov b,#0Ah
82 div ab
83 mov r0,a
84
85 ;Display the low value,显示个位
86 mov a,b
87 mov dptr,#TAB_LED
88 movc a,@a+dptr
89
90 call sendTo74164 ;Display the numbet
91 clr DIG_1
92 setb DIG_2
93 call DELAY_DISP
94
95 ;Display the high value,显示十位
96 mov a,r0
97 mov dptr,#TAB_LED
98 movc a,@a+dptr
99
100 call sendTo74164 ;Display the numbet
101 clr DIG_2
102 setb DIG_1
103 call DELAY_DISP
104
105 ret
106 ;*******************************************
107 ;Send data of A to chip 74LS164
108 sendTo74164:
109 push 07h
110 push acc
111
112 mov r7,#08 ;send 8 bits
113 SEND164_LOOP:
114 clr CLK_74164 ;clear clock-line for reading data
115 rlc a
116 mov DAT_74164,c ;move data-bit to data-line
117 setb CLK_74164 ;send data to 74164
118 djnz r7,SEND164_LOOP
119 clr CLK_74164 ;clear clock-line for reading data
120
121 pop acc
122 pop 07h
123 ret
124 ;****************************************************
125 NUM_SUB:
126 ;Get previos value
127 mov a,CURR_NUM
128 jz NUM_SUB_RESET ;到了1s看看变量是不是0,是赋15(红绿灯换3F变CF),不是-1
129
130 NUM_SUB_1:
131 ;Simple sub 1
132 dec CURR_NUM ;不是0,CURR_NUM-1
133 jmp NUM_SUB_EXIT
134
135 NUM_SUB_RESET:
136
137 mov CURR_NUM,#15 ;
138 call CHANGE_LED ;Red to green or green to red
139
140 NUM_SUB_EXIT:
141
142 ret
143 ;****************************************************
144 CHANGE_LED:
145 push acc
146
147 mov a,VAR_LED
148 cjne a,#03FH,TO_RED_LED
149 mov VAR_LED,#0CFH ;Red to green led
150 jmp CHANGE_LED_EXIT
151
152 TO_RED_LED:
153 mov VAR_LED,#03FH ;Green to red led
154
155 CHANGE_LED_EXIT:
156 mov P1,VAR_LED
157 pop acc
158
159 ret
160 ;****************************************************
161 DELAY_DISP:
162 mov r7,#15
163 DELAY_DISP_LOOP:
164 mov r6,#200
165 djnz r6,$
166 mov r6,#200
167 djnz r6,$
168
169 djnz r7,DELAY_DISP_LOOP
170 ret
171 ;****************************************************
172 ;****************************************************
173 ;LED code
174 TAB_LED:
175 DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H
176 ;****************************************************
177 END
主程序做工作只有显示数码管上的数字,开中断使得数字能够在1s过后跳变为下一个数字和改变后红绿灯