📄 lib.asm
字号:
Lib SEGMENT CODE
;I2C读写地址定义(I/O口)
AT24C02Read EQU 10100001B
AT24C02Write EQU 10100000B
SCL BIT P3.0
SDA BIT P3.1 ;I2C总线
I2CContr BIT P1.7 ;I2C器件开启(1开启 0关闭)
PUBLIC UNEX2,OpenI2c,CloseI2c,ReadI2CDate,WriteI2CDate,DealyLong,VOTE3
RSEG Lib
;*******************************************************
;I2C 器件读写模块
;*******************************************************
OpenI2c:
PUSH PSW
SETB RS0
SETB RS1
CLR I2CContr
LCALL DealyLong
POP PSW
RET
CloseI2c:
PUSH PSW
SETB RS0
SETB RS1
SETB I2CContr
LCALL DealyLong
POP PSW
RET
;****************************************************
;从I2C器件读出数据
;输入参数为 A:数据的地址
;输出参数为 A:数据的值
ReadI2CDate:
PUSH PSW
SETB RS0
SETB RS1
PUSH ACC
LCALL SendI2CStartBit
;发送起始位
MOV A,#AT24C02Write
LCALL SendI2CByte
;发送向AT24C02写数据命令
LCALL ReciveI2CAckBit
NOP
NOP
CJNE A,#00,ReadI2CDataEnd
;等待回应
POP ACC
LCALL SendI2CByte
;发送地址
LCALL ReciveI2CAckBit
NOP
NOP
CJNE A,#00,ReadI2CDataEnd
;等待回应
LCALL SendI2CStartBit
;发送起始位
MOV A,#AT24C02Read
LCALL SendI2CByte
;发送向8583读数据命令
LCALL ReciveI2CAckBit
NOP
NOP
CJNE A,#00,ReadI2CDataEnd
;等待回应
LCALL ReceiveI2CByte
;读取相应地址数据
PUSH ACC
LCALL SendI2CUnAckBit
;等待回应
LCALL SendI2CStopBit
;发送停止位
ReadI2CDataEnd:
LCALL Delay10us
POP ACC
POP PSW
RET
;-------------------------------------------------
;向I2C器件写入数据
;输入参数为 A数据的地址
; B数据的值
WriteI2CDate:
PUSH PSW
SETB RS0
SETB RS1
PUSH B
PUSH ACC
SETB SDA
SETB SCL
LCALL SendI2CStartBit
MOV A,#AT24C02Write
LCALL SendI2CByte
LCALL ReciveI2CAckBit
NOP
NOP
CJNE A,#00,WriteI2CDataEnd2
POP ACC
LCALL SendI2CByte
LCALL ReciveI2CAckBit
NOP
NOP
CJNE A,#00,WriteI2CDataEnd1
POP B
MOV A,B
LCALL SendI2CByte
LCALL ReciveI2CAckBit
NOP
NOP
CJNE A,#00,WriteI2CDataEnd
LCALL SendI2CStopBit
WriteI2CDataEnd:
LCALL Delay10us
POP PSW
RET
WriteI2CDataEnd1:
POP B
POP PSW
RET
WriteI2CDataEnd2:
POP ACC
POP B
POP PSW
RET
;****************************************************
;I2C 发送一个字节子程序
;输入参数: A (待发送字节)
SendI2CByte:
MOV B,A
MOV A,R0
PUSH ACC
MOV A,B
MOV R0,#8
CLR C
SendI2CByte0:
RLC A
NOP
NOP
JNC SendI2CByte1
LCALL SendI2CBit1
SJMP SendI2CByte2
SendI2CByte1:
LCALL SendI2CBit0
SendI2CByte2:
NOP
NOP
DJNZ R0,SendI2CByte0
POP ACC
MOV R0,A
RET
;--------------------------------------------------------
;I2C接收一个字节子程序
;输出参数: A(接收到的字节)
ReceiveI2CByte:
MOV A,R0
PUSH ACC
MOV R0,#8
MOV A,#0
ReceiveI2CByte1:
LCALL ReciveI2CBit
RLC A
NOP
NOP
DJNZ R0,ReceiveI2CByte1
MOV B,A
POP ACC
MOV R0,A
MOV A,B
RET
;--------------------------------------------------------
;I2C 发送一个起始位
SendI2CStartBit:
SETB SDA
LCALL Delay10us
SETB SCL
LCALL Delay10us
CLR SDA ;Start Bit
LCALL Delay10us
CLR SCL
RET
;--------------------------------------------------------
;I2C 发送一个位 0
SendI2CBit0:
CLR SDA
LCALL Delay10us
SETB SCL
LCALL Delay10us
CLR SCL
LCALL Delay10us
RET
;--------------------------------------------------------
;I2C 发送一个位 1
SendI2CBit1:
SETB SDA
LCALL Delay10us
SETB SCL
LCALL Delay10us
CLR SCL
LCALL Delay10us
RET
;--------------------------------------------------------
;I2C 接收一个位
;输出参数:PSW.C 接收位
ReciveI2CBit:
SETB SDA
LCALL Delay10us
SETB SCL
LCALL Delay10us
MOV C,SDA
CLR SCL
LCALL Delay10us
RET
;--------------------------------------------------------
;从I2C总线接收一个响应位子程序
;输出参数:ACC.7 为所接收到的认可位
ReciveI2CAckBit:
SETB SDA
SETB SCL
LCALL Delay10us
NOP
NOP
MOV A,#0FFH
MOV C,SDA
JC ReciveI2CAckBit1
MOV A,#00H
ReciveI2CAckBit1:
CLR SCL
RET
;--------------------------------------------------------
;向I2C总线发送一个不响应位
SendI2CUnAckBit:
SETB SDA
LCALL Delay10us
SETB SCL
LCALL Delay10us
CLR SCL
LCALL Delay10us
RET
;--------------------------------------------------------
;向I2C总线发送一个响应位
SendI2CAckBit:
CLR SDA
LCALL Delay10us
SETB SCL
LCALL Delay10us
CLR SCL
SETB SDA
LCALL Delay10us
RET
;--------------------------------------------------------
;向I2C总线发送一个停止位
SendI2CStopBit:
CLR SDA
LCALL Delay10us
SETB SCL
LCALL Delay10us
SETB SDA
LCALL Delay10us
RET
;--------------------------------------------------------
;延时10US
Delay10us:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
RET
;--------------------------------------------------------
DealyLong:
MOV A,R2
PUSH ACC
MOV A,R3
PUSH ACC
MOV R2,#02FH
DelayLong1:
MOV R3,#0FFH
DelayLong2:
NOP
NOP
NOP
DJNZ R3,DelayLong2
DJNZ R2,DelayLong1
POP ACC
MOV R3,A
POP ACC
MOV R2,A
RET
NOP
NOP
;*****************************************************
;
;传感器非线性标度变换子程序
;
;*****************************************************
;双字节补码减法子程序(NSUB)
;功能:(R2R3)-(R6R7) = (R4R5)
;入口:R2R3中存放被减数,R6R7中存放减数。
;出口:差存放在R4R5中,OV=1表示溢出。
;使用寄存器:A,R2-R7及标志CY
NSUB:
MOV A,R3
CLR C
SUBB A,R7
MOV R5,A
MOV A,R2
SUBB A,R6
MOV R4,A
RET
;------------------------------------------------------
;采用重复加法的双字节无符号数乘法子程序
;功能:(R2R3)*(R6R7)=(R4R5R6R7)
;入口:R2R3中存放被乘数,R6R7中存放乘数
;出口:积存放在R4R5R6R7中
;使用寄存器:A,R2-R7及标志CY
NMUL:
MOV R4,#0
MOV R5,#0
MOV R0,#16
CLR C
NMLP:
MOV A,R4
RRC A
MOV R4,A
MOV A,R5
RRC A
MOV R5,A
MOV A,R6
RRC A
MOV R6,A
MOV A,R7
RRC A
MOV R7,A
JNC NMLN
MOV A,R5
ADD A,R3
MOV R5,A
MOV A,R4
ADDC A,R2
MOV R4,A
NMLN:
NOP
NOP
DJNZ R0,NMLP
MOV A,R4
RRC A
MOV R4,A
MOV A,R5
RRC A
MOV R5,A
MOV A,R6
RRC A
MOV R6,A
MOV A,R7
RRC A
MOV R7,A
RET
;------------------------------------------------------
;双字节补码加法子程序(NADD)
;功能:(R2R3)+(R6R7) = (R4R5)
;入口:R2R3中存放被加数,R6R7中存放加数。
;出口:和存放在R4R5中,OV=1表示溢出。
;使用寄存器:A,R2-R7
NADD:
MOV A,R3
ADD A,R7
MOV R5,A
MOV A,R2
ADDC A,R6
MOV R4,A
RET
;------------------------------------------------------
;采用比较法的无符号双字节数除法子程序
;功能:(R2R3R4R5)/(R6R7)=(R4R5),余数在(R2R3)中,
;若(R2R3)>=(R6R7),则为溢出,置位F0
;入口:R2R3R4R5中存放被除数,R6R7中存放除数
;出口:商存放在R4R5中,余数存放在R2R3中
;使用寄存器:A,R1-R7及标志CY,F0
NDIV:
MOV A,R3
CLR C
SUBB A,R7
MOV A,R2
SUBB A,R6
NOP
NOP
JNC NDVE1
MOV B,#16
NDVL1:
CLR C
MOV A,R5
RLC A
MOV R5,A
MOV A,R4
RLC A
MOV R4,A
MOV A,R3
RLC A
MOV R3,A
XCH A,R2
RLC A
XCH A,R2
MOV F0,C
CLR C
SUBB A,R7
MOV R1,A
MOV A,R2
SUBB A,R6
NOP
NOP
JB F0,NDVM1
JC NDVD1
NDVM1:
MOV R2,A
MOV A,R1
MOV R3,A
INC R5
NDVD1:
NOP
NOP
DJNZ B,NDVL1
CLR F0
RET
NDVE1:
SETB F0
RET
NOP
NOP
;------------------------------------------------------
READP:
CLR A
MOVC A,@A+DPTR
INC DPTR
MOV R6,A
CLR A
MOVC A,@A+DPTR
INC DPTR
MOV R7,A
RET
;------------------------------------------------------
;非线性标度变换子程序
;功能:传感器的输出与被测量是非线性关系时的标度变换。
;入口:采样存在R2R3中,分段端点的采样值、实际值存放
; 在DPTR指向的程序区内,端点个数N在R1中
;出口:标度变换后的输出值的R4R5中,若A=0FF则表示测量值
; 不正常。
;使用寄存器:A,R0-R7,DPTR,CY
;说明:因传感器输出与被测量是非线性,本程序采用折线近似法
;把分段端点存放在程序存储器中,存放的次序是:X1,Y1...XN,YN。
;计算时按如下步骤进行:
;(1)根据采样值X在表中查找X(I),使得X(I-1)<=X<X(I)。
;(2)根据查得的X(I-1)和X(I)在表中找到对应的Y(I-1)及Y(I)。
;(3)按照下面的插值公式计算出与X对应的变换值Y:
; Y=Y(I-1)+(X-X(I-1))*(Y(I)-Y(I-1))/(X(I)-X(I-1))
UNEXE1:
MOV A,#0FFH
RET
UNEX2:
LCALL READP
LCALL NSUB
NOP
NOP
JC UNEXE1
INC DPTR
INC DPTR
UNEX21:
MOV A,R4
PUSH ACC
MOV A,R5
PUSH ACC
LCALL READP
LCALL NSUB
NOP
NOP
JC UNEX22
INC DPTR
INC DPTR
POP ACC
POP ACC
NOP
NOP
DJNZ R1,UNEX21
SJMP UNEXE
UNEX22:
LCALL READP
MOV A,R6
MOV R2,A
MOV A,R7
MOV R3,A
MOV A,DPL
CLR C
SUBB A,#06H
MOV DPL,A
NOP
NOP
JNC UNEX23
DEC DPH
UNEX23:
LCALL READP
LCALL NSUB
POP ACC
MOV R3,A
POP ACC
MOV R2,A
MOV A,R6
PUSH ACC
MOV A,R7
PUSH ACC
MOV A,R4
MOV R6,A
MOV A,R5
MOV R7,A
LCALL NMUL
MOV A,R4
PUSH ACC
MOV A,R5
PUSH ACC
MOV A,R6
PUSH ACC
MOV A,R7
PUSH ACC
LCALL READP
MOV A,R6
MOV R2,A
MOV A,R7
MOV R3,A
MOV A,DPL
CLR C
SUBB A,#06H
MOV DPL,A
NOP
NOP
JNC UNEX24
DEC DPH
UNEX24:
LCALL READP
LCALL NSUB
MOV A,R4
MOV R6,A
MOV A,R5
MOV R7,A
POP ACC
MOV R5,A
POP ACC
MOV R4,A
POP ACC
MOV R3,A
POP ACC
MOV R2,A
LCALL NDIV
MOV A,R4
MOV R2,A
MOV A,R5
MOV R3,A
POP ACC
MOV R7,A
POP ACC
MOV R6,A
LCALL NADD
MOV A,#00H
RET
UNEXE:
MOV A,#0FFH
RET
;*******************************************************
;三中取二表决
;信息及其副本放在R2,R3,R4中
;F0=1表决失败,F0=0表决成功,数据在A中。
VOTE3:
MOV A,R2
XRL A,R3
JZ VOTE32
MOV A,R2
XRL A,R4
JZ VOTE32
MOV A,R3
XRL A,R4
JZ VOTE31
SETB F0
RET
VOTE31:
MOV A,R3
MOV R2,A
VOTE32:
CLR F0
MOV A,R2
RET
NOP
NOP
;///////////////////////////////////////////////////////////////
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -