⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 8.asm

📁 单片机实验程序-13种-17.4M-pdf.zip
💻 ASM
字号:
;*************************************
;*                                   *
;*      自 动 往 返 小 汽 车         *
;*          2001年9月              *
;*************************************
;
;
;
;*************************************
;*                                   *
;*      主程序和中断程序入口         *
;*                                   *
;*************************************
;
		ORG     0000H			;程序执行起始地址
                LJMP    START	;跳至START
		ORG     0003H			;外中断0入口
                LJMP    INTEX0	;跳至INTEX0中断服务程序
		ORG     000BH			;定时器T0中断入口
                RETI				;中断返回
                ORG     0013H			;外中断1入口
                LJMP    INTEX1	;跳至INTEX1中断服务程序
                ORG     001BH			;定时器T1中断入口
                LJMP    INTT1	;跳至INTT1中断服务程序
		ORG     0023H			;串口中断入口
		RETI				;中断返回
		ORG     002BH			;定时器T2中断入口
		RETI				;中断返回
;
;***************************
;*                         *
;*       初始化程序        *
;*                         *
;****************************
CLEARMEMIO:        MOV   R0,  #70H      ;清70H-76H显示单元
                   MOV   R7,  #07H      ;循环次数
 ML0:              MOV   @R0, #00H      ;清0
                   INC   R0      	   ;下一地址
                   DJNZ  R7,  ML0       ;未完再循环
                   MOV   TMOD,#10H      	 ;T1为16位定时器
                   MOV   R4,#14H     	 ;1秒定时用(50毫秒20次)
                   MOV   TL1,#0B0H   	 ;50毫秒定时用初值
                   MOV   TH1,#3CH     	 ;
                   MOV     20H,#00H      	 ;清0操作
                   MOV     21H,#00H       ;
                   MOV     22H,#00H       ;
                   MOV     23H,#00H       ;
		   MOV	   24H,#00H      ;
                   CLR     30H            ;清停车标志
                   SETB    ET1            ;开T1中断
                   SETB    EX1            ;开外中断1
                   SETB    IT1            ;外中断1采用边沿触发
                   SETB    IT0            ;外中断0优先级为1(最高)
                   SETB    EX0            ;开外中断0
                   SETB   EA       	     ;开总中断允许
                   SETB   TR1        	 ;开启定时器T1
                   RET            	    	;子程序返回
;
;*************************************
;*                                   *
;*	      主  程    序               *
;*                                   *
;*************************************
;
START:          LCALL   CLEARMEMIO      ;上电初始化
                SETB    P1.6    		   ;选择7.5V输出
                CLR     P1.7    		   ;选择7.5V输出
                SETB    P3.7    		   ;前进状态
                CLR     P3.6    		   ;前进状态
                CLR     P1.0    		   ;电机供电开始
MAIN:           LCALL   DISP    		   ;LED显示一次
                LJMP	MAIN    		   ;转MAIN循环
                NOP             		   ;PC值出错处理
      	        NOP
	       	LJMP   	START    	   ;重新初始化
;
;*************************************
;*                                   *
;*外中断0服务程序,用作跑道位置处理 *
;*   23H作跑道计数器                 *
;*************************************
INTEX0:       PUSH    ACC    		   ;堆栈保护
              PUSH    PSW    		   ;
              CLR     EX0    		   ;关中断
              LCALL   DISP    		   ;LED显示一次(延时抗干扰)
              JB     P3.2,IN0RET    	   ;P3.2为1退出(干扰)
              INC     23H    		   ;跑道计数器加1
              MOV     A,23H    		   ;数据入A
              CJNE    A,#06H,JUDGE1     ;不是第6道转JUDGE1
              LCALL   STOP    		   ;是第6道,停车
              LJMP    IN0RET    		   ;转中断退出
JUDGE1:       CJNE    A,#03H,JUDGE2     ;不是第3道转JUDGE2
              LCALL   STOPSLOW    	   ;是第3道,变慢车
              LJMP    IN0RET    		   ;转中断退出
JUDGE2:       CJNE    A,#04H,JUDGE3     ;不是第4道转JUDGE3
              LCALL   FAST    		   ;是第4道,变快车
              LJMP    IN0RET    		   ;转中断退出
JUDGE3:       CJNE    A,#05H,IN0RET     ;不是第5道转INORET退出
              LCALL   STOPSLOW    	   ;是第5道,变慢车
IN0RET:       CLR     IE0    		   ;清外中断0中断标志
              POP     PSW    		   ;恢复现场
              POP     ACC    		   ;
              LCALL   DL7MS    		   ;延时7毫秒(抗干扰)
              SETB    EX0    		   ;开外中断0
              RETI    		   		   ;中断返回
;
;************************************
;*          慢车控制子程序          *
;************************************
STOPSLOW:      CLR     P1.6    		   ;关7.5V电源
               CPL     P3.6    		   ;反向驱动(刹车)
               CPL     P3.7    		   ;反向驱动
               LCALL   DS50MS    	   ;刹车时间(可根据试车情况调整)
               LCALL   DS50MS    	   ;
               LCALL   DS50MS    	   ;
               CPL     P3.6    		   ;正向驱动
               CPL     P3.7    		   ;正向驱动
               SETB    P1.7    		   ;开4.3V电源
               RET    		   			;返回
;
;************************************
;*         快车控制子程序           *
;************************************
FAST:          CLR     P1.7    		   ; 关4.3V电源
               SETB    P1.6    		   ; 开7.5V电源
               RET    		  		   ;返回
;
;************************************
;*         停车控制程序             *
;************************************
STOP:         MOV    23H,#00H    	   ;跑道计数单元清0
              CPL     P3.6    		   ;反向驱动(刹车)
              CPL     P3.7    		   ;反向驱动(刹车)
              LCALL   DS50MS    		   ;刹车时间
              LCALL   DS50MS    		   ;刹车时间(可调整)
              SETB   P1.0    		   ;关电机电源
              SETB   PT1    		       ;定时器T1为高优先级
              LCALL   DS10S    		   ;停车10秒
              CLR     PT1    		   ;恢复T1为低优先级
              SETB    P1.6    		   ;开7.5V电源(高速)
              CLR     P1.7    		   ;关4.3V
              CLR     P1.0    		   ;电机电源开
              CPL     30H    		   ;停车点位置判断标志取反
              JB      30H,STREN    	   ;为1(中途停车)转STREN
              LCALL   CLR00    		   ;是终点,调复0程序
 STREN:       RET    		   			;返回
;
;*********************************
;*        计时清0程序           *
;*********************************
CLR00:           MOV   70H,#00H    		   ;计时单元清0
                 MOV   71H,#00H    		   ;计时单元清0
                 MOV   72H,#00H    		   ;计时单元清0
                 MOV   73H,#00H    		   ;计时单元清0
                 RET    		   			   ;返回
;
;*************************************
;*                                   *
;*   外中断1程序,里程计数用        *
;*   20H、21H、22H、24H作计数器     *
;*************************************
INTEX1:          PUSH   ACC    		   	   ;堆栈保护
                 PUSH   PSW    		   	   ;
                 CLR    EX1    		   	   ;关外中断1
                 INC    20H    		   	   ;圈加1
  LLLL:          MOV    A,20H    		   ;判断是否满6圈
                 CJNE   A,#06H,LLL    	   ;不满6圈转LLL退出
                 MOV    20H,#00H    		   ;满6圈清0进位(6圈为1米)
                 INC    21H    		   	   ;上位加1
                 MOV    A,21H    		   ;判断是否满10
                 CJNE   A,#0AH,LLL    	   ;不满10转LLL
                 MOV    21H,#00H    		   ; 满10清0进1位
                 INC    22H    		   	   ; 高位加1
                 MOV    A,22H    		   ; 判断是否满10
                 CJNE   A,#0AH,LLL    	   ; 不满10转LLL
                 MOV    22H,#00H    		   ; 满10清0进1位
                 INC    24H    		  	   ; 高位加1
                 MOV    A,24H    		   ; 判断是否满10
                 CJNE   A,#0AH,LLL    	   ; 不满10转LLL
                 MOV    24H,#00H    		   ; 满10清0
LLL:             MOV    74H,21H    		   ; 将里程数移入显示单元(个位)
                 MOV    75H,22H    		   ; 将里程数移入显示单元(十位)
                 MOV    76H,24H    		   ; 将里程数移入显示单元(百位)
IN1RET:          POP    PSW    		   		;恢复堆栈
                 POP    ACC    		  		;
                 SETB   EX1    		   		;开外中断1
                 RETI    		   			;中断返回
;
;*************************************
;*           时间计时器程序           *
;*	     (T1定时中断服务程序)      *
;*                                    *
;*************************************
INTT1:             PUSH  	ACC    		   ;堆栈保护
                   PUSH  	PSW    		   ;
                   MOV 	TL1,#0B0H      ;赋50毫秒定时初值
                   MOV 	TH1,#3CH    	   ;
                   DEC 	R4    		   ;减1
                   MOV 	A,R4    		   ;
                   JNZ 	RETT0    	   ;不为0转RETT0
                   MOV 	R4,#14H    	   ;为0(1秒到)重赋初值
                   MOV 	R0,#71H    	   ;地址指向71H
                   ACALL 	ADD1    		   ;加1秒操作
                   MOV 	A,R3    		   ;
                   CLR 	C    		   ;
                   CJNE	A,#60H,CC  	   ;是否为60秒?
CC: 		   JC	 RETT0    	   ;小于60转RETT0
                   ACALL CLR0    	   ;大于或等于60清0
                   MOV 	R0,#73H    	   ;指向分计时地址单元
                   ACALL ADD1    		   ;分加1
                   MOV 	A,R3    		   ;
                   CLR 	C    		   ;
                   CJNE A,#60H,CCC      ;是否为60分?
CCC: 		   JC	    RETT0    	    ;小于60转RETT0
                   ACALL		CLR0    		    ;大于或等于60分计时单元清0
  RETT0: 	   POP 		PSW    		    ;恢复堆栈
                   POP 		ACC    		    ;
                   RETI    		   			;中断返回
;
              ;;;;;;;;;;;;;; ;;;;
              ; 加1操作程序    ;
              ;;;;;;;;;;;;;; ;;;;
ADD1: 		   MOV	 A,@R0    		    ;取计数值
                   DEC	 R0    		    		;指向低一个地址
                   SWAP	 A    		    		;计数值高低四位交换
                   ORL 	 A,@R0    		    ;相或组合成一个数据
                   ADD 	 A,#01H    		    ;加1
                   DA 	 A    		    		;十进制调整
                   MOV 	 R3,A    		    ;暂存R3内
                   ANL 	 A,#0FH    		    ;高四位变0
                   MOV	 @R0,A    		    ;放回低地址
                   MOV	 A,R3    		    ;取回R3内数据
                   INC	 R0    		    		;地址加1
                   SWAP	 A    		    		;高低四位交换
                   ANL 	 A,#0FH    		    ;高四位为0
                   MOV	 @R0,A    		    ;放回原地址
                   RET    		    			;返回
;
               ;;;;;;;;;;;;;
               ; 清0程序  ;
               ;;;;;;;;;;;;;
CLR0: 		   CLR	 A    		    		;清A
                   MOV   @R0,A    		    ;对应地址单元清0
                   DEC	 R0    		    		;指向低一地址
                   MOV	 @R0,A    		    ;清0
                   RET    		    			;返回
;
;

               ;;;;;;;;;;;;;
               ; 显示程序  ;
               ;;;;;;;;;;;;;
DISP: 		   MOV 	R1,#70H    		    ;显示数据首址
                   MOV	R5,#0FEH    		    ;扫描字
PLAY:		   MOV	A,R5    		    		;扫描字入A
                   MOV	P2,A    		    		;从P2口输出
                   MOV 	A,@R1    		    ;取显示数据
                   MOV 	DPTR,#TAB        	;取段码表首址
                   MOVC A,@A+DPTR        		; 查数据对应段码
                   MOV	 P0,A    	    		;段码从P0口输出
                   LCALL DL1MS    			;点亮1毫秒
                   INC 	R1    		    		;指向下显示数地址
                   MOV 	A,R5    		    		;扫描字入A
                   JNB	 ACC.6,ENDOUT   		;ACC.6=0转ENDOUT结束
                   RL 	A    		    		;循环左移
                   MOV 	R5,A    		    		;放回A
                   AJMP PLAY    		    		;转PLAY再显示
ENDOUT:		   MOV  P2,#0FFH	    		;显示结束处理。P2口置1
                   RET    		    			;子程序结束
;
;LED共阴段码表(0-9)
TAB: 		   DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH
;
;1毫秒延时程序
DL1MS: 		MOV R6,#14H
DL1:   		MOV R7,#19H
DL2:   		DJNZ R7,DL2
                DJNZ R6,DL1
                RET
;
;延时程序,用调用显示程序实现,可使LED显示稳定
DS50MS: 	LCALL DISP	    		;(7毫秒)
                LCALL DISP
                LCALL DISP
DS20MS: 	LCALL DISP
                LCALL DISP
                LCALL DISP
                RET
;
;10秒延时程序,用调用显示程序实现,可使LED显示不熄灭
DS10S:    	MOV    R2,#08H	    ;(8*11*16*7=9956毫秒)
TI0:    	MOV    R0,#0B0H
TI1:    	LCALL  DISP
         	DJNZ   R0,TI1
        	DJNZ   R2,TI0
        	RET
;7毫秒延时程序,跑道计数器抗干扰用
DL7MS:    SETB   PX1    		       ;外中断1置高优先级
          MOV    R2,#0EH    	               ;赋定时值
DL11:     LCALL  DISP    		       ;调用显示程序
          DJNZ   R2,DL11    	               ;循环
          CLR    PX1    		       ;外中断1恢复低优先级
          RET    		    	       ;返回
;
          END    		    		;程序结束

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -