⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 实验十一(1).asm

📁 单片机只是别人的东西
💻 ASM
📖 第 1 页 / 共 2 页
字号:

ByteCnt DATA 28H          ;I2C总线收发字节计数器
SlvAdr  DATA 29H          ;从器件地址(控制信息)
SubAdr  DATA 2AH          ;对于32Kbit(4BK)存储容量及以上器件来说,待读写
                          ;单元地址为两字节,分别存放SubAdr、SubAdr+1单元中
RcvDat  DATA 30H          ;接收数据缓冲区(长度为8字节)

XmtDat  DATA 48H          ;发送数据缓冲区(长度为8字节)

FHbit   BIT  00H          ;发送及接收成功标志存放在00H位单元中。0表示成功;
                          ;1表示失败
NOACK   BIT  01H          ;读操作时主器件非应答标志位,1表示非应答,0表示应答。

SCL     BIT  P1.0         ;模拟I2C总线时钟信号, 输出
SDA     BIT  P1.1         ;模拟I2C总线数据/地址引脚,双向

ORG 0000H
LJMP MAIN                 ;跳转主程序入口地址

ORG 0100H
PROC MAIN                 ;主程序
MAIN:
     MOV SP, #0DFH        ;对于具有256字节内部RAM芯片来说,
                          ;将0E0H-0FFH,共计32字节作为堆栈区
     MOV DPTR, #8000H     ;关闭蜂鸣器
     MOV A, #0FFH
     MOVX @DPTR, A

     ;---复位后,将08H-0FF内部RAM单元清0。
     MOV R7, #248
     MOV R0, #08H
LOOPIC1:
     MOV @R0, #0
     INC R0
     DJNZ R7, LOOPIC1

     ;读24C01的7E、7FH单元
     MOV ByteCnt, #2	;传送2字节
     MOV SlvAdr, #0A0H	;24C01 EEPROM从器件地址
     MOV SubAdr, #7EH	;从7EH单元开始
     LCALL ReceData	;调用读EEPROM子程序,读出的2个字节存放在30-31单元中.
     ;判别读出的内容
     MOV R0, #RcvDat
     MOV A, @R0
     CJNE A, #5AH, NEXT1
     INC R0
     MOV A, @R0
     CJNE A, #0A5H, NEXT1
     ;等于5A、0A5H,说明已经初始化过,把日历时钟读到48-4EH单元中
     MOV ByteCnt, #7	;传送7字节
     MOV SlvAdr, #0A2H	;日历时钟器件地址为A2H
     MOV SubAdr, #02H	;从日历时钟的02H单元开始
     LCALL ReceData	;调用读EEPROM子程序,读出的7个字节存放在30-36单元中.
     SJMP NEXT2         
NEXT1:
     ;日历初始化
     MOV R0, #XmtDat    ;发送缓冲区首地址送R0
     MOV @R0, #00H      ;秒初值
     INC R0
     MOV @R0, #30H      ;分初值
     INC R0
     MOV @R0, #12H      ;时初值
     INC R0
     MOV @R0, #09H      ;日初值
     INC R0
     MOV @R0, #03H      ;星期初值
     INC R0
     MOV @R0, #11H      ;世纪及月初值
     INC R0
     MOV @R0, #04H      ;年初值
     MOV ByteCnt, #07H	;传送7字节
     MOV SlvAdr, #0A2H	;PCF8563日历时钟器件地址为A2H
     MOV SubAdr, #02H	;从日历时钟的02H单元开始
     LCALL SendData	;调用写EEPROM多字节写入过程,将发送缓冲区内的信息写入
                        ;PCF8563日历芯片内日历时间单元
     ;把初始化标志写入EEPROM的24C01芯片的7EH、7FH单元中。
     MOV R0, #XmtDat    ;发送缓冲区首地址送R0
     MOV @R0, #5AH
     INC R0
     MOV @R0, #0A5H
     MOV ByteCnt, #02H	;传送2字节
     MOV SlvAdr, #0A0H	;24C01 EEPROM从器件地址
     MOV SubAdr, #7EH	;从7EH单元开始
     LCALL SendData	;调用写EEPROM多字节写入过程,将发送缓冲区内的信息写入
                        ;EEPROM的7EH、7FH单元中。
NEXT2:     
     SJMP $             ;虚拟主程序

END

;------------------------串行EEPROM、日历时钟读写子程序------------
; 发送数据子程序
;名称:SendData
;描述:发送ByteCnt 个字节给从器件,如I2C总线串行EEPROM
;从器件地址在SlvAdr 中,存储单元地址在SubAdr 中
;所发送数据的字节数在ByteCnt中,发送的数据在XmtDat 缓冲区中
;成功发送数据,FHbit标志为0; 当FHbit为1时表示从器件无应答或损坏
;*************************************************************************************************

Proc SendData
SendData:
     PUSH PSW
     PUSH ACC
     CLR  RS0              ;使用2区(10)
     SETB RS1

     LCALL START           ;启动IC总线
     MOV A ,SlvAdr         ;将从器件地址放累加器A中
     LCALL SentByte        ;发送从器件总线地址
     JB FHBIT,SenReturn    ;从器件不应答返回
     ;--------对于存储器单元地址为16位的EEPROM存储器
;     MOV R0, #SubAdr+1
;     MOV A, @R0            ;存储单元地址高8位送累加器Acc,即先发送高8位地址A15~A8
;     LCALL SentByte        ;发存储单元地址
;     JB FHbit,SenReturn    ;从器件不应答返回

     ;--------对于存储单元地址为8位时,仅保留如下内容即可
     MOV R0, #SubAdr
     MOV A, @R0            ;存储单元地址低8位送累加器Acc,再发送低8位地址A7~A0
     LCALL SentByte        ;发存储单元地址
     JB FHbit,SenReturn    ;从器件不应答返回

     MOV R0,#XmtDat        ;取发送数据缓冲区首址
SentNext:
     MOV A,@R0
     LCALL SentByte ;发送一次数据
     JB FHbit,SenReturn ;出错返回
     INC R0 ;取下一个数据
     DJNZ ByteCnt,SentNext ;重复操作直到发送完最后一个数据
     LCALL STOP ;停止IC总线操作

;********查询方式检测内部写入周期是否已完成**********
LOOP:
     NOP                     ;两次操作之间的延迟
     NOP
     NOP
     NOP
     LCALL START ;启动IC总线
     MOV A ,SlvAdr ;将从器件地址放累加器A中
     LCALL SentByte ;发送从器件总线地址
     JB FHBIT,LOOP ;从器件不应答返回
     LCALL STOP ;停止IC总线操作
;***********************************************************
SenReturn:
     POP ACC
     POP PSW
     RET
END

;************************************************************************************************
; 接收数据子程序
;名称:ReceData
;描述:自从器件(如I2C总线串行EEPROM)读出ByteCnt个字节数据信息
;从器件地址在SlvAdr 中,待读出的存储单元地址在SubAdr 中
;所发送数据的字节数在ByteCnt中,接收的数据放在RevDat 缓冲区中
;成功接收数据,FHbit标志为0; 当FHbit为1时表示从器件无应答或损坏
;*************************************************************************************************
PROC ReceData
ReceData:
     PUSH PSW
     PUSH ACC
     CLR  RS0           ;使用2区(10)
     SETB RS1

     LCALL START        ;启动IC总线
     MOV A ,SlvAdr      ;将从器件地址放累加器A中
     LCALL SentByte     ;发送从器件总线地址
     JB FHBIT,RevReturn ;从器件不应答返回
     ;-----------对于存储器单元地址为16位的EEPROM存储器
;     MOV R0, #SubAdr+1
;     MOV A, @R0         ;存储单元地址高8位送累加器Acc,即先发送高8位地址A15~A8
;     LCALL SentByte     ;发存储单元地址

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -