📄 nickles_i2c.asm
字号:
;===============================================
; 程序设计: 俞长新
; 开始日期: 2002.03.01
; 版本: VER 1.00
; MCU =AT89C52 8KBYTES FLASH MEMORY /256 RAM
; XTAL = 12.0000MHz
; EEPROM= AT24C02
;===============================================
; I2C总线接口定义
;===============================================
IIADR EQU 00H ;I2C器件的物理地址
SCL BIT P1.6 ;I2C时钟线
SDA BIT P1.7 ;I2C数据线
WP BIT P1.2 ;I2C写保护检测
I2CNOP MACRO
NOP
NOP
NOP
ENDM
;===============================================
; I2C总线接口函数
;===============================================
;===== 写I2C器件1字节 入口为R7 ACC =====
BYTEWR:
PUSH ACC ;
LCALL START ;
MOV A,#0A0H+IIADR ;
LCALL SENDBYTE ;
MOV A,R7
LCALL SENDBYTE ;
POP ACC
LCALL SENDBYTE ;
LCALL STOP ;
SJMP DELAY ;
;===== 页(8个字节)写I2C器件 入口为R7,R1,R6=====
PAGEWR:
MOV A,R6
JNZ PAGEWRN
RET
PAGEWRN:
LCALL START ;
MOV A,#0A0H+IIADR ;
LCALL SENDBYTE ;
MOV A,R7
LCALL SENDBYTE ;
PAGEWR1:
MOV A,@R1 ;
LCALL SENDBYTE ;
INC R1 ;
DJNZ R6,PAGEWR1 ;
LCALL STOP ;
;===== 写I2C器件后延时10毫秒 =====
DELAY:
MOV A,R7
PUSH ACC
MOV A,R6
PUSH ACC
MOV R6,#20 ;10ms
DELAY1:
MOV R7,#250 ;250*2us*20
DELAY2:
DJNZ R7,DELAY2 ;
DJNZ R6,DELAY1 ;
POP ACC
MOV R6,A
POP ACC
MOV R7,A
RET
;===== 读I2C器件当前 入口为ACC =====
CUREAD:
LCALL START ;
MOV A,#0A1H+IIADR ;
LCALL SENDBYTE ;
LCALL READBYTE ;
LCALL SENDNOACK ;
LCALL STOP ;
RET
;===== 读I2C器件1字节 入口为R7 ACC =====
BYTEREAD:
LCALL START ;
MOV A,#0A0H+IIADR ;
LCALL SENDBYTE ;
MOV A,R7
LCALL SENDBYTE ;
LCALL START ;
MOV A,#0A1H+IIADR ;
LCALL SENDBYTE ;
LCALL READBYTE ;
LCALL SENDNOACK ;
LCALL STOP ;
RET
;===== 读I2C器件(R6)个字节 入口为R6,R7,出口为R1-> =====
RANDREAD:
LCALL START ;
MOV A,#0A0H+IIADR ;
LCALL SENDBYTE ;
MOV A,R7
LCALL SENDBYTE ;
LCALL START ;
MOV A,#0A1H+IIADR ;
LCALL SENDBYTE ;
SJMP RANDREAD2 ;
RANDREAD1:
LCALL SENDACK ;
RANDREAD2:
LCALL READBYTE ;
MOV @R1,A ;
INC R1 ;
DJNZ R6,RANDREAD1 ;
LCALL SENDNOACK ;
LCALL STOP ;
RET
;===== 字节数据传统送子程序 =====
SENDBYTE:
MOV B,#8 ;8位
SENDBY2:
RLC A
MOV SDA,C ;
I2CNOP
SETB SCL ;置时钟线为高通知被控器开始
I2CNOP
CLR SCL ;保证时钟高周期大于4uS
DJNZ B,SENDBY2 ;
SETB SDA
I2CNOP
SETB SCL
I2CNOP
SETB C
JB SDA,SENDBY6 ;ACK=1
CLR C
SENDBY6:
CLR SCL
RET
;===== 字节数据接收子程序 =====
READBYTE:
SETB SDA
MOV B,#8
READBY2:
CLR SCL
I2CNOP
SETB SCL
MOV C,SDA
RLC A
I2CNOP
DJNZ B,READBY2
RET
;===== 发送应答位子程序 =====
SENDACK:
CLR SCL
I2CNOP
CLR SDA
I2CNOP
SETB SCL
I2CNOP
CLR SCL
RET
;===== 发送非应答位子程序 =====
SENDNOACK:
CLR SCL
I2CNOP
SETB SDA
I2CNOP
SETB SCL
I2CNOP
CLR SCL
RET
;===== START 发送I2C 起始条件 =====
START:
SETB SDA ;发送起始条件的数据信号
I2CNOP
SETB SCL ;发送起始条件的时钟信号
I2CNOP
CLR SDA ;发送起始信号
I2CNOP
CLR SCL ;钳住I2C 发送或接收数据
RET
;===== STOP 发送I2C 总线停止条件 =====
STOP:
CLR SDA
I2CNOP
SETB SCL
I2CNOP
SETB SDA
RET
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -