用定时器和中断共同实现红绿灯程序
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过后跳变为下一个数字和改变后红绿灯