📄 ex4-3.asm
字号:
$INCLUDE (STC12C5A.INC) ;包含STC12C5A60S2单片机寄存器定义文件
;定义ISP/IAP命令
ISP_IAP_BYTE_READ EQU 1H ;字节读
ISP_IAP_BYTE_PROGRAM EQU 2H ;字节编程
ISP_IAP_SECTOR_ERASE EQU 3H ;扇区擦除
;定义Flash操作等待时间及允许IAP/ISP/EEPROM操作的常数(设置IAP_CONTR)
ENABLE_IAP EQU 82H ;系统工作时钟<20MHz 时
DEBUG_DATA EQU 5AH ;EEPROM单元的测试值,如正确应等于该值
START_ADDRESS EQU 0000H ;EEPROM测试起始地址
ORG 0000H
LJMP MAIN
ORG 0100H
MAIN: MOV SP, #70H ;堆栈指针指向 70H单元
MOV P1,#0F0H ;演示程序开始工作,P1.0/P1.1/P1.2/P1.3控制的灯亮
LCALL Delay ;延时
MOV P1,#0FH ;演示程序开始工作,P1.7/P1.6/P1.5/P1.4控制的灯亮
LCALL Delay ;延时
;读出EEPROM测试起始地址单元的内容
MAIN1: MOV DPTR, #START_ADDRESS ;将EEPROM测试起始地址送DPTR数据指针
LCALL Byte_Read
MOV 40H, A ;将EEPROM 的值送40H 单元保存
CJNE A, #DEBUG_DATA, NOT_EQU_DEBUG_DATA ;如果数据比较不正确,就跳转
;数据是对的,亮P1.7控制的灯,然后在P1口上将EEPROM的数据显示出来
MOV P1,#01111111B ;如(START_ADDRESS)的值等于#DEBUG_DATA,亮P1.7
LCALL Delay ;延时
MOV A, 40H ;将保存在40H单元中EEPROM 的值从40H单元送累加器A
CPL A ;取反的目的是相应的灯亮代表 1,不亮代表0
MOV P1,A ;数据是对的,送P1显示
SJMP $ ;数据正确,送P1显示后,CPU在此无限循环执行此句
NOT_EQU_DEBUG_DATA:
;EEPROM里的数据是错的,亮P1.3控制的灯,然后在P1 口上将错误的数据显示出来,
;再将该EEPROM所在的扇区整个擦除,将正确的数据写入后,亮P1.5控制的灯
MOV P1,#11110111B ;如(START_ADDRESS)的值不等于#DEBUG_DATA, 亮P1.3
LCALL Delay ;延时
MOV A, 40H ;将保存在40H单元中EEPROM 的值从40H单元送累加器A
CPL A ;取反的目的是相应的灯亮代表 1,不亮代表0
MOV P1, A ;数据不对,送 P1 显示
LCALL Delay ;延时
MOV DPTR,#START_ADDRESS ;将EEPROM测试起始地址送DPTR数据指针
LCALL Sector_Erase ;擦除整个扇区
MOV DPTR, #START_ADDRESS;将EEPROM测试起始地址送DPTR数据指针
MOV A, #DEBUG_DATA ;写入 EEPROM 的数据为 #DEBUG_DATA
LCALL Byte_Program ;字节编程
MOV P1, #11011111B ;将P1.3灯关闭,亮P1.5灯,代表数据已被修改
SJMP $ ;字节编程后,CPU在此无限循环执行此句
;--------- 读一字节 --------------------------------
;读一字节,调用前需打开IAP功能,入口:DPTR=字节地址,返回:A=读出字节
Byte_Read:
MOV IAP_CONTR,#ENABLE_IAP ;打开IAP功能, 设置Flash操作等待时间
MOV IAP_CMD,#ISP_IAP_BYTE_READ ;设置为IAP/ISP字节读模式命令
MOV IAP_ADDRH, DPH ;设置目标单元地址的高8位地址
MOV IAP_ADDRL, DPL ;设置目标单元地址的低8位地址
MOV IAP_TRIG, #5AH ;先送5AH,再送A5H到ISP/IAP触发寄存器
MOV IAP_TRIG, #0A5H ;送完A5H后,ISP/IAP命令立即被触发启动
NOP
MOV A, IAP_DATA ;读出的数据在IAP_DATA单元中,送入累加器A
LCALL IAP_Disable ;关闭IAP功能, 清相关的特殊功能寄存器
RET
;-------------- 字节编程 -------------------------------
;字节编程,调用前需打开IAP功能,入口:DPTR=字节地址, A=需写入的数据
Byte_Program:
MOV IAP_CONTR, #ENABLE_IAP ;打开IAP功能, 设置 Flash 操作等待时间
MOV IAP_CMD, #ISP_IAP_BYTE_PROGRAM ;设置为IAP/ISP字节编程模式命令
MOV IAP_ADDRH, DPH ;设置目标单元地址的高8位地址
MOV IAP_ADDRL, DPL ;设置目标单元地址的低8位地址
MOV IAP_DATA, A ;要编程的数据先送进ISP_DATA寄存器
MOV IAP_TRIG, #5AH ;先送5AH,再送A5H到ISP/IAP触发寄存器
MOV IAP_TRIG, #0A5H ;送完A5H后,ISP/IAP命令立即被触发启动
NOP
LCALL IAP_Disable ;关闭 IAP 功能, 清相关的特殊功能寄存器
RET
;--------------- 擦除扇区 ---------------------------------
;擦除扇区, 入口:DPTR =扇区地址
Sector_Erase:
MOV IAP_CONTR, #ENABLE_IAP ;打开IAP功能, 设置 Flash 操作等待时间
MOV IAP_CMD, #03H ;设置为IAP/ISP/EEPROM扇区擦除模式命令
MOV IAP_ADDRH, DPH ;设置目标单元地址的高8位地址
MOV IAP_ADDRL, DPL ;设置目标单元地址的低8位地址
MOV IAP_TRIG, #5AH ;先送5AH,再送A5H到ISP/IAP触发寄存器
MOV IAP_TRIG, #0A5H ;送完A5H 后,ISP/IAP命令立即被触发启动
NOP
LCALL IAP_Disable ;关闭IAP功能, 清相关的特殊功能寄存器
RET
;--------------- 关闭IAP功能---------------------------------
IAP_Disable: ;关闭IAP功能, 清相关的特殊功能寄存器
;一次连续的IAP操作完成之后建议关闭IAP功能,不需要每次都关
MOV IAP_CONTR, #0 ;关闭 IAP 功能
MOV IAP_CMD, #0 ;清命令寄存器,使命令寄存器无命令,此句可不用
MOV IAP_TRIG, #0 ;清命令触发寄存器,使命令触发寄存器无触发,此句可不用
MOV IAP_ADDRH, #0FFH ;送地址高字节单元为FFH,指向非EEPROM区
MOV IAP_ADDRL, #0FFH ;送地址低字节单元为FFH,防止误操作
RET
;--------------- 延时子程序---------------------------------
Delay:
CLR A
MOV R0, A
MOV R1, A
MOV R2, #20H
Delay_Loop:
DJNZ R0, Delay_Loop
DJNZ R1, Delay_Loop
DJNZ R2, Delay_Loop
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -