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

📄 wds1620.asm

📁 C8051F.rar
💻 ASM
字号:
;参考程序B:WDS1620.ASM  数字式温度传感器DS1620实验DALLAS( 串行三线接口)
;	WDS1620.ASM 数字温度传感器DS1620测温实验:P0.2接DQ位 P0.3接 CLK位,P0.4接RST位
;数字式温度传感器DS1620配有DALLAS( 串行三线接口)
;用DS1620测量温度,用SAA1064驱动四位数码管显示温度值:012.5℃
;设定DS1620的上限温度值(THIGH)为30度,下限温度值(TLOW)为20度.
;用DS1620测量温度,用SAA1064驱动四位数码管显示温度值:012.5℃
;显示器位置:	    第一位	第二位	第三位	第四位
;显示数值           0	     1`	      2 .	    5
;数值存储单元地址  72H	    73H	      74H	    75H
;设定DS1620的上限温度值(THIGH)为30度,下限温度值(TLOW)为20度.
$include (c8051f020.inc)
 RST            EQU   P0.4   ;复位线
 CLK            EQU   P0.3   ;时钟线
 DQ             EQU   P0.2   ;数据线
 WR_CONFIG      EQU   0CH     ;写DS1620  CONFIGUARATION 命令
 RD_TEMP        EQU   0AAH    ;读DS1620 温度值命令命令
 RD_CONFIG      EQU   0ACH    ;读DS1620 CONFIGURATION命令
 STOP_CONVERT   EQU   22H     ;停止转换命令
 START_CONV     EQU   0EEH    ; 开始转换命令
 WR_TH          EQU   01H      ;写温度上限命令
 WR_TL          EQU   02H      ; 写温度下限命令
 RD_TH          EQU   0A1H    ; 读温度上限命令
 RD_TL          EQU   0A2H   ; 读温度下限命令
 SLAW           EQU   060H      ;存放SAA1064 写的寻址字节在60H中
 SLAR           EQU   061H      ;存放SAA1064 读的寻址字节在61H中 
 SLA            EQU   68H          
 NUMBYT         EQU   6BH     ;被传送的字节数存放单元
 MTD            EQU   20H     ;发送数据缓冲区首地址
 MRD            EQU   30H     ;接收字节缓冲区首地址       
 VSCL           EQU   P0.1     ;IIC时钟信号
 VSDA           EQU   P0.0    ;LLC数据输入/输出线
 COM            EQU   17H     ;SAA1064 的设置。
 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   MAIN
         ORG    03BH        ;SMBus中断向量
         LJMP   SMBus_ISR
ORG      100H   
MAIN:    MOV	  WDTCN,#0deH   ;关看门狗
	     MOV  	WDTCN,#0adH
		LCALL  PORT_Init
         MOV    XBR2,#40H
         LCALL  DS1620INT   ;DS1620初始化:设定上/下限温度值
         ACALL  RDS1620  ;读出DS1620采集的温度值,并转化为十进制数据
         LCALL   DELY    ;延时一秒
         LCALL   DISPLAY  ;显示温度值(四位)
         AJMP    MAIN
RDS1620: SETB    RST
         MOV     A,#START_CONV   ;DS1620命令 开始转换
         CALL    OUT_1620
         CLR     RST
				 NOP
				 NOP
         SETB     RST
         MOV      A,#RD_TEMP    ; DS1620命令 读出温度值
         ACALL    OUT_1620
         ACALL    IN_1620        ;输入温度值的低8位,存入20H中.
         MOV      20H,A
         ACALL    IN_1620        ;输入温度值的高8位,存入A中.
         MOV      72H,#0         ;71H存符号位"+"("0"为正,"1"为`负")
         ANL      A,#01
         CJNE     A,#1,SV    ;判符号位.,(A)=0 温度为正,(A)=1,温度为负
       MOV      72H,#10H ;71H存符号位"-" ("-"的字形码为"40H")查表地址为10H
         MOV      A,20H      ;温度为负值,数据为补码,应求反加1
         CPL      A
         INC      A
         MOV      75H,A
SV:      MOV      A,20H
         ACALL    EXCH     ;子程序EXCH将二进制数据转化为十进制数据
         RET
EXCH  : CLR     C     ;子程序EXCH将二进制数据转化为十进制数据
        MOV     B,A
				ANL     A,#01
				MOV     75H,A
				MOV     A,B
        RRC     A     ;存放在72H(百为),73H(十位),74H(个位),75H(小数位)中
        MOV     B,#10 
        DIV     AB
        PUSH    ACC
        MOV     74H,B
        POP     ACC
        MOV     B,#10
        DIV     AB
        MOV     72H,A ;存放在72H(百位),73H(十位),74H(个位),75H(小数位)中
        MOV     73H,B
        MOV     A,B
				MOV     A,75H
				MOV     75H,#0
				CJNE    A,#1,VS
        MOV     75H,#5
  VS:   RET   
OUT_1620:  MOV   R0,#8H    ;串行输出一个字节(8 BIT),输出数据在A中。
     WLP:  RRC   A
           CLR    CLK
           MOV   DQ,C
           SETB   CLK
           DJNZ  R0,WLP
           RET
  IN_1620: MOV   R0,#8     ;串行输入一个字节(8 BIT),结果在R2中.
           SETB  DQ
           MOV   R2,#0
      RLP: CLR   CLK
           MOV   C,DQ
           SETB  CLK
           MOV   A,R2
           RRC   A
           MOV   R2,A
           DJNZ  R0,RLP
           RET 
DELY:      MOV R5,#8      ;延时子程序(延时一秒)
TM2:       MOV R6,#0H  
TM1:       MOV R7,#0H    
           DJNZ R7,$
           DJNZ R6,TM1
           DJNZ R5,TM2
           RET
DISPLAY:CLR    SM_BUSY          ;为第一次传输清除SM_Busy标志
				MOV    R1,#50H          ;从50H--5EH 看中断过程
; SAA1064W: 依次连续写入6个数到SAA1064中去:17H,3FH,06H,5BH,4FH
        MOV     SUBADDR,#00H ; 装入SAA1064的子地址(SUBADR=00H)
        MOV     DATA_COUNT,#6H    ; 装入待写数据块的长度
        MOV     SLA_ADD,#SAA1064ADR   ; 装入从器件的写地址
		MOV     71H,#0AH              ;(TAB+0AH)=17H=COM
		MOV     R0,#71H                  ; R0做计数器用
        LCALL   SEND   
		CLR     EA                ; 调用数据发送子程序
    	RET                       ; SAA1064显示结束结束,返回主程序
TAB:    DB  3fH,06H,5bH,4FH,66H,6DH,7DH,07H,7FH,6FH,17H,40H
;发送子程序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)装入累加器
                        ;  每个状态对应一个地址偏移量
    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   
		CJNE    R0,#74H,VV
		ADD     A,#80H         ;加小数点
		MOV     DATA_BYTE ,A   
VV:   MOV     SMB0DAT,DATA_BYTE ;将要显示的数据(字型码)送SAA1064
      INC     R0 
	    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,#0H      ;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
DS1620INT:
    SETB   RST
	 MOV    A,#WR_TH
	 ACALL  OUT_1620
	 MOV    A,#3CH     ;设定上限温度:30度
	 LCALL OUT_1620
	 CLR    RST
	 NOP
	 NOP
	 SETB   RST
     MOV    A,#WR_TL
	 ACALL  OUT_1620
	 MOV    A,#28H     ;设定下限温度:20度
	 LCALL  OUT_1620
	 CLR    RST
RET
END

⌨️ 快捷键说明

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