📄 lm92saa1064.#1
字号:
;参考程序B : //LM92SAA1064.ASM
;WLM92SAA1064.ASM程序功能:读/写LM92并将温度值显示在SAA1064驱动的数码管上.
;要显示的数据在70H--7BH中.
$include (C8051F020.inc)
CHIP_A EQU 090H ; LM92芯片的写地址
CHIP_B EQU 070H ; SAA1064芯片的写地址
;SMBus状态:
SMB_BUS_ERROR EQU 00H ;(所有方式)总线错误
SMB_START EQU 08H ;(MT&MR)主收发器发送起始位成功.再将从机写地址送SMB0DAT
SMB_RP_START EQU 10H ;(MT&MR)主收发器重复发送起始位成功,再将从机读地址送SMB0DAT
SMB_MTADDACK EQU 18H ;(MT)主收发器发送从地址+W成功;收到 ACK(从机应答)
; 再将从器件的子地址送入SMB0DAT.
SMB_MTADDNACK EQU 20H ;(MT)主收发器发送从地址+W成功;收到 NACK(从机无应答)
SMB_MTDBACK EQU 28H ;(MT)主收发器发送数据字节成功;收到ACK(从机应答)
SMB_MTDBNACK EQU 30H ;(MT)主发送器发送数据成功;收到NACK(从机无应答).
SMB_MTARBLOST EQU 38H ;(MT)总线竞争失败
SMB_MRADDACK EQU 40H ;(MR)主收发器发送从地址+R成功;收到 ACK(从机应答)
SMB_MRADDNACK EQU 48H ;(MR)主收发器发送从地址+R成功;收到NACK(从机无应答)
SMB_MRDBACK EQU 50H ;(MR)主收发器接收数据成功;主机发送ACK
SMB_MRDBNACK EQU 58H ;(MR)主收发器接收数据成功;主机发送NACK
DSEG ; 数据段;
ORG 30H
RECEIVE_BYTEH: DS 1 ; 保存SMBus刚收到的16位数据的高字节
RECEIVE_BYTEL: DS 1 ; 保存SMBus刚收到的16位数据的低字节
TRANSMIT_BYTE: DS 1 ; 保存SMBus待发送的字节
SLA_ADD: DS 1 ; 保存从地址
WRI_ADD: DS 1 ; 保存从地址+ WRITE
READ_ADD: DS 1 ; 保存从地址+ READ
SUBADR_ADD: DS 1 ; 要访问的器件地址
; 用于暂存数据的单元
DATA_COUNT: DS 1 ; 计数器单元
DATA_BYTE: DS 1 ; 数据单元
DATA_ADDR: DS 1 ; 地址单元
BSEG
ORG 00H
RW: DBIT 1 ;R/W命令位。l=READ,0=WRITE
SM_BUSY: DBIT 1 ;SMBus忙标志(软件保存)
BYTE_SENT: DBIT 1 ;刚发送的字节为l,表示地址;为0是数据字节
CSEG ;代码段
ORG 00H ;复位
LJMP MAIN
ORG 03BH ;SMBus中断向量
LJMP SMBus_ISR
;主程序
MAIN: MOV SP,#7H
MOV R1,#50H
MOV WDTCN,#0DEH ;禁止看门狗定时器
MOV WDTCN,#0ADH;
LCALL PORT_Init ;初始化I/O端口
; 初始化SMBus程序段
MOV SMB0CN,#04H ; 配置 SMBus在确认周期发送 ACK
MOV SMB0CR,#0ECH ; 设置时钟速率=100 kHz (系统时钟为4MHZ)
ORL SMB0CN,#40H ; 允许SMBus
ORL EIE1,#02H ; 允许SMBus中断
CLR SM_BUSY ; 为第一次传输清除SM_Busy标志
SETB EA
; 配置LM92为连续采样模式,向LM92配置寄存器写数据0
MOV DATA_BYTE,#0 ;装入待写的数据
MOV DATA_ADDR,#00H ; 装入待写数据的首地址
MOV DATA_COUNT,#1H ; 装入待写数据块的长度
WRITE: ;发送数据DATA_BYTE到存储器地址DATA_ADDR
MOV SLA_ADD,#CHIP_A ; 装入从器件的写地址
MOV TRANSMIT_BYTE,DATA_BYTE ; 将待发送数据装入TRANSMIT_BYTE
MOV SUBADR_ADD,DATA_ADDR ;将器件地址装入 SUBADR_ADD
LCALL SEND ; 调用发送子程序
INC DATA_BYTE ;数据的值加一
INC DATA_ADDR ;地址加1
DJNZ DATA_COUNT,WRITE ; 计数器减1循环
READ:MOV R1,#50H
MOV DATA_ADDR,#00H ; 装入首地址
MOV DATA_COUNT,#1H ; 装入数据块长度
SETB EA ;开中断
MOV SLA_ADD,#CHIP_A ;装入从器件的写地址
MOV SUBADR_ADD,DATA_ADDR ;将存储器地址装入 SUBADR_ADD
LCALL RECEIVE ; 调用接收子程序
MOV 30H,RECEIVE_BYTEH ;从LM92读出的数据的高8位存入30H
MOV 31H,RECEIVE_BYTEL ;从LM92读出的数据的低8位存入31H
LCALL LDELAY
CLR SI
CLR EA
LCALL EXCHG ; 数据转换子程序
LCALL SAA1064 ;SAA1064驱动四位数码管显示子程序
SJMP READ ; 运行结束,原地等待.
;发送子程序SEND;向LM92发送单字节写操作。
SEND:
PUSH ACC ;保存累加器
JB SM_BUSY,$ ;等待SMBus空闲
CLR RW ; RW= 0(写)
MOV A,SLA_ADD ; 取SLA_ADD到A
MOV WRI_ADD,A ;将SLA_ADD+ WRITE保存到WRI_ADD
SETB SM_BUSY ; 占用SMBus
SETB STA ; 启动发送过程
JB SM_BUSY,$ ;等待发送结束(在中断中处理)
POP ACC
RET
; 接收子程序RECEIVE
;接收子程序RECEIVE执行一次读出LM92温度值(16位)的操作。读出两个字节.
RECEIVE:
PUSH ACC ;保存累加器
JB SM_BUSY,$ ;等待 SMBus空闲
SETB RW ;RW= l(读)
MOV A,SLA_ADD ;取SLA_ADD到A
MOV WRI_ADD,A ;将SLA_ADD+ WRITE保存到WRI_ADD
MOV A,SLA_ADD ;取SLA_ADD到A
ORL A,#01 ; 准备加读命令
MOV READ_ADD,A ; 将SLA_ADD+READ保存到 READ_ADD
SETB SM_BUSY ; 占用SMBus
SETB STA ; 启动发送过程
JB SM_BUSY,$ ;等待接收结束(在中断中处理)
POP ACC ; 恢复累加器
RET
;SMBus 中断程序 ,处理SMBUS 中断
SMBus_ISR:
PUSH PSW ; 保护现场
PUSH ACC ;
PUSH DPH ;
PUSH DPL ;
MOV A,SMB0STA ; 将当前SMBus状态(SMB0STA)装入累加器
; 每个状态对应一个地址偏移量
ANL A,#7FH ; 屏蔽最高位
MOV @R1,A ;在50H---60H中存放SMB0STA和SMB0DAT,可查看中断路径
INC R1
MOV @R1,SMB0DAT;
INC R1
MOV DPTR,#SMB_STATE_TABLE ; DPTR指向状态表的起始地址
JMP @A+DPTR ;转移到当前状态
;SMBuS状态表 ;(SMB0STA =00H)
SMB_STATE_TABLE: ; SMB_BUS_ERROR总线错误(对所有方式)
ORG SMB_STATE_TABLE+SMB_BUS_ERROR
SETB STO ; 停止位置1,使硬件复位
JMP SMB_ISR_END ; 中断返回
;SMB_START ; (SMB0STA =08H)
;主发送器/接收器发送起始位成功.再将从机写地址送SMB0DAT并清除START位.
ORG SMB_STATE_TABLE+SMB_START
MOV SMB0DAT,WRI_ADD ; 装载从地址+ W````
CLR STA ; 清除START位
JMP SMB_ISR_END ; 中断返回
;SMB_RP_START ;(SMB0STA =10H)
;主发送器/接收器发送重复起始位成功.
;再将从机读地址送SMB0DAT并清除START位.
ORG SMB_STATE_TABLE+SMB_RP_START
MOV SMB0DAT,READ_ADD ;装载从地址+ R
CLR STA ; 清除START位
JMP SMB_ISR_END
;SMB_MTADDACK (SMB0STA =18H)
;主发送器(MT)发送从地址+W成功;收到 ACK(从机应答)
;再将要发的子地址送入SMB0DAT.
ORG SMB_STATE_TABLE+SMB_MTADDACK
MOV SMB0DAT,SUBADR_ADD ;装载从器件的子地址到SMB0DAT.
SETB BYTE_SENT ;BYTE_SENT=1.在下一次中断调用时存储器地址刚被发送
JMP SMB_ISR_END
;SMB_MTADDNACK (SMB0STA =20H)
;主发送器(MT)发送从地址+W成功;收到 NACK(从机无应答)
;用确认查询重试。发送 STOP+START
ORG SMB_STATE_TABLE + SMB_MTADDNACK
SETB STO
SETB STA
JMP SMB_ISR_END
;SMB_MTDBACK SMB0STA =28H)
;主发送器(MT)发送数据字节成功;收到ACK(从机应答)
;检查BYTE_SENT:如果为1,说明刚发出的是存储器地址;为0,刚发出的是数据字节
ORG SMB_STATE_TABLE+SMB_MTDBACK
JBC BYTE_SENT,ADDRESS_SENT ;如果BYTE_SENT=1,清除该位并转到
;ADDRESS_SENT去执行状态表以外的处理程序
JMP DATA_SENT ; 如果BYTE_SENT=0,数据刚被发出,
; 传输过程完成,转到传输结束
;SMB_MTDBNACK ;(SMB0STA =30H)
;主发送器(MT)发送数据成功;收到NACK,从机无应答.
;用确认查询重试。发送STOP+START重试
ORG SMB_STATE_TABLE+SMB_MTDBNACK
SETB STO
SETB STA
JMP SMB_ISR_END
; SMB_MTARBLOST ;(SMB0STA =38H);竞争失败.重新启动传输.
ORG SMB_STATE_TABLE+SMB_MTARBLOST
SETB STO
SETB STA
JMP SMB_ISR_END
; SMB_MRADDACK ;(SMB0STA =40H)
;(MR)主收发器发送从地址+R成功;收到 ACK(从机应答).主机发送ACK.
ORG SMB_STATE_TABLE+SMB_MRADDACK
SETB AA ;主机发送ACK,转入SMB_MRDBACK
JMP SMB_ISR_END
; SMB_MRADDNACK ;(SMB0STA =48H)
;(MR)主收发器发送从地址+R成功;收到NACK(从机无应答),发送重复起始位重试
ORG SMB_STATE_TABLE+SMB_MRADDNACK
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -