📄 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 + -