;***********************AT240X_SAMPLE**************************
;程序功能:本程序是利用文件AT240X.ASM中的子程序对EEPROM 240X进行多字节读写的操作示
例(同样适用于2416,24C02).
;说明:本程序在AT24C01A上调试通过.
;***********************符号定义******************************
常量定义
I2C_SDA EQU P1.0 数据线
I2C_SCL EQU P1.1 时钟线
变量定义
I2C_AD DATA 50H 存放器件的三位可编程地址或页地址(0-7)
I2C_SUBA DATA 51H 存放片内寻址字节.
I2C_NUMBYT DATA 52H 存放传送的字节数.
I2C_TDA DATA 53H 存放发送数据缓冲区首地址.
I2C_RDA DATA 54H 存放接收数据缓冲区首地址.
DELAYMS_NUM DATA 55H 存放延时的毫秒数
;************************************************************
ORG 00H
MOV I2C_AD,#00H 设器件的三位可编程地址
MOV I2C_SUBA ,#00H 设器件子地址
MOV I2C_NUMBYT,#02H 写2字节数据
MOV I2C_TDA,#30H 设发送缓冲区首址
***********写********************
待发送数据
MOV 30H,#0FFH
MOV 31H,#0FFH
LCALL I2C240X_WRNBYT 写入数据
JC $ 若未正常写入则停止
延时10ms
MOV DELAYMS_NUM,#0AH 置延时毫秒数
LCALL DELAYNMS
***********读********************
MOV I2C_NUMBYT,#02H 读2字节数据
MOV I2C_RDA,#40H 设接收缓冲区首址
LCALL I2C240X_RDNBYT 读出数据
JC $ 若未正常读出则停止
SJMP $
;************************************************************
包含文件
#include <240X.ASM>
#include
END
;***********************240X.asm**********************************
;程序功能:本程序包实现对EEPROM 240X的多字节读写操作.
;入口参数: I2C_AD 存放器件的三位可编程地址或页地址(0-7).
; I2C_SUBA存放片内寻址字节.
; I2C_NUMBYT存放要传送数据的字节数.
; I2C_TDA存放发送数据缓冲区首地址.
; I2C_RDA存放接收数据缓冲区首地址.
;出口参数:接收到的数据存放在接收数据缓冲区内.
; C存放接收到的应答位或非应答位,0表示应答位,1表示非应答位或总线不可用(数
据未正常写入).
;占用资源:A,PSW,R0,R1,R3.
;占用堆栈:2字节.
;子程序调用:I2C_START,I2C_STOP,I2C_TACK,I2C_TNACK,I2C_CACK,I2C_WRBYT,I2C_RDBYT.
;说明:1,本程序包适用的芯片有2401,2402,2404,2408,2416.
; 2,本程序适用于晶振频率为12MHZ,即单周期指令用时1us的模式,若晶振频率不
; 为12MHZ,则需相应地改变NOP指令的条数.
; 3,此程序调用了文件VI2C.ASM中的子程序,在此程序末尾已经用include指令将文件
VI2C.ASM包含进来了.
; 4,使用该程序前,用户需定义下列各符号.
;***********************符号定义示例****************************
; 常量定
义
; I2C_SDA EQU P1.0 数据线
; I2C_SCL EQU P1.1 时钟线
; 变量定义
; I2C_AD DATA 50H 存放器件的三位可编程地址或页地址(0-7)
; I2C_SUBA DATA 51H 存放片内寻址字节
; I2C_NUMBYT DATA 52H 存放传送的字节数
; I2C_TDA DATA 53H 存放发送数据缓冲区首地址
; I2C_RDA DATA 54H 存放接收数据缓冲区首地址
;***********************I2C240X_WRNBYT*************************
;程序功能:本程序实现对EEPROM 240X写入N字节数据.
;入口参数: I2C_AD 存放器件的三位可编程地址或页地址(0-7),I2C_TDA存放待发送数据缓
冲区首址,
; I2C_NUMBYT存放待发送数据个数,I2C_SUBA存放片内寻址字节.
;出口参数:C存放接收到的应答位或非应答位,0表示应答位,1表示非应答位或总线不可用(数
据未正常写入).
;占用资源:A,PSW,R0,R1,R3.
;占用堆栈:2字节.
;子程序调用:I2C_START,I2C_STOP,I2C_CACK,I2C_WRBYT.
I2C240X_WRNBYT:
MOV R3,I2C_NUMBYT R3存放待发送字节数
LCALL I2C_START 发开始信号
JC I2C_WABORT 若总线不可用则中止
MOV A,I2C_AD 将三位可编程地址或页地址送入累加器
RL A 左移一位对齐格式
ORL A,#0A0H 加上固定的高四位地址
CLR ACC.0 设定为写
LCALL I2C_WRBYT 发送写器件地址
LCALL I2C_CACK 检查应答位
JC I2C_WABORT 若检测到非应答位则中止
MOV A,I2C_SUBA 将片内寻址字节送入累加器
LCALL I2C_WRBYT 发送
LCALL I2C_CACK 检查应答位
JC I2C_WABORT 若检测到非应答位则中止
MOV R1,I2C_TDA 将待发送数据缓冲区首址送R1
I2C_WLOOP: MOV A,@R1 待发送数据送入累加器
LCALL I2C_WRBYT 发送N字节数据
LCALL I2C_CACK 检测应答位
JC I2C_WABORT 若检测到非应答位则中止
INC R1 发送数据缓冲区指针调整
DJNZ R3,I2C_WLOOP 是否发完?
CLR C 清错误标志位,正常写入
I2C_WABORT: LCALL I2C_STOP 发送停止位
RET
;***********************I2C240X_RDNBYT***********************
;程序功能:本程序实现从EEPROM240X中读出N字节数据.
;入口参数: I2C_AD 存放器件的三位可编程地址或页地址(0-7),I2C_RDA存放待接收数据缓
冲区首址,
; I2C_NUMBYT存放待接收数据个数,I2C_SUBA存放片内寻址字节.
;出口参数:接收到的数据存放在接收数据缓冲区中,C存放接收到的应答位或非应答位,0表示
应答位,
; 1表示非应答位或总线不可用(数据未正常读出)
;占用资源:A,PSW,R0,R1,R3.
;占用堆栈:2字节.
;子程序调用:I2C_START,I2C_STOP,I2C_TACK,I2C_TNACK,I2C_CACK,I2C_WRBYT,I2C_RDBYT.
I2C240X_RDNBYT:
MOV R3,I2C_NUMBYT R3存放待接收字节数
LCALL I2C_START 发开始信号
JC I2C_RABORT 若总线不可用则中止
MOV A,I2C_AD 将三位可编程地址或页地址送入累加器
RL A 左移一位对齐格式
ORL A,#0A0H 加上固定的高四位地址
CLR ACC.0 设定为写
LCALL I2C_WRBYT 发送写器件地址
LCALL I2C_CACK 检查应答位
JC I2C_RABORT 若检测到非应答位则中止
MOV A,I2C_SUBA 将片内寻址字节送入累加器
LCALL I2C_WRBYT 发送
LCALL I2C_CACK 检查应答位
JC I2C_RABORT 若检测到非应答位则中止
LCALL I2C_START 发开始信号
JC I2C_RABORT 若总线不可用则中止
MOV A,I2C_AD 将三位可编程地址或页地址送入累加器
RL A 左移一位对齐格式
ORL A,#0A0H 加上固定的高四位地址
SETB ACC.0 设定为读
LCALL I2C_WRBYT 发送读器件地址
LCALL I2C_CACK 检查应答位
JC I2C_RABORT 若检测到非应答位则中止
MOV R1,I2C_RDA 将待接收数据缓冲区首址送R1
I2C_RLOOP: LCALL I2C_RDBYT 接收1字节数据
MOV @R1,A 送入缓冲区
DJNZ R3,I2C_TTACK 是否接收完?
LCALL I2C_TNACK 发送非应答位
CLR C 清错误标志位,正常读出
I2C_RABORT: LCALL I2C_STOP 发送结束信号
RET
I2C_TTACK: LCALL I2C_TACK 发送应答位
INC R1 接收数据缓冲区指针调整
SJMP I2C_RLOOP
;************************************************************
#include
;2004.11.19 12MHZ
;*******************VI2C**************************************
;程序功能:单主系统主方式下虚拟I2C总线软件包(100KHZ).
;入口参数: 无.
;出口参数: C存放接收到的应答位或非应答位,0表示应答位,1表示非应答位或总线不可用.
;占用资源:A,PSW,R0.
;占用堆栈:0字节.
;子程序调用:无.
;说明:1,本程序适用于晶振频率为12MHZ,即单周期指令用时1us的模式,若晶振频率不
; 为12MHZ,则需相应地改变NOP指令的条数.
; 2,该软件包用于与其它操作I2C接口器件的子程序配合使用.
; 3,使用该程序前,用户需定义下列各符号.
;***********************符号定义示例****************************
; 常量定义
; I2C_SDA EQU P1.0 数据线
; I2C_SCL EQU P1.1 时钟线
;***********************I2C_START******************************
;程序功能:本程序实现在虚拟I2C总线上发送起始位。
;入口参数:无.
;出口参数:SDA,SCL返回为低电平,
; 错误标志位C,若错误标志位C为高电平则表示总线不可用.
;占用资源:C.
;占用堆栈:0字节.
;子程序调用:无.
;说明:当SCL为高电平时,SDA由高变低.
I2C_START: SETB I2C_SDA
SETB I2C_SCL
判断总线是否可用
JNB I2C_SDA,I2C_ER1 不为高则跳转
JNB I2C_SCL,I2C_ER1 不为高则跳转
NOP 保证启动建立时间大于4.7us (start
setup time)
CLR I2C_SDA 保证启动保持时间大于4.0us (start hold
time)
NOP
NOP
NOP
NOP
NOP
CLR I2C_SCL
CLR C 清错误标志位(总线可用)
SJMP I2C_OK1
I2C_ER1: SETB C 置错误标志位(总线不可用)
I2C_OK1: RET
;***********************I2C_STOP*******************************
;程序功能:本程序实现在虚拟I2C总线上发送结束位。
;入口参数:SCL在入口时应为低电平.
;出口参数:SDA,SCL都为高电平.
;占用资源:无.
;占用堆栈:0字节.
;子程序调用:无.
;说明:当SCL为高电平时,SDA由低变高。
I2C_STOP: CLR I2C_SDA
NOP 保证SCL低电平时间大于4.7us(clock pulse
width low)
NOP 以及数据建立时间大于200ns(data in
setup time)
SETB I2C_SCL
NOP 保证结束建立时间大于4.7us(stop setup
time)
NOP
NOP
NOP
NOP
SETB I2C_SDA
RET
;**********************I2C_TACK*******************************
;程序功能:本程序实现向虚拟I2C总线上发送应答位。
;入口参数:SCL在入口时应为低电平.
;出口参数:SDA,SCL都为低电平.
;占用资源:无.
;占用堆栈:0字节.
;子程序调用:无.
I2C_TACK: CLR I2C_SDA 发送应答位
NOP 保证SCL低电平时间大于4.7us(clock pulse
width low)
NOP 以及数据建立时间大于200ns(data in
setup time)
SETB I2C_SCL 产生一个时钟周期
NOP 保证SCL高电平时间大于4.0us(clock pulse
width high)
NOP
NOP
NOP
CLR I2C_SCL
RET
;**********************I2C_TNACK******************************
;程序功能:本程序实现向虚拟I2C总线上发送非应答位。
;入口参数:SCL在入口时应为低电平.
;出口参数:SDA为高电平,SCL为低电平.
;占用资源:无.
;占用堆栈:0字节.
;子程序调用:无.
I2C_TNACK: SETB I2C_SDA 发送非应答位
NOP 保证SCL低电平时间大于4.7us(clock pulse
width low)
NOP 以及数据建立时间大于200ns(data in
setup time)
SETB I2C_SCL 产生一个时钟周期
NOP 保证SCL高电平时间大于4.0us(clock pulse
width high)
NOP
NOP
NOP
CLR I2C_SCL
RET
;**********************I2C_CACK*******************************
;程序功能:本程序实现从虚拟I2C总线上检查应答位。
;入口参数:SCL在入口时应为低电平.
;出口参数:应答位存在C中,SCL为低电平.
;占用资源:C.
;占用堆栈:0字节.
;子程序调用:无.
I2C_CACK: SETB I2C_SDA 置I2C_SDA为输入方式
NOP 保证SCL低电平时间大于4.7us(clock
pulse width low)
NOP 以及保证tAA大于0.1us(clock low to
data out valid)
SETB I2C_SCL
NOP 保证SCL高电平时间大于4.0us(clock
pulse width high)
NOP
NOP
NOP
MOV C,I2C_SDA 接收应答位
CLR I2C_SCL 拉低时钟线
RET
;***********************I2C_WRBYT******************************
;程序功能:本程序实现向虚拟I2C总线上发送一字节数据.
;入口参数:A存待发送单字节数据,SCL在入口时应为低电平.
;出口参数:SCL为低电平.
;占用资源:A,PSW,R0.
;占用堆栈:0字节.
;子程序调用:无.
I2C_WRBYT: MOV R0,#08H 计8位
I2C_WLP: RLC A
MOV I2C_SDA,C
保证SCL低电平时间大于4.7us(clock
pulse width low)
NOP 以及数据建立时间大于200ns(data in
setup time)
SETB I2C_SCL 产生一个时钟周期
NOP 等待接收器件读取
NOP 保证SCL高电平时间大于4.0us(clock
pulse width high)
NOP
NOP
CLR I2C_SCL 拉低时钟线以便再次发送
DJNZ R0,I2C_WLP 是否发完8位
RET
;***********************I2C_RDBYT******************************
;程序功能:本程序实现从虚拟I2C总线上接收一字节数据.
;入口参数:SCL在入口时应为低电平.
;出口参数:A存放接收到的单字节数据,SCL为低电平.
;占用资源:A,PSW,R0.
;占用堆栈:0字节.
;子程序调用:无.
I2C_RDBYT: MOV R0,#08H 计数8位
SETB I2C_SDA 置1以便输入
I2C_RLP: NOP 保证SCL低电平时间大于4.7us(clock pulse
width low)
保证SCL低电平时间大于4.7us(clock pulse width low)
NOP 以及保证tAA大于0.1us(clock low to data
out valid)
以及数据建立时间大于200ns(data in setup time)
NOP
SETB I2C_SCL 拉高时钟线,以便输入
NOP 保证SCL高电平时间大于4.0us(clock
pulse width high)
NOP
MOV C,I2C_SDA
RLC A
CLR I2C_SCL 拉低时钟线,以便发送器发送
DJNZ R0,I2C_RLP
RET
;****************DELAYNMS***************************************
;程序功能:本程序实现延时Nms.
;入口参数:DELAYMS_NUM存放延时的毫秒数.
;出口参数:无.
;占用资源:R3
;占用堆栈:0字节.
;子程序调用:无.
;说明:1,本程序适用于晶振频率为12MHZ时,即单周期指令用时1us的模式,
; 时间计算公式为(249*4+1+1+2)*(DELAYMS_NUM)+2=1000*(DELAYMS_NUM)+2
; 2,未加上调用该子程序的指令执行的时间,如 LCALL DELAYNMS
; 3,使用该子程序前需定义符号DELAYMS_NUM,例DELAYMS_NUM DATA 55H
DELAYNMS: MOV R3,#0F9H 1us
LOOP500: NOP
NOP
DJNZ R3,LOOP500 2us
NOP
DJNZ DELAYMS_NUM,DELAYNMS 2us
RET 2us
END