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

📄 at93c46.asm

📁 在AT93C46里面存储数字并读出显示
💻 ASM
字号:

;**************************************************************
;AT93C46是ATMEL公司生产的带SPI接口的EEPROM存储器.
;本程序是适用于HaiYunV1.0单片机实验板的读写AT93C46的程序,
;通过将数据0~F写入AT93C46的00H~0FH地址并一位一位地读出来显示
;在数码管上,详细地演示了SPI接口的操作.
;实验时要把AT93C46的电源选择跳线VCC_C46拨到ON
;MCU:AT89S52
;XTAL:12MHz
;作者:chhaich
;EMAIL:chhaich@163.com
;**************************************************************
;//define pin 定义引脚
			CS equ	P1.4 		;定义片选端 				
			SK equ	P1.7  		;定义时钟线
			DI equ	P1.5		;定义数据输入线
			DO equ	P1.6  		;定义数据输出线
;//define OP code	定义操作码
			OP_EWEN_H	equ	00h	;// 00					write enable
			OP_EWEN_L	equ	60h	;// 11X XXXX				write enable
			OP_EWDS_H	equ	00h	;// 00					disable
			OP_EWDS_L	equ	00h	;// 00X XXXX				disable
			                  
			OP_WRITE_H	equ	40h	;// 01 A6-A0				write data
			OP_READ_H	equ	80h	;// 10 A6-A0				read data
			                  
			OP_ERASE_H	equ	0c0h	;// 11 A6-A0				erase a word
			                  
			OP_ERAL_H	equ	00h	;// 00					erase all
			OP_ERAL_L	equ	40h	;// 10X XXXX				erase all
			OP_WRAL_H	equ	00h	;// 00  					write all	
			OP_WRAL_L	equ	20h	;// 01X XXXX		 		write all		

;定义数据存储在单片机的地址
			SendData	DATA		30h		;要发送数据存储的地址
			GetData		DATA		31h		;接收到的数据存储的地址
			OpCodeH		DATA		32h		;操作码高位存储的地址
			OpCodeL		DATA		33h		;操作码低8位存储的地址
			Addr		DATA		34h		;数据要存储到AT93C46的地址


;*****************************************
;主程序
;*****************************************
		org 0000h
		ljmp main
		org 0030h
main:
		CLR CS		;初始化端口
		CLR SK
		SETB DI
		SETB DO
		LCALL ewen	;使能写入操作
		LCALL erase	;擦除全部内容
		
		MOV R0,#10H			;循环的次数赋初值
		MOV A,#00H
		MOV SendData,A		;存储的数据赋初值
		MOV Addr,A		;存储在AT93C46的地址赋初值
mainloop:
		LCALL write		;写入数据
		INC SendData	;数据加一
		INC Addr		;地址加一
		DJNZ R0,mainloop	;示写完继续

		LCALL ewds		;使能写保护

ReadDataAndDisplay:		;读出数据并显示
		MOV R0,#10H
		MOV A,#00H
		MOV Addr,A
readloop:
		LCALL read		;读出
		LCALL display	;显示
		mov r4,#100					;延时一秒左右
loopdisp:
		lcall delay
		djnz r4,loopdisp			
		inc addr					;读出数据的地址加一
		djnz r0,readloop			;没有读完指定的数据就跳转回去继续读下一个地址的数据并显示
		ljmp ReadDataAndDisplay		;跳转回到ReadDataAndDisplay循环


;*****************************************
;写允许子程序
;*****************************************
ewen:
		MOV A,#OP_EWEN_H			;将操作码高位写入相应存储单元
		MOV OpCodeH,A
		MOV A,#OP_EWEN_L			;将操作码低位写入相应存储单元
		MOV OpCodeL,A			
		LCALL inop					;调用写入操作码子程序
		CLR CS						;关片选
		RET							;子程序返回
		
;*****************************************
;写保护子程序,调用后不可以再写入数据
;*****************************************
ewds:
		MOV A,#OP_EWDS_H			;将操作码高位写入相应存储单元     
		MOV OpCodeH,A                                                 
		MOV A,#OP_EWDS_L            ;将操作码低位写入相应存储单元     
		MOV OpCodeL,A                                                 
		LCALL inop                  ;调用写入操作码子程序             
		CLR CS                      ;关片选                           
		RET                         ;子程序返回                       
;*****************************************
;擦除所有子程序,调用后所有数据都被擦除
;在调用写保护子程序后再调用本程序无效
;*****************************************
erase:	
		MOV A,#OP_ERAL_H			;将操作码高位写入相应存储单元     
		MOV OpCodeH,A                                                 
		MOV A,#OP_ERAL_L            ;将操作码低位写入相应存储单元     
		MOV OpCodeL,A                                                 
		LCALL inop                  ;调用写入操作码子程序             
		LCALL delay                                      
		LCALL delay                                      
		LCALL delay
		CLR CS                      ;关片选      
		RET                         ;子程序返回  
;*****************************************
;写入一个数据到指定的地址
;*****************************************
write:
		MOV A,#OP_WRITE_H			;将操作码高位写入相应存储单元
		MOV OpCodeH,A
		MOV A,addr					;将写入数据的地址写入相应存储单元
		MOV OpCodeL,A
		LCALL inop					;调用写入操作码子程序
		LCALL shin					;调用写入数据子程序
		CLR CS						;关片选
		LCALL delay					;延时一段时间等待写入
		RET							;子程序返回
;*****************************************
;读取addr指向的地址处的数据
;*****************************************
read:
		MOV A,#OP_READ_H			;将操作码高位写入相应存储单元
		MOV OpCodeH,A				
		MOV A,addr					;将读取数据的地址写入相应存储单元
		MOV OpCodeL,A
		LCALL inop					;调用写入操作码子程序
		LCALL shout					;调用读出数据子程序
		CLR CS						;关片选
		RET							;子程序返回
;*****************************************  
;移入操作码或者地址
;*****************************************
inop:
		clr SK		;发送开始位
		setb DI
		setb CS
		nop
		nop
		setb SK
		nop
		nop
		clr SK		;发送起始位完毕
		
		MOV A,OpCodeH	;移入操作码的最高位
		RLC A
		MOV DI,C
		SETB SK
		RLC A
		CLR SK
		
		MOV DI,C		;移入操作码的次高位
		SETB SK
		NOP
		NOP
		CLR SK
		
		MOV A,OpCodeL	;移入余下的操作码或地址 
		RLC A			
		MOV R5,#07H
LOOPIN:
		RLC A			;带进位左移,将最高位移入进位位
		MOV DI,C		;把进位位送到数据输入口
		SETB SK			;拉高时钟线
		NOP				;延时
		CLR SK			;拉低时钟线
		DJNZ R5,LOOPIN	
		SETB DI			;拉高数据输入口
		RET				;子程序返回
		
;*****************************************   
;移入数据
;*****************************************
shin:
		MOV R5,#08H		;8位数据
		MOV A,SendData	;存储的数据送到A
SHINLOOP:
		RLC A			;数据带进位左移
		MOV DI,C		;数据最高位送到数据输入口
		SETB SK			;产生移位脉冲
		NOP
		CLR SK
		DJNZ R5,SHINLOOP	
		SETB DI			;拉高数据输入口
		RET				;子程序返回
;*****************************************
;移出数据
;*****************************************
shout:
		MOV R5,#08H		;8位数据
SHOUTLOOP:
		SETB SK			;拉高时钟线
		NOP				;
		CLR SK			;拉低时钟线
		MOV C,DO		;读取数据到进位位
		RLC A			;带进位左移
		DJNZ R5,SHOUTLOOP	
		MOV GetData,A	;读取完毕就把数据移动到GetData存储单元
		RET				;子程序返回

;******************************************************
;延时程序,大约10ms
;******************************************************		
delay:
		mov r7,#40
loopdelay:
		mov r6,#100
		djnz r6,$
		djnz r7,loopdelay
		ret	

;******************************************************
;显示程序
;******************************************************
display:
		anl P1,#0f8h			;开显示并把显示的位定在第一位
		setb P1.3				
		mov dptr,#TABLE			;取段码地址
		mov a,GetData			;把读出的数据送到A
		movc a,@a+dptr			;查表查到段码
		mov P0,a				;显示段码送到P0口
		ret						;返回

				
TABLE:	
		DB 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h,88h,83h,0c6h,0a1h,86h,8eh
		;   0,   1,   2,   3,  4,  5,  6,  7,  8,  9,	A,	b,	 C,	  d,  E,	F
		
		
		end	

⌨️ 快捷键说明

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