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

📄 wds18b20.asm

📁 c8051f020温度传感器DS1620 调通了的啊
💻 ASM
字号:
;参考程序B: 程序名WDS18B20.ASM程序功能:DS18B20采样得到的温度值存入72H--75H中,再传送到SAA1064驱动的四位数码管上显示.
$include (c8051f020.inc)
DAT      EQU   P0.2
TEMPH    EQU   20H
TEMPL    EQU   21H
SAA1064ADR      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;
    TRANSMIT_BYTE: DS    1          ;保存SMBus待发送的字节
    RECEIVE_BYTE:  DS    1         ; 保存SMBus刚收到的字节
    SLA_ADD:       DS    1          ;保存从地址
    WRI_ADD:       DS    1         ; 保存从地址+ WRITE
    READ_ADD:      DS    1         ; 保存从地址+ READ
    SUBADDR:       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  
CSEG    ;代码段
         ORG      00H         ;复位
         LJMP     DS18B20
         ORG     03BH        ;SMBus中断向量
          LJMP    SMBus_ISR
    ORG    100H   
DS18B20: MOV	  WDTCN,#0deH   ;关看门狗
	     MOV  	WDTCN,#0adH
	     LCALL  PORT_Init
		 MOV    XBR2,#40H	      ;使能交叉开关和弱上拉
MAIN:    LCALL  RDTEMP
		 LCALL  DELAY            ;延时
		SETB   EA
         LCALL  DISPLAY    ;用SAA1064驱动四位数码管显示四位温度值.
         LCALL  BELL
         SJMP   MAIN
EXCHANG: MOV   A,21H      ;DS18B20采集到的原始数据已存放在20H,21H中.
         MOV   B,#16             ;数据处理:将原始转换为十进制数据,存放在
		 DIV   AB                ;72H(百位),73H(十位),74H(个位),75H(小数位)中.
         MOV   74H,A
         MOV   A,20H      
         MOV   B,#16
         MUL   AB
         ADD    A,74H
         MOV   B,#10
         DIV   AB
         MOV   74H,B
         MOV   B,#10
         DIV   AB
         MOV   73H,B
         MOV   72H,A
         MOV   71H,#0
         MOV   A,21H
         ANL   A,#0FH
         MOV   B,#8
         DIV   AB
         MOV   75H,#0
         CJNE   A,#1,SSS
         MOV   75H,#5
 SSS:    RET
RDTEMP:   CLR    EA
          LCALL   RESET        ;复位
          MOV     A,#0CCH     ;发SKIP ROM 命令
          LCALL   WRITE
          MOV     A,#44H       ;发开始温度转换命令
          LCALL   WRITE
          LCALL   RESET
          MOV     A,#0CCH      ;发SKIP ROM 命令       
          LCALL   WRITE
          MOV     A,#0BEH     ;  发读存储器命令
          LCALL   WRITE
          LCALL   READ       ;  读出温度的低字节
          MOV     B,A
          MOV     TEMPL,A
          LCALL   READ        ; 读出温度的高字节
          MOV     TEMPH,A
          LCALL   EXCHANG
          SETB   EA
          RET
RESET:    ;复位子程序   
LA:      SETB   DAT 
         MOV    R2,#200
LB:      CLR    DAT
         DJNZ   R2,LB
         SETB   DAT
         MOV    R2,  #30
LC:      DJNZ   R2,LC
         CLR    C
         ORL    C,DAT
         JC     LB
         MOV    R6,#80
LD:      ORL    C,DAT
         JC     LP
         DJNZ   R6,LD
         SJMP   LA
         DJNZ   R6,LD
LP:      MOV    R2,#250
LF:      DJNZ   R2,LF
         RET
WRITE:     ;写字节子程序 
           MOV   R3,#8    
WR1:       SETB  DAT
           MOV   R4,#8      
           RRC   A
           CLR   DAT
WR2:       DJNZ  R4,WR2  ; DELAY  16US
           MOV   DAT   ,C
           MOV   R4,#30
WR3:       DJNZ  R4,WR3
           DJNZ  R3,WR1
           SETB  DAT
           RET 
READ:     CLR    EA     ;读字节子程序
           MOV    R6,#8
RD1:       CLR    DAT
           MOV    R4,#6
           NOP
           SETB   DAT
RD2:       DJNZ   R4,RD2
           MOV    C,DAT
           RRC    A
           MOV    R5,#30
RD3:       DJNZ   R5,RD3
           DJNZ   R6,RD1
           SETB   DAT
		   SETB   EA
           RET
 DELAY:    MOV    R7,#10   ;延时
    DL2:   MOV    R6,#200         
DL1:   MOV    R5,#250       
DL0:   DJNZ   R5,DL0
           DJNZ   R6,DL1
           DJNZ   R7,DL2
           RET  
    BELL: CLR   P3.5
		  MOV   R7,#1
		  ACALL  DL2
          SETB    P3.5
		 MOV   R7,#20
		 ACALL  DL2
         RET 
DISPLAY:CLR    SM_BUSY          ;为第一次传输清除SM_Busy标志
		MOV    R1,#50H          ;从50H--5EH 看中断过程
; SAA1064W: 依次连续写入5个数到SAA1064中去:17H,3FH,06H,5BH,4FH
        MOV     SUBADDR,#00H ; 装入SAA1064的子地址(SUBADR=00H)
        MOV     DATA_COUNT,#6H    ; 装入待写数据块的长度
        MOV     SLA_ADD,#SAA1064ADR   ; 装入从器件的写地址
		MOV     71H,#0AH
		MOV     R0,#71H                  ; R0做计数器用
        LCALL   SEND   
		CLR     EA                ; 调用数据发送子程序
    	RET                       ; SAA1064显示结束结束,返回主程序
TAB:    DB  3fH,06H,5bH,4FH,66H,6DH,7DH,07H,7FH,6FH,17H
;发送子程序SEND;
;SEND子程序执行一次向SAA1064写入六位数据(0,17H,4FH,5BH,06H,3FH)的过程。
;该子程序管理SM_BUSY位,设置 RW=WRITE,装载 SLAW,启动写操作。
     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保存到SLAW
	 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,SUBADDR          ;装载从器件的子地址到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
  DJNZ   DATA_COUNT,ADDRESS_SENT
 ;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   
			SETB    STA
      JMP    SMB_ISR_END
;SMB_MRDBACK                    (SMB0STA  =50H)
;(MR)主收发器接收数据成功;主机发送ACK .
  ORG    SMB_STATE_TABLE+SMB_MRDBACK       
MOV    RECEIVE_BYTE, SMB0DAT
CLR    AA ;主机发NACK(清除AA),下一次中断来时转入;SMB_MRDBNACK(58H)
CLR    SM_BUSY;
  JMP     SMB_ISR_END
;SMB_MRDBNACK                  ;(SMB0STA  =58H)
;(MR)主收发器接收数据成功;主机发送NACK 
;读操作完成。读数据寄存器并发送STOP
      ORG     SMB_STATE_TABLE+SMB_MRDBNACK     
      MOV    RECEIVE_BYTE, SMB0DAT
      SETB    STO
	  SETB    AA       ;主机发ACK,为下一次传输置位AA
      CLR    SM_BUSY;
      JMP    SMB_ISR_END
;状态表结束,处理"SMB_MTDBACK"状态码的程序段。
;对于地址字节刚发出的状态。通过检查RW位确定处理方法。
;如果为读,则转到RW_READ,如果为写,则将待发送数据装入SMBODAT。
    ADDRESS_SENT:
		MOV     DPTR,#TAB   ;查表,找到显示的数据(字型码)
		MOV     A,@R0
		MOVC    A,@A+DPTR     
       MOV     DATA_BYTE ,A   
		INC     R0  
	   CJNE    R0,#75H,VV
		ADD     A,#80H
       MOV     DATA_BYTE ,A   
VV:    MOV     SMB0DAT,DATA_BYTE ;将要显示的数据(字型码)送SAA1064
	    JMP     SMB_ISR_END            ; 中断返回
;对于地址字节刚发出的状态。重复发送START,启动存储器读操作
    RW_READ:
    SETB      STA                    ;重复发送START
    JMP      SMB_ISR_END            ;中断返回
;这是一个写操作,数据字节已发出。传输过程结束。发送STOP,释放总线,中断返回
    DATA_SENT:
    SETB    STO                     ;发送STOP后中断返回
    CLR     SM_BUSY                ; 释放 SMBus
    JMP     SMB_ISR_END            ; 中断返回
;SMBus ISR exit
;恢复现场,清除SI位,从中断返回
   SMB_ISR_END:
    CLR    SI
    POP    DPL 
    POP    DPH
    POP    ACC
    POP    PSW
    RETI
PORT_Init :
   MOV    OSCICN,#14H        ;内部晶振设定为2MHZ
   MOV    P0MDOUT,#0FFH      ;P0口为开漏方式
   MOV    XBR0,#01H  ;通过功能选择开关将将SDA接P0.0引脚,SCL接P0.1引脚
   MOV    XBR2 ,#40H;      允许功能选择开关和弱上拉
 ; 初始化SMBus程序段
   MOV   SMB0CN,#04H     ; 配置 SMBus在确认周期发送 ACK
   MOV   SMB0CR,#0F6H    ; 设置时钟速率=100 kHz (内部晶振设定为2MHZ)
   ORL   SMB0CN,#40H     ; 允许SMBus
   ORL    EIE1,#02H      ; 允许SMBus中断
	SETB   EA
   RET
	 END

⌨️ 快捷键说明

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