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

📄 ic.asm

📁 IC卡收费器
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	JMP NUEND
NU5:
	CJNE A,#5H,NU6
	MOV 72H,#6DH
	JMP NUEND
NU6:
	CJNE A,#6H,NU7
	MOV 72H,#7DH
	JMP NUEND
NU7:
	CJNE A,#7H,NU8
	MOV 72H,#07H
	JMP NUEND
NU8:
	CJNE A,#8H,NU9
	MOV 72H,#7FH
	JMP NUEND
NU9:
	MOV 72H,#6FH
NUEND:
RET
;*****************************向存储芯片写入*******************
WR_1B:  SETB      SDA            ;初始状态
        SETB      SCL            ;置SDA&SCL=1	
        ACALL     START	         ;启动I2C总线
        MOV       R7,#0A0H       ;写命令	
        ACALL     WR8BIT         ;按位写入1个字节	
        ACALL     CACK	         ;应答检查
        MOV       ACC,POINTER    ;取芯片地址
        MOV       R7,ACC         ;送芯片地址
        ACALL     WR8BIT	 ;写芯片地址
        ACALL     CACK	         ;应答检查
        MOV       ACC,NUMB       ;取待写数据
	MOV       R7,ACC         ;送数据 
        ACALL     WR8BIT	 ;写数据
	ACALL     CACK	         ;应答检查
	ACALL     STOP	         ;停止
	ACALL     DEL10MS	 ;等待内部写周期完成
        RET
;***************************读存储芯片指定地址的单元******************
RD_1B:        LCALL      START	;启动总线
	      MOV        R7,#0A0H	;写命令
              LCALL      WR8BIT	;写写命令
	      LCALL      CACK	;应答检查
MOV        A,POINTER	;取地址
MOV        R7,A	;送地址
LCALL      WR8BIT	;写地址
LCALL      CACK	;应答检查
SETB       SDA	;
SETB       SCL	;保证启动条件
LCALL      START	;再次启动总线,以便进行读操作
MOV        R7,#0A1H	;送芯片地址+写命令
LCALL      WR8BIT	;写芯片地址+写命令
LCALL      CACK	;应答检查
LCALL      RD8BIT	;读8位数
LCALL      STOP	;关闭总线
RET
START:     LCALL       DEL5US	;对2402操作开始
	   CLR         SDA		;在SCL=1时,SDA由1变为0表示开始
	   LCALL       DEL5US	
	   CLR         SCL
    	   LCALL       DEL5US
      RET
;***************************写8比特*****************************
WR8BIT: MOV       A,R7	       ;将R7中的数发送出去
	MOV       R6,#08H      ;数据位数
WR1BIT: RLC       A	       ;将A中的数据移到数据线上
	MOV       SDA,C	       ;送出数据
	LCALL     DEL5US       ;延时5US
        SETB      SCL	       ;发送串行时钟进行写操作
	LCALL     DEL5US	
	CLR       SCL
	DJNZ      R6,WR1BIT	;串行发送8BIT
        SETB      SDA	        ;准备接收ACK	
        LCALL     DEL5US	
	SETB      SCL	        ;接收ACK的时钟
	LCALL     DEL5US
	RET
CACK:   MOV       R1,#05        ;检测应答	      
CACK1:  MOV       C,SDA
	DJNZ	  R1,Y1
	LJMP   	  Y2	 
Y1:     JC        CACK1         ;有应答的时候应为低电平
	AJMP	  Y3	
Y2:     MOV	  R1,#06H
Y3:	CLR       SCL	        ;为下一步其他操作做准备
	CLR       SDA	        ;
	LCALL     DEL1MS	;等待内部写完
RET
;***************************读8比特*****************************
RD8BIT:       PUSH   ACC	;保存 ACC
	      MOV         R6,#08H	
RD1B:         SETB        SDA	;置数据线=1
	      LCALL       DEL5US	
	      SETB        SCL	;输出一个串行时钟
	      LCALL       DEL5US	
	      MOV         C,SDA	;读数据线上的数据到C
	      RLC         A		;移到ACC
	      LCALL       DEL5US	
	      CLR         SCL
	      DJNZ        R6,RD1B	;读8BIT数据
	      LCALL       DEL5US
	      CLR         SDA
	      MOV         R7,ACC	;将接收到的数据保存到R7
	      POP         ACC		;还原ACC
              RET
STOP:         LCALL      DEL5US	;对2402操作结束
              SETB       SCL		;在 SCL	=1时,SDA由0变为1表示结束
	      LCALL      DEL5US	
	      SETB       SDA
	      LCALL      DEL5US
	      RET
DEL5US:         NOP
                NOP
                NOP
	        NOP
	        RET
DEL1MS:   MOV  R4,#200
	  NOP
	  NOP
	  NOP
	  DJNZ R4,$-3
	  RET
DEL10MS:  MOV     3FH,#10
	  LCALL   DEL1MS
	  DJNZ    3FH,$-3
RET
;*******************把内存30~37写入外存30H~37H****************
WT:
		MOV R0,#30H
	MOV R1,#30H
CUN1:
	MOV POINTER,R0
	MOV 39H,R1
	MOV NUMB,@R1
	LCALL WR_1B
	CJNE R1,#06H,W13
	JMP W11
W13:
	MOV R1,39H
	INC R0
	INC R1
	CJNE R0,#36H,CUN1
	JMP W21
W11:
	LCALL WRONG
W21:

	RET
;****************把内存40~47写入外存50H~57H**********************
WT1:
	MOV R0,#50H
	MOV R1,#40H
RCUN1:
	MOV POINTER,R0
	MOV 59H,R1
	MOV NUMB,@R1
	LCALL WR_1B
	CJNE R1,#06H,RW13
	JMP RW11
RW13:
	MOV R1,59H
	INC R0
	INC R1
	CJNE R0,#56H,RCUN1
	JMP RW21
RW11:
	LCALL WRONG
RW21:
	RET
;***************************60TO40****************************
STS:
	MOV R4,#05H
	MOV R1,#60H
DD1:
	MOV @R1,#00H
	INC R1
	DJNZ R4,DD1
	LCALL NUIN
	MOV R6,#05H
	MOV R0,#60H
	MOV A,#40H
	ADD A,R7
	CLR C
	SUBB A,#2H
	MOV R1,A
	MOV 53H,A 
DD2:
	MOV A,@R0
	MOV @R1,A
	INC R0
	DEC R1
	DJNZ R7,DD2
	MOV R1,53H
	INC R1
DD3:
	MOV @R1,#00H
	INC R1
	;MOV A,R1
	CJNE R1,#46H,DD3
	RET
;*****************************错卡显示********************
WRONG:
	CLR  WELA
       	MOV  P0,#00H   
        SETB WELA
        CLR  WELA                              
	CLR  DULA
	MOV  P0,#08H         ;全选中,显示下横线
	SETB DULA
	CLR  DULA
        LCALL DELAY2
	MOV R3,#100
WRO:
	LCALL DELAY2
	DJNZ R3,WRO
	RET
;********************把外存30~37读入内存30H~37H*********************
RT:
		MOV R0,#30H
	MOV R1,#30H
QU1:
	MOV POINTER,R0
	MOV 39H,R1
	LCALL RD_1B
	MOV A,R7
	MOV R1,39H
	MOV @R1,A
	INC R0
	INC R1
	CJNE R0,#36H,QU1
	JMP RT21
RT11:
	LCALL WRONG
RT21:
RET
;***************************显示余额*********************
SHOWSUR:
SH0:
	MOV R7,#07H
	LCALL KSTART       ;有任意键按下则返回      
	JNZ SHEND
	MOV 71H,#0FEH      ;初始化,此时选中最左边的数码管
SH1:
	MOV R1,#35H        ;循环显示的起始位置,数据的最高位
SH3:
	DJNZ R7,SH2        ;一轮是否显示完
	MOV R7,#07h        ;显示完毕则重给R2赋原值
	JMP SH0
SH2:
	MOV A,@R1          ;显示的数字放入A中
	LCALL K2N
	CLR  DULA
	MOV  P0,#00H         
	SETB DULA
	CLR  DULA
        CLR  WELA
       	MOV  P0,71H   
        SETB WELA
        CLR  WELA                            
	CLR  DULA
	MOV  P0,72H         ;全灭,选中71H位,显示72H内容
	SETB DULA        
	CLR  DULA
        LCALL DELAY2
	MOV A,71H
	RL A
	MOV 71H,A
	DEC R1
	JMP SH3
SHEND:
	RET
;*****************把外存50~57写入内存40H~47H*************************
RRT1:
	MOV R0,#50H
	MOV R1,#40H
RQU1:
	MOV POINTER,R0
	MOV 59H,R1
	LCALL RD_1B
	MOV A,R7
	MOV R1,59H
	MOV @R1,A
	INC R0
	INC R1
	CJNE R0,#56H,RQU1
	JMP RRT21
RRT11:
	LCALL WRONG
RRT21:
RET
;***************************显示上一次的操作数*********************
SHOWDO:
DO0:
	MOV R7,#07H
	LCALL KSTART     ;有任意键按下则返回      
	JNZ DOEND
	MOV 71H,#0FEH    ;初始化,此时选中最左边的数码管
DO1:
	MOV R1,#45H      ;循环显示的起始位置,数据的最高位
DO3:
	DJNZ R7,DO2      ;一轮是否显示完
	MOV R7,#07h      ;显示完毕则重给R2赋原值
	JMP DO0
DO2:
	MOV A,@R1        ;显示的数字放入A中
	LCALL K2N
	CLR  DULA
	MOV  P0,#00H         
	SETB DULA
	CLR  DULA
        CLR  WELA
       	MOV  P0,71H   
        SETB WELA
        CLR  WELA                            
	CLR  DULA
	MOV  P0,72H       ;全灭,选中71H位,显示72H内容
	SETB DULA        
	CLR  DULA
        LCALL DELAY2
	MOV A,71H
	RL A
	MOV 71H,A
	DEC R1
	JMP DO3
DOEND:
	RET
;********************选择功能键的时候进行显示************************
SELSHOW:                        ;因为按键的问题,本来应该1对应1,现在改为4对应1
	CJNE  A,#0CH,SHOW2
                                ;按下的是4,选择的是功能1,显示的也是1,按键依次判断,不是的就顺移
	CLR  WELA
       	MOV  P0,#00H   
        SETB WELA
        CLR  WELA 
        CLR  DULA
	MOV  P0,#00H             ;位全选,全灭
	SETB DULA
	CLR  DULA 
        CLR  WELA
       	MOV  P0,#0FEH   
        SETB WELA
        CLR  WELA                             
	CLR  DULA
	MOV  P0,#06H               ;选中Q1,显示1
	SETB DULA
	CLR  DULA
        LCALL DELAY2
	MOV R0,A                  ;键值送到R0 中进行传递
	JMP KEYSCAN       
;调用键盘扫描程序,将扫描值放回累加器中,返回的时候不再回到这里,
;而是回到上面调用SELSHOW处     
SHOW2:
	CJNE  A,#0DH,SHOW3
	CLR  WELA
       	MOV  P0,#00H   
        SETB WELA
        CLR  WELA 
        CLR  DULA
	MOV  P0,#00H         ;位全选,全灭
	SETB DULA
	CLR  DULA 
        CLR  WELA
       	MOV  P0,#0FEH   
        SETB WELA
        CLR  WELA                             
	CLR  DULA
	MOV  P0,#5BH         ;选中Q1,显示2
	SETB DULA
	CLR  DULA
        LCALL DELAY2
	MOV R0,A
	JMP KEYSCAN
SHOW3:
	CJNE  A,#0EH,SHOW4
	CLR  WELA
       	MOV  P0,#00H   
        SETB WELA
        CLR  WELA 
        CLR  DULA
	MOV  P0,#00H         ;位全选,全灭
	SETB DULA
	CLR  DULA 
        CLR  WELA
       	MOV  P0,#0FEH   
        SETB WELA
        CLR  WELA                             
	CLR  DULA
	MOV  P0,#4FH         ;选中Q1,显示3
	SETB DULA
	CLR  DULA
        LCALL DELAY2
	MOV R0,A
	JMP KEYSCAN
SHOW4:
	CJNE  A,#0FH,SURE
	CLR  WELA
       	MOV  P0,#00H   
        SETB WELA
        CLR  WELA 
        CLR  DULA
	MOV  P0,#00H         ;位全选,全灭
	SETB DULA
	CLR  DULA 
        CLR  WELA
       	MOV  P0,#0FEH   
        SETB WELA
        CLR  WELA                             
	CLR  DULA
	MOV  P0,#66H         ;选中Q1,显示4
	SETB DULA
	CLR  DULA
        LCALL DELAY2
	MOV R0,A
SURE:
	RET
;************************键盘扫描*********************************   
KEYSCAN:
      LCALL KSTART                       ;调用检测按键子程序                                            
      JNZ PRE                            ;有键按下继续 
      LCALL DELAY2                       ;无键按下调用延时去抖动程序 
      AJMP  KEYSCAN                      ;返回继续检测有无按键按下 
PRE:  LCALL DELAY2  
      LCALL DELAY2                       ;有键按下继续延时去抖动 
      LCALL KSTART                       ;再一次调用检测按键程序 
      MOV R1,#04H
      JNZ K2                             ;确认有按下进行下一步 
      AJMP KEYSCAN                       ;无键按下返回继续检测 
K2:   MOV R2,#0feH                       ;将扫描值送入 R2暂存 
      MOV R4,#00H          
K3:   MOV P3,R2                          ;将R2的值送入P2口  
L6:   JB P3.4,L1                         ;P2.0等于1跳转到L1 
      MOV R3,#00H                        ;将第一行的行值00H送入ACC  
      AJMP LK                            ;跳转到键值处理程序 
L1:   JB P3.5,L2                         ;P2.1等于1跳转到L2 
      MOV R3,#01H                        ;将第二行的行值送入ACC 
      AJMP LK                            ;跳转到键值理程序进行键值处理 
L2:   JB P3.6,L3                         ;P2.2等于1跳转到L3 
      MOV R3,#02H                        ;将第三行的行值送入ACC 
      AJMP LK                            ;跳转到键值处理程序 
L3:   JB P3.7,NEXT                       ;P2.3等于1跳转到NEXT处 
      MOV R3,#03H
      AJMP LK                            ;将第四行的行值送入ACC                                                                                                          
NEXT:                                                                                                                        
    MOV A,R2                             ;将R2的值送入A                                               
    RL A                                 ;扫描未完成将A中的值右移一位进行下一列的扫描      
    MOV R2,A                             ;将ACC的值送入R2暂存
    MOV A,R4
    ADD A,#4H
    MOV R4,A                              
    DJNZ R1,K3                           ;跳转到K3继续 
    JMP K2                             
LK:
    MOV A,R3
    ADD A,R4
RET                                 
;************************端口初始化,便于判断是否有键按下**************
KSTART:  
     MOV P3,#0FH                        ;将P1口高四位置0低四位值1   
     MOV A,P3                           ;读P1口  
     XRL A,#0FH                         ;将A中的值与A中的值相异或 
     RET                                ;子程序返回 
;********* ***************40ms延时去抖动子程序***************
DELAY2:                                 ;8*FA*2=40ms 
    MOV R5,#08H  
L7: MOV R6,#0AH
L8: DJNZ R6,L8
    DJNZ R5,L7
RET
;*********************蜂鸣器程序************************************************
FENGMING:
      MOV  R5,#0B0H
FEE:      CLR SPK
      LCALL DELAY88
      LCALL DELAY88
      LCALL DELAY88
      LCALL DELAY88
      LCALL DELAY88
      LCALL DELAY88
      LCALL DELAY88
      LCALL DELAY88
      SETB SPK
      LCALL DELAY88
      DJNZ R5,FEE
     
RET
;**********************************************************************************      
DELAY3:                                 ;8*16*FA*2=640ms 
      MOV R5,#80H  
LLL7: MOV R6,#0FAH
LLL8: DJNZ R6,LLL8
      DJNZ R5,LLL7
RET
;***************************************************************************************
DELAY88:MOV R1,#20H
  LL88: MOV R2,#02H
      DJNZ R2,$
      DJNZ R1,LL88
      RET
END

⌨️ 快捷键说明

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