赞助论坛
  • 5024阅读
  • 0回复

学习单片机之---单片机与AT24C0X的的汇编源程序 [复制链接]

楼层直达
jswr  
发帖
339
精华
1
金币
264
威望
8
贡献
7
好评
15
注册
2008-06-30
楼主    jswr 发表于: 2008-08-20 17:28:38 
单片机与AT24C0X的的汇编源程序


;***********************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