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

📄 lm92saa1064.#1

📁 C8051F.rar
💻 #1
📖 第 1 页 / 共 2 页
字号:
;参考程序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 + -