一、间接寻址
include HT66F0185.inc
ds .section 'data'
cs .section at 000h 'code'
;间接寻址
MOV A,80h ;将欲清除的存储器起始地址
MOV MP0,A ;存入MP0(01h)中
MOV A,16 ;设定A=16
LOOP: CLR IAR0 ;清除MP0所指定的存储器地址
INC MP0 ;MP0加1;指向下一个地址
SDZ ACC ;ACC=ACC-1
JMP LOOP ;若ACC≠0,继续下一个地址
JMP $ ;死循环 防止堆栈溢出 程序跑飞
官方资料:IAR0(00H):间接寻址寄存器0(Indirect Addressing Register 0),它是8位间接寻址寄存器,结合MP0寄存器完成间接存取数据存储器(RAM)的工作。在HT66Fx0单片机内部实际上没有IAR0寄存器,但若指令以IAR0作为操作数时,单片机的动作是将MP0寄存器所存放的内容当做数据存储器(指的是GPR或SFR)的地址,然后针对该地址内的数据执行指定的运算。
MP0(01H):数据存储器指针0(Data Memory Pointer 0)。
简单来讲:如图1-1所示,MP0存储的内容为地址(蓝色框),可以理解为门牌号;IAR0存储的内容为此地址存储的数据(红色框),可以理解为门牌号对应的房子里的东西,存好门牌号后对IAR0操作就可以对门牌号对应的东西进行操作。
简化程序:MOV A,80H
MOV MP0,A
INC IAR0
程序举例说明:如图1-1所示,以红色圆圈为例,此时,它的地址为80h,数据内容为00,若要对它进行间接寻址操作,只需将80H存入MP0,即地址,再对IAR0进行操作就可以对80H这个地址存储的内容进行操作了,比如INC IAR0,即内容加1,红色圆圈就会变成01。上诉程序中将80H地址存入MP0,之后CLR IAR0即对80H地址中的内容进行清零操作,INC MP0为MP0中内容加一,即为地址加1,就是下图中红色圆圈右移一格的位置,循环16次,对80H~96H中的内容进行清零操作,结果为下图中红色框中的红色00。
图1-1 RAM数据存储器
二、查表
include HT66F0185.inc
ds .section 'data'
;查表
DATA1_L0 EQU [83H] ;设定低8位数据存储地址
DATA1_HI EQU [84H] ;设定高8位数据存储地址
DATA2_L0 EQU [95H] ;设定低8位数据存储地址
DATA2_HI EQU [96H] ;设定高8位数据存储地址
cs .section at 000h 'code'
;查表
MOV A,HIGH TABLE ;取表地址高8位
MOV TBHP,A ;设定TBHP地址
MOV A,LOW TABLE ;取表地址低8位
MOV TBLP,A ;设定TBLP地址
TABRD DATA1_L0 ;读取数据 低8位
MOV A,TBLH
MOV DATA1_HI,A ;高位数据存至DATA1_HI
INC TBLP ;指向下一地址
TABRD DATA2_L0 ;读取数据 低8位
MOV A,TBLH
MOV DATA2_HI,A ;高位数据存至DATA2_HI
JMP $
ORG 0700H
TABLE: DC 1234H,3234H,5566H ;数据建表区
TBLP(07h):表格指针低字节(Table Pointer Low Byte)
TBLH(08h):表格数据读取高字节(Table High Bits)
TBHP(09h):表格指针高字节(Table Pointer High Byte)
程序解读:DATA1_L0 EQU [83H] ;设定低8位数据存储地址 (结果如图2-1)
DATA1_HI EQU [84H] ;设定高8位数据存储地址
DATA2_L0 EQU [95H] ;设定低8位数据存储地址
DATA2_HI EQU [96H] ;设定高8位数据存储地址
EQU 后设定地址可以改为想要存取表格数据的地址
图2-1
若改为设定变量的形式 DATA1_L0 DB ? (如图2-2)
DATA1_HI DB ?
DATA2_L0 DB ?
DATA2_HI DB ?
则一般来说 默认从[80h]地址开始存。HT66FX0系列特殊寄存器地址为00h~7Fh。
图2-2
建表注意一般写在程序跑不到的地方,如程序末端,若写在开头,有可能表内数据会被程序误认为是寄存器地址而出错。
查表流程:通过HIGH LOW 伪指令将表格地址取出或者直接写表格地址,分别存入TBHP、TBLP中,即可开始读取数据,TABRD读取的是低8位,高8位存在TBLH中,用寄存器或变量存起来即可读取到表格数据了。
注意:TBLH是只读寄存器,无法用“TABRD[m]”以外的指令更改其值,因此,最后避免在主程序和中断服务子程序中同时使用查表指令,若无法避免,就先把TBLH的值存好。
三、EEPROM
include HT66F0185.inc
ds .section 'data'
;EEPROM写
EEPROM_ADRES EQU 00H
EEPROM_DATA DB ?
W_FLAG DB ?
;EEPROM读
R_FLAG DB ?
READ_ADRES DB ?
cs .section at 000h 'code'
;EEPROM
;写
MOV A,4
MOV W_FLAG,A
;写入EEPROM中的地址
MOV A,EEPROM_ADRES
MOV EEA,A
;查表
MOV A,HIGH TAB
MOV TBHP,A
MOV A,LOW TAB
MOV TBLP,A
WRITE: TABRD EEPROM_DATA
;写入EEPROM中的数据
MOV A,EEPROM_DATA
MOV EED,A
MOV A,40H
MOV MP1,A
MOV A,01H
MOV BP,A
CLR EMI
SET IAR1.3
SET IAR1.2
SET EMI
;轮询法
BACK:
SZ IAR1.2
JMP BACK
CLR IAR1
CLR BP
INC TBLP
INC EEA
SDZ W_FLAG
JMP WRITE
;读
;存到RAM里的地址
MOV A,92H
MOV READ_ADRES,A
MOV A,4
MOV R_FLAG,A
;读EEPROM数据的地址
MOV A,EEPROM_ADRES
MOV EEA,A
READ: MOV A,040H
MOV MP1,A
MOV A,01H
MOV BP,A
SET IAR1.1
SET IAR1.0
BACK1:
SZ IAR1.0
JMP BACK1
CLR IAR1
CLR BP
;由于要存到RAM1里,设置BP为01H,即为BANK1,RAM1
MOV A,01H
MOV BP,A
MOV A,READ_ADRES
MOV MP1,A
MOV A,EED
MOV IAR1,A
INC EEA
INC READ_ADRES
SDZ R_FLAG
JMP READ
JMP $
TAB: DC 28H,29H,42H,55H
EEA:地址寄存器 ——要写\读的地址
EED:数据寄存器 ——要写\读的数据
EEC:控制寄存器 ——控制写\读开始
官方资料:该系列单片机的EEPROM 数据存储器容量最大可达128×8 位。由于映射方式与程序存储器和数据存储器不同,因此不能像其它类型的存储器一样寻址。使用Bank 0 中的一个地址寄存器EEA和一个数据寄存器EED以及Bank 1 中的一个控制寄存器EEC,可以实现对EEPROM 的单字节读写操作。有三个寄存器控制内部EEPROM 数据存储器总的操作。地址寄存器EEA、数据寄存器EED 及控制寄存器EEC。EEA 和EED 位于Bank 0 中,它们能像其它特殊功能寄存器一样直接被访问。EEC 位于Bank 1 中,不能被直接访问,仅能通过MP1 和IAR1 进行间接读取或写入。由于EEC 控制寄存器位于Bank 1中的“40H”,在EEC寄存器上的任何操作被执行前,MP1 必须先设为“40H”,BP 被设为“01H”。
程序解读:
写数据:EEPROM_ADRES为写入到EEPROM中的地址存到EEA,通过查表读取4个数据,依次(写完一个再写一个)写入EEPROM中存入EED,MP1 必须先设为“40H”,BP 被设为“01H”才能对EEC操作,先关闭总中断,SET IAR1.3 /SET IAR1.2为使能WREN:数据EEPROM 写使能位 和 使能WR:EEPROM 写控制位 ,注意:这2位置高使能时,顺序不能错,且调试时要一次性跑过这俩句,不能单步调试这俩句。之后开总中断,通过轮询IAR1.2即WR口是否为0判断是否写入成功,写成功后,清一下寄存器,地址加1,判断下标志位就进行下一次写数据。如图3-1,写入成功点击上传即可看到写入的数据。
图3-1
读数据:READ_ADRES为读到RAM1里的地址,EEPROM_ADRES为要读取的EEPROM中的数据的地址,MP1 必须先设为“40H”,BP 被设为“01H”才能对EEC操作,先关闭总中断,SET IAR1.1 /SET IAR1.0为使能RDEN:数据EEPROM 读使能位和 使能RD:EEPROM 读控制位 ,注意:这2位置高使能时,顺序不能错,且调试时要一次性跑过这俩句,不能单步调试这俩句。之后开总中断,通过轮询IAR1.0即WR口是否为0判断是否读取成功,读成功后,清一下寄存器,由于要存入RAM1(BANK1)中,需先设置BP为01H,之后通过间接寻址(BP为01H时,用MP1和IAR1寄存器)的方式将读取到的数据(读取的数据先置于EED中了)存入相应地址,地址加1,判断下标志位就进行下一次读数据。如图3-2,读取成功的数据存储到RAM1中。
图3-2