以下是应用三星4位单片机的源程序完全版。可直接使用。
;************************************************************************
;* IIC 读写 子程序 *
;* *
;* 1. 开始子程序: IIC_BEGN *
;* 2. 结束子程序: IIC_STOP *
;* 3. 向外设传送数据子程序: IIC_WTX *
;* 4. 从外设接收数据子程序: IIC_RTX *
;* 5. 写命令子程序: IIC_WCOM *
;* 6. 读命令子程序: IIC_RCOM *
;* 7. 写数据到器件中的子程序: IIC_WR *
;* 8. 从器件中读数据的子程序: IIC_RD *
;* 9. 检测IIC器件内部定时写周期是否结束 IC_TEST *
;* *
;************************************************************************
; 1. 开始子程序: IIC_BEGN. 发开始命令,即在SCL="1"时,SDA由"1"变"0"
IIC_BEGN: LD EA,#0FH ; 设定SCL,SDA对应的端口为输出态
REF LD_PMG1_EA ; P6.3~P6.0为输入, P3.3~P3.0为输出
REF BITR_SCL ; 清SCL="0",为SDA上的数据改变做准备
BITS SDA ; 置SDA="1"
;NOP ;
REF BITS_SCL ; 置SCL="1"
BITR SDA ; 清SDA="0",即在SCL="1"时,使SDA由"1"变"0"
;NOP ;
REF BITR_SCL ; 清SCL="0", 允许SDA总线上的数据改变
RET ;
; 2. 结束子程序: IIC_STOP. 发结束命令: 即在SCL="1"时,SDA由"0"变"1"
IIC_STOP: LD EA,#0FH ; 设定SCL,SDA对应的端口为输出态
REF LD_PMG1_EA ; P6.3~P6.0为输入, P3.3~P3.0为输出
REF BITR_SCL ; 清SCL="0",为SDA上的数据改变做准备
BITR SDA ; 清SDA="0"
;NOP ;
REF BITS_SCL ; 置SCL="1"
BITS SDA ; 置SDA="1",即在SCL="1"时,使SDA由"0"变"1"
;LD A,#0H ;
;XCH A,Y ;
;LD A,#0H ;
;XCH A,Z ; 将 YZ (存放读写命令)清"0", 防止对IIC进行误操作
RET ;
; 3. 向外设传送数据子程序: IIC_WTX (该数据存储在BSC0和BSC1中)
IIC_WTX: DI ;
LD EA,#0FH ; 设定SCL,SDA对应的端口为输出态
REF LD_PMG1_EA ; P6.3~P6.0为输入, P3.3~P3.0为输出
LD L,#7H ; 按每字节8位数据输出
IICWLP: REF BITR_SCL ; 清SCL="0",为SDA上的数据改变做准备
LDB C,BSC0.@L ; BSC0的高6位+L的高2位做地址,L的低2位做位数
LDB SDA,C ; 从bit3(BSC1)~bit0(BSC0)依次输送到数据总线上
;NOP ;
REF BITS_SCL ; 置SCL="1",产生上升沿,发送一位数据
DECS L ; 当L="0"时,运行该指令后产生借位,则跳过下一条JR指令
JR IICWLP ; 否则,未传送完8个字节,继续传送
REF BITR_SCL ;
BITS SDA ;
LD EA,#0EH ; 设定SCL对应的端口为输出态,SDA对应的端口为输入态
REF LD_PMG1_EA ; P6.3~P6.0和P3.0为输入, P3.3~P3.1为输出
LD EA,#4AH ; P6,P3,P1连接上拉电阻,为输入数据提供电源
LD PUMOD,EA ; 0100 1010
; 读取外设发出的确认信号
IICWACK: REF BITR_SCL ; 清SCL="0",器件使SDA="0"
REF BITS_SCL ; 置SCL="1",产生上升沿,让CPU在此期间读取SDA上的信号
BTSF SDA ; 检测器件在SDA上发回的"0"信号,是"0"则跳
JR IICWACK ; 继续检测
REF BITR_SCL ; 清SCL="0",为下一个8位数据在SDA上改变做准备
EI ;
RET ;
; 4. 从外设接收数据子程序: IIC_RTX (将数据存储在BSC0和BSC1中)
IIC_RTX: LD EA,#0EH ; 设定SCL对应的端口为输出态,SDA对应的端口为输入态
REF LD_PMG1_EA ; P6.3~P6.0和P3.0为输入, P3.3~P3.1为输出
LD EA,#4AH ; P6,P3,P1连接上拉电阻,为输入数据提供电源
LD PUMOD,EA ; 0100 1010
LD L,#7H ; 按每字节8位数据输入
IICRLP: REF BITR_SCL ; 清SCL="0",器件串出一位数据
REF BITS_SCL ; 置SCL="1",产生上升沿,让CPU在此期间读取SDA上的信号
LDB C,SDA ; 从数据总线上依次将数据存到bit3(BSC1)~bit0(BSC0)
REF LDB_BSC0AL_C; BSC0的高6位+L的高2位做地址,L的低2位做位数
DECS L ; 当L="0"时,运行该指令后产生借位,则跳过下一条JR指令
JR IICRLP ; 否则,未传送完8个字节,继续传送
REF BITR_SCL ;
RET ;
; 5. 写命令子程序: IIC_WCOM
;
IIC_WCOM: CALLS IIC_BEGN ; 调用IIC的开始命令,调用子程序时 EA 将被修改
PUSH HL ; 调用子程序时 EA 和 L 将被修改
LD EA,YZ ;
REF LD_BSC0_EA ; 将 写命令 送BSC1,BSC0
CALLS IIC_WTX ; 调用IIC的写数据到器件的子程序(包括CPU发出的应答部分)
POP EA ;
REF LD_BSC0_EA ; 将 地址 送BSC1,BSC0
JPS IIC_WTX ; 调用IIC的写数据到器件的子程序(包括CPU发出的应答部分)
; 6. 读命令子程序: IIC_RCOM
IIC_RCOM: CALLS IIC_BEGN ; 调用IIC的开始命令,调用子程序时 EA 将被修改
PUSH HL ; 调用子程序时 EA 和 L 将被修改
LD EA,YZ ;
REF LD_BSC0_EA ; 将 写命令 送BSC1,BSC0
CALLS IIC_WTX ; 调用IIC的写数据到器件的子程序(包括CPU发出的应答部分)
POP EA ;
REF LD_BSC0_EA ; 将 地址 送BSC1,BSC0
CALLS IIC_WTX ; 调用IIC的写数据到器件的子程序(包括CPU发出的应答部分)
CALLS IIC_BEGN ; 重新调用IIC的开始命令
LD EA,YZ ;
INCS A ; 读命令=写命令+1
REF LD_BSC0_EA ; 将 读命令 送BSC1,BSC0
JPS IIC_WTX ; 调用IIC的写数据到器件的子程序(包括CPU发出的应答部分)
; 7. 写数据到器件中的子程序: IIC_WR
IIC_WR: LD EA,#10H ;
REF SBS_EA_WX ;
JR IIC_WRNE ; NO ERRO
RET ; 写入的字节数> 16字节,为非法写入,被禁止!
IIC_WRNE: DECS WX ; 在WX从"00H"-> "FFH"时,才产生借位跳转,所以应先减去1
JR IIC_WRLP ;
RET ; WX=00H, 不往器件中写入数据
IIC_WRLP: REF LD_EA_AHL ; (HL)-> A,(HL+1)-> E
REF LD_BSC0_EA ;
PUSH HL ; 调用子程序时 EA 和 L 将被修改
CALLS IIC_WTX ; 调用IIC的写数据到器件的子程序(包括CPU发出的应答部分)
POP HL ;
INCS HL ;
INCS HL ; HL=HL+2
DECS WX ; 字节数减1, 如果产生借位,说明写完所有字节,跳转
JR IIC_WRLP ; 否则, 继续写入下一字节
JPS IIC_STOP ; 调用 结束子程序
; 8. 从器件中读数据的子程序: IIC_RD
;
IIC_RD: DECS WX ; 在WX从"00H"-> "FFH"时,才产生借位跳转,所以应先减去1
JR IIC_RDLP ;
RET ; WX=00H, 不从器件中读出数据
IIC_RDLP: PUSH HL ; 调用子程序时 EA 和 L 将被修改
CALLS IIC_RTX ; 读器件中的数据
POP HL ;
LD EA,BSC0 ;
REF LD_AHL_EA ; (HL) <-A,(HL+1) <-E
INCS HL ;
INCS HL ; HL=HL+2
DECS WX ; 字节数减1, 如借位,则读完所有字节,跳到"非应答确认"
JR IIC_RDAC ; 否则, 跳到发应答信号部分
; 已读完所有的数据,CPU发"高电平非应答确认"信号
LD EA,#0FH ; 设定SCL,SDA对应的端口为输出态
REF LD_PMG1_EA ; P6.3~P6.0为输入, P3.3~P3.0为输出
REF BITR_SCL ; 清SCL="0",为SDA上的数据改变做准备
BITS SDA ; 置SDA="1"
;NOP ;
REF BITS_SCL ; 置SCL="1",产生上升沿,发送一位非应答确认信号
JPS IIC_STOP ; 调用 结束子程序
; 未读完,CPU发低电平确认应答信号,以便读取下8位数据
IIC_RDAC: LD EA,#0FH ; 设定SCL,SDA对应的端口为输出态
REF LD_PMG1_EA ; P6.3~P6.0为输入, P3.3~P3.0为输出
REF BITR_SCL ; 清SCL="0",允许SDA总线上的数据改变
BITR SDA ; 清SDA="0",CPU发低电平确认信号,准备下8位数据的读取
;NOP ;
REF BITS_SCL ; 置SCL="1", 产生上升沿,发送一位确认数据
REF BITR_SCL ;
JPS IIC_RDLP ; 继续读出下一字节
; 9. 检测IIC器件内部定时写周期是否结束
;
IIC_TEST: LD EA,#A2404_0 ;
REF LD_BSC0_EA ; 将 写命令 送BSC1,BSC0
CALLS IIC_BEGN ; 调用IIC的开始命令,调用子程序时 EA 将被修改
; 调用完IIC_BEGIN后, P3.3~P3.0已被设为输出
LD L,#7H ; 按每字节8位数据输出
IIC_TSTL: REF BITR_SCL ; 清SCL="0",为SDA上的数据改变做准备
LDB C,BSC0.@L ; BSC0的高6位+L的高2位做地址,L的低2位做位数
LDB SDA,C ; 从bit3(BSC1)~bit0(BSC0)依次输送到数据总线上
;NOP ;
REF BITS_SCL ; 置SCL="1",产生上升沿,发送一位数据
DECS L ; 当L="0"时,运行该指令后产生借位,则跳过下一条JR指令
JR IIC_TSTL ; 否则,未传送完8个字节,继续传送
REF BITR_SCL ;
LD EA,#0EH ;
; 设定SCL对应的端口为输出态,SDA对应的端口为输入态
REF LD_PMG1_EA ; P6.3~P6.0和P3.0为输入, P3.3~P3.1为输出
LD EA,#4AH ; P6,P3,P1连接上拉电阻,为输入数据提供电源
LD PUMOD,EA ; 0100 1010
; 读取外设发出的确认信号
REF BITR_SCL ; 清SCL="0",器件使SDA="0"
REF BITS_SCL ; 置SCL="1",产生上升沿,让CPU在此期间读取SDA上的信号
BTSF SDA ; 检测器件在SDA上发回的"0"信号,是"0"则跳
JPS IIC_TEST ; 继续检测
REF BITR_SCL ; 清SCL="0",为下一个8位数据在SDA上改变做准备
JPS IIC_STOP ;
[/face]
发表时间:2003年5月2日18:12:30