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

📄 at24c02.asm

📁 AT24C02是基于IIC总线的串行数据存储器EEPROM
💻 ASM
字号:


;*****************************************************************************************
;程序说明
;*****************************************************************************************
;名称: MCS8051-III学习板演示程序(AT24C02测试)
;功能: 保存键盘值到AT24C02中并在数码管显示
;版本:2007-07-01

;*****************************************************************************************
;硬件说明
;*****************************************************************************************
;单片机: 	兼容MCS-51单片机/STC89C51
;晶振频率:  12MHz

;*****************************************************************************************
;说明:程序预定义	
;*****************************************************************************************
LED7A_CTRL	EQU		P1.7					;数码管第一位控制引脚(0为有效,1为无效)
LED7B_CTRL	EQU		P1.6					;数码管第二位控制引脚(0为有效,1为无效)
LED7C_CTRL	EQU		P1.5					;数码管第三位控制引脚(0为有效,1为无效)
LED7D_CTRL	EQU		P1.4					;数码管第四位控制引脚(0为有效,1为无效)

LED7_STATUS	EQU		P0						;数码管状态引脚(0为有效,1为无效)

LED7A_DATA  EQU		70H						;数码管第一位显示值(千位)
LED7B_DATA  EQU		71H						;数码管第二位显示值(百位)
LED7C_DATA  EQU		72H						;数码管第三位显示值(十位)
LED7D_DATA  EQU		73H						;数码管第四位显示值(个位)

LED7_NUM	EQU		74H						;数码管动态扫描值(值为从0到3)

KEY_STATUS	EQU		P2						;键盘状态引脚

IIC_SDA		EQU		P1.1					;IIC总线SDA引脚定义
IIC_SCL		EQU		P1.0					;IIC总线SCL引脚定义

;*****************************************************************************************
;说明:程序开始	
;*****************************************************************************************
			ORG		0000H					;程序首地址 PC=0000H
			JMP		START					;程序跳转到START PC=0030H   
	
			ORG		000BH					;T0中断程序入口
			JMP		LED7SCAN				;数码管动态扫描处理程序
	
			ORG		0030H					;程序开始
START:		
			CLR		IIC_SCL					;IIC时钟引脚至0
			CLR		P1.7
								
											;T0中断设定
			MOV		TMOD, #00000001B		;使用T0:GATE=0,C/T=0(定时),M1 M0=01(工作方式1)
			MOV		TH0, #0ECH				;定时时间5毫秒
			MOV		TL0, #078H
			SETB	ET0						;允许T0中断		
			SETB    TR0						;使T0工作

			MOV		A, #0					;AT24C02的地址值为0
			CALL	AT24C02_READBYTE		;AT24C02读操作,读出数据存放在A中
			
			SETB	EA						;总中断开启
	
			MOV		LED7A_DATA,	A			;数码管第一位初始值
			MOV		LED7B_DATA,	A			;数码管第二位初始值
			MOV		LED7C_DATA,	A			;数码管第三位初始值
			MOV		LED7D_DATA,	A			;数码管第四位初始值

			MOV		LED7_NUM, #0			;数码管动态扫描值至0,扫描第一位
			MOV		DPTR, #KEYTAB			;键盘编码表地址送DPTR	

											;检测键盘
			MOV		R5, #0EFH				;置扫描码初值
			MOV		R4, #04H				;置循环扫描次数为4次			
L1:		
			MOV		R3, #16					;置判断键盘码循环次数为15次
			MOV		KEY_STATUS,	R5			;将扫描码置键盘引脚
			MOV		A, R5					;改变扫描码
			RL		A
			MOV		R5, A
			MOV		A, KEY_STATUS
			ANL		A, #0FH					;判断是否有按键按下
			CJNE	A, #0FH, L2				;若有按键按下则转到L2
			JMP		L4						;若无则转到L4
L2:
			MOV		A, R3					;根据键盘码判断那个键按下
			DEC		A
			MOVC	A, @A+DPTR
			CJNE	A, KEY_STATUS,	L3						
			MOV		A, R3
			DEC		A

			MOV		LED7A_DATA,	A			;将显示值放到数码管显示值中
			MOV		LED7B_DATA,	A			
			MOV		LED7C_DATA,	A
			MOV		LED7D_DATA,	A

											;将键盘值保存在AT24CO2中
			MOV		R5, A
			MOV		A, #0
			CALL	AT24C02_WRITEBYTE


			JMP		L4	
L3:	
			DJNZ	R3, L2	
L4:
			DJNZ	R4, L1		 	
			MOV		R5, #0EFH				;置扫描码初值
			MOV		R4, #04H  				;置循环扫描次数为4次

			JMP	L1
								
;*****************************************************************************************		
;函数:LEDSCAN
;说明: 数码管动态扫描处理程序
;参数: 
;返回; 无
;*****************************************************************************************						
LED7SCAN:				
			PUSH	ACC						;ACC入栈
			PUSH	PSW						;PSW入栈
			PUSH	DPL						;DPL入栈
			PUSH	DPH						;DPH入栈
					
			MOV		DPTR,#LED7TAB			;数码管显示码表地址送DPTR
	
			MOV		A, LED7_NUM				;数码管动态扫描值送A
		
			CJNE	A, #0, LED7SCAN_1		;若数码管动态扫描值为0,则处理数码管的第一位,否则跳转到LED7SCAN_1
			SETB	LED7D_CTRL				;设置数码管第四位无效
			MOV		A, LED7A_DATA			;将千位值送A
			MOVC	A, @A+DPTR				;将显示码送A
			CLR		LED7A_CTRL				;设置数码管第一位有效
			JMP		LED7SCAN_4				;跳转到LED7SCAN_4
				
LED7SCAN_1:
			CJNE	A, #1, LED7SCAN_2		;若数码管动态扫描值为1,则处理数码管的第二位,否则跳转到LED7SCAN_2
			SETB	LED7A_CTRL				;设置数码管第一位无效
			MOV		A, LED7B_DATA			;将百位值送A
			MOVC	A, @A+DPTR				;将显示码送A
			CLR		LED7B_CTRL				;设置数码管第二位有效
			JMP		LED7SCAN_4				;跳转到LED7SCAN_4
				
LED7SCAN_2:
			CJNE	A, #2, LED7SCAN_3		;若数码管动态扫描值为2,则处理数码管的第三位,否则跳转到LED7SCAN_3
			SETB	LED7B_CTRL				;设置数码管第二位无效
			MOV		A, LED7C_DATA			;将十位值送A
			MOVC	A, @A+DPTR				;将显示码送A
			CLR		LED7C_CTRL				;设置数码管第三位有效
			JMP		LED7SCAN_4				;跳转到LED7SCAN_4
				
LED7SCAN_3:
			SETB	LED7C_CTRL				;设置数码管第三位无效
			MOV		A, LED7D_DATA			;将个位值送A
			MOVC	A, @A+DPTR				;将显示码送A
			CLR		LED7D_CTRL				;设置数码管第四位有效

			MOV		LED7_NUM, #0			;数码管动态扫描值置0
			JMP		LED7SCAN_5				;跳转到LED7SCAN_5

LED7SCAN_4:
			INC		LED7_NUM				;数码管动态扫描值加1
LED7SCAN_5:	
			MOV		LED7_STATUS, A			;显示码送数码管状态引脚
			
			MOV		TH0, #0ECH				;重新设置T0定时值
			MOV		TL0, #078H
			
			POP		DPH						;DPH出栈
			POP		DPL						;DPL出栈
			POP		PSW						;PSW出栈
			POP		ACC						;ACC出栈

			RETI							;中断返回


;*****************************************************************************************		
;IIC总线处理函数
;*****************************************************************************************						
IIC_START:									;IIC起始函数
			SETB	IIC_SDA
			SETB	IIC_SCL
			NOP
			NOP
			NOP
			NOP
			CLR		IIC_SDA
			NOP
			NOP
			NOP
			NOP
			CLR		IIC_SCL
			RET	
		
IIC_STOP:									;IIC结束函数
			CLR		IIC_SDA
			SETB	IIC_SCL
			NOP
			NOP
			NOP
			NOP
			SETB	IIC_SDA
			NOP
			NOP
			NOP
			NOP
			CLR		IIC_SCL
			RET
		
IIC_ACK:									;IIC应答函数
			CLR		IIC_SDA
			SETB	IIC_SCL
			NOP
			NOP
			NOP
			NOP
			SETB	IIC_SDA
			CLR		IIC_SCL
			RET

IIC_NACK:									;IIC反应答函数
			SETB	IIC_SDA
			SETB	IIC_SCL
			NOP
			NOP
			NOP
			NOP
			CLR		IIC_SDA
			CLR		IIC_SCL
			RET		
			 								
IIC_WBYTE:									;IIC写字节函数	
			MOV		R7, #8
IIC_WBYTE_1:
			RLC		A
			JC		IIC_WBYTE_2
			CLR		IIC_SDA
			SETB	IIC_SCL
			NOP
			NOP
			NOP
			NOP
			CLR		IIC_SCL
			DJNZ	R7, IIC_WBYTE_1	
			RET
IIC_WBYTE_2:	
			SETB	IIC_SDA
			SETB	IIC_SCL
			NOP
			NOP
			NOP
			NOP
			CLR		IIC_SCL
			CLR		IIC_SDA
			DJNZ	R7, IIC_WBYTE_1
			RET
		
IIC_RBYTE:									;IIC读字节函数	
			MOV		R7, #8
IIC_RBYTE_1:
			SETB	IIC_SDA
			SETB	IIC_SCL
			MOV		C, IIC_SDA
			MOV		A, R6
			RLC		A
			MOV		R6, A
			CLR		IIC_SCL	
			DJNZ	R7, IIC_RBYTE_1
			RET
		
;*****************************************************************************************		
;名称:AT24C02_WRITEBYTE:
;说明:AT24C02写字节操作
;参数: A存放写入地址,R5存放写入数据
;返回: 无
;*****************************************************************************************						
AT24C02_WRITEBYTE:
			PUSH	ACC
			CALL	IIC_START
			MOV		A, #10100000B
			CALL	IIC_WBYTE	
			CALL	IIC_ACK
			POP		ACC
			CALL	IIC_WBYTE
			CALL	IIC_ACK
			MOV		A, R5
			CALL	IIC_WBYTE
			CALL	IIC_ACK
			CALL	IIC_STOP
			RET

;*****************************************************************************************		
;名称:AT24C02_READBYTE
;说明:AT24C02读字节操作
;参数: A存放读出地址
;返回: A存放读出数据
;*****************************************************************************************								
AT24C02_READBYTE:
			PUSH	ACC
			CALL	IIC_START
			MOV		A, #10100000B
			CALL	IIC_WBYTE	
			CALL	IIC_ACK
			POP		ACC
			CALL	IIC_WBYTE
			CALL	IIC_ACK
			CALL	IIC_START
			MOV		A, #10100001B
			CALL	IIC_WBYTE
			CALL	IIC_ACK
			CALL	IIC_RBYTE
			CALL	IIC_NACK
			CALL	IIC_STOP
			RET	
			

;*****************************************************************************************
;说明:七段数码管十六进制显示码表		
;*****************************************************************************************
LED7TAB:		
			DB		0C0H, 0F9H, 0A4H, 0B0H, 099H, 092H, 082H, 0F8H, 080H, 090H	;从'0'到'9'
			DB		088H, 083H, 0C6H, 0A1H, 086H, 08EH, 0FFH			     	;从'A'到'F'	
	
;*****************************************************************************************
;说明:键盘十六进制编码表		
;*****************************************************************************************			
KEYTAB:				
			DB		0DEH, 0E7H, 0D7H, 0B7H, 0EBH, 0DBH, 0BBH, 0EDH, 0DDH, 0BDH	;从'0'到'9'
			DB		077H, 07BH, 07DH, 07EH,	0BEH, 0EEH							;从'A'到'F'

								
	
;*****************************************************************************************		
;说明:程序结束	
;*****************************************************************************************		
			END								;程序结束

⌨️ 快捷键说明

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