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

📄 ds1629.asm

📁 pic系列单片机得控制程序 主要进行温度采集和转换控制
💻 ASM
字号:
; ds1629.asm

; Program to demonstrate various operations on the DS1629 device.  For more info, see
; the data sheet


        LIST P=16F877, R=DEC

        INCLUDE "P16F877.inc"

; Definitions for the DS1629

DEVADD_1629    EQU    0x9E         ; I2C device address for DS 1629

; Commands that the DS 1629 supports

ACCESS_CONFIG  EQU    0xAC         ; Access the config register for read or write
START_CONVERT  EQU    0xEE         ; Start a temperature conversion
STOP_CONVERT   EQU    0xEE         ; Stop a temperature conversion
TEMP_READ_CMD  EQU    0xAA         ; Read the temp, 1 or 2 bytes
READ_COUNTER   EQU    0xA8         ; Read the count_remain register
READ_SLOPE     EQU    0xA8         ; Read the count_per_c register
ACCESS_CLOCK   EQU    0xC0         ; Access the clock/calendar register
ACCESS_ALARM   EQU    0xC7         ; Access the alarm register
ACCESS_THERM_H EQU    0xA1         ; Access the thermostat register high register
ACCESS_THERM_L EQU    0xA2         ; Access the thermostat register high register
ACCESS_RAM     EQU    0x17         ; Access the onboard RAM

; Definitions for the PIC

SDA        EQU   4     ; PORT C bit for SDA
SCL        EQU   3     ; PORT C bit for SCL
I2CRW      EQU   2     ; R/_W bit in SSPSTAT


RAM        EQU   0x20

Temp       EQU   RAM+6
Counter    EQU   RAM+7
DTemp1     EQU   RAM+8
DTemp2     EQU   RAM+9
Temper1    EQU   RAM+10
Temper2    EQU   RAM+11
Status     EQU   RAM+12
RamAddress EQU   RAM+13
RamValue   EQU   RAM+14
DTemp3     EQU   RAM+15

; Start of the Program

        ORG       3
        goto      Start

        ORG       0x20
Start

; Initialize the TRIS registers.  Importantly, SDA and SCL must be inputs

        bsf       STATUS, RP0
        clrf      TRISA               ; for led bar
        clrf      TRISD               ; for led bar
        bsf       TRISC,SDA
        bsf       TRISC,SCL
        bcf       STATUS, RP0

; Initialize the I2C control

        call      I2CConfig

; This tests three things - read the status, read and write memory and read the temperature
; You should see the default status 0xC0, then 0xA3 and finally the two bytes of the 
; temperature with one second displays before starting over.  The temperature at 70 degrees F
; displays as 0x17 and then 0x80

mainloop

        call      TestStatus
        movlw     1
        call      Delay_sec

        call      TestMem
        movlw     1
        call      Delay_sec

        call      TestTemp
        movlw     1
        call      Delay_sec

        goto      mainloop

TestMem
        movlw     0xA3
        movwf     RamValue

        movlw     0x10
        movwf     RamAddress

        call      WriteRam

        movwf     100
        call      Delay_ms

        call      ReadRam
        movf      RamValue,W
        call      DispLedBar

        return

; Get and display the status byte

TestStatus
        call      ReadStatus
        movf      Status,W
        call      DispLedBar

        return

; Now read the temperature.

TestTemp
        call      TempRead
        call      TempDisplay

        return


; Reading the temperature is a two byte operation (if accuracy is desired)
; The sequence is:
;    Start, Send Address, Send Command, Restart, Send Address, Read MSB, 
;    Send Ack, Read LSB, Send Nack, Stop

TempRead
        call      I2CStart

; Send the control byte

        movlw     DEVADD_1629
        andlw     0xFE                ; make it a write
        call      I2CSend

; Send the read temperature command

        movlw     TEMP_READ_CMD
        call      I2CSend

; Restart for read of data

        call      I2CRestart
 
; Send the address again
      
        movlw     DEVADD_1629
        iorlw     0x01                ; make it a read
        call      I2CSend

; and read the data with an ACK between the bytes

        call      I2CReceive
        movwf     Temper1

        call      I2CAck

        call      I2CReceive
        movwf     Temper2

        call      I2CNack

; Bring a merciful end to this

        call      I2CStop

        return


TempDisplay
        movf      Temper1,W
        call      DispLedBar
        movlw     1
        call      Delay_sec

        movf      Temper2,W
        call      DispLedBar
        movlw     1
        call      Delay_sec
       
 return

; Reading that status can be either one or two bytes.  Here, do only 1 byte
; Start, Send devaddr (write), send command, restart, send devaddr (read), read MSB
; send Nack, stop

ReadStatus
        call      I2CStart

; Send the control byte

        movlw     DEVADD_1629
        andlw     0xFE                ; make it a write
        call      I2CSend

; Send the read status command

        movlw     ACCESS_CONFIG
        call      I2CSend

; Restart for read of data

        call      I2CRestart
 
; Send the address again
      
        movlw     DEVADD_1629
        iorlw     0x01                ; make it a read
        call      I2CSend

; and read the MSB

        call      I2CReceive
        movwf     Status

        call      I2CNack

        call      I2CStop

        return


; ---------------------------------------------------------
; Write to RAM has the following sequence
; Start, send control (write), send address, send data, stop

WriteRam
        call      I2CStart

; Send the control byte

        movlw     DEVADD_1629
        andlw     0xFE                ; make it a write
        call      I2CSend

; Send the command

        movlw     ACCESS_RAM
        call      I2CSend


; Send the address

        movf      RamAddress,W
        call      I2CSend

; Send the data

        movf      RamValue,W
        call      I2CSend

; Stop

        call      I2CStop

        return

; ---------------------------------------------------------
; Reading RAM has the following sequence
; Start, send control (write), send address, Restart, send control (read), read data, 
; send Nack, stop


ReadRam
        call      I2CStart

; Send the control byte

        movlw     DEVADD_1629
        andlw     0xFE                ; make it a write
        call      I2CSend

; Send the command

        movlw     ACCESS_RAM
        call      I2CSend

; Send the address

        movf      RamAddress,W
        call      I2CSend

; Restart

        call      I2CRestart

; Send the control byte

        movlw     DEVADD_1629
        iorlw     0x01                ; make it a read
        call      I2CSend

; Read the data

        call      I2CReceive
        movwf     RamValue

; Ack the data

        call      I2CNack
; Stop

        call      I2CStop

        return

;----------------------------------------------------------------------------------
; I2C control routines

I2CConfig
;        movlw     b'00111011'     ; enable SSP and set mode to Master/Slave Idle
        movlw     b'00111000'     ; to be used when SPADD is used to set the speed
        movwf     SSPCON

        bsf       STATUS, RP0

; the following three or do none of these and accept the defaults.

;        clrf      SSPCON2
;        bcf       SSPSTAT, SMP
;        bcf       SSPSTAT, CKE

; If using SPADD, calculate SPADD = (Fosc/(i2c_clock_speed * 4)) - 1
; e.g. the DS1629 has a maximum clock rate of 400 kHz, so 
; SPADD = 20x10^6/(4x10^5 * 4) - 1 = 11.5

        movlw     12
        movwf     SSPADD

        bcf       STATUS, RP0
       
        return

; Issue a start

I2CStart

        bsf       STATUS, RP0
        bsf       SSPCON2, SEN     ; initiate a start condition
        bcf       STATUS, RP0

        call      I2CWait

        return

; Issue a restart

I2CRestart
        bsf       STATUS, RP0
        bsf       SSPCON2, RSEN     ; initiate a restart condition
        bcf       STATUS, RP0
        call      I2CWait

        return

; Issue a stop

I2CStop
        bsf       STATUS, RP0
        bsf       SSPCON2, PEN     ; initiate a stop condition
        bcf       STATUS, RP0
        call      I2CWait

        return

; Send a byte

I2CSend
        movwf     SSPBUF            ; Start a write op
        call      I2CWait

        return

; Receive a byte

I2CReceive
        bsf       STATUS, RP0
        bsf       SSPCON2, RCEN     ; Start receive
        bcf       STATUS, RP0
        call      I2CWait

        movf      SSPBUF, W         ; return in W
        return

; Initiate an Ack response from the master

I2CAck
        bsf       STATUS, RP0
        bcf       SSPCON2, ACKDT     ; setup ACK
        bsf       SSPCON2, ACKEN     ; send ACK
        bcf       STATUS, RP0
        call      I2CWait

        return

; Initiate a Nack response from the master

I2CNack
        bsf       STATUS, RP0
        bsf       SSPCON2, ACKDT     ; setup NACK
        bsf       SSPCON2, ACKEN     ; send NACK
        bcf       STATUS, RP0
        call      I2CWait
        return

; -----------------------------------------------------------------
; Various I2C wait operations

; Wait for an operation end by waiting for the BF bit in SSPSTAT

I2CBFWait
        bsf       STATUS, RP0
        btfsc     SSPSTAT, BF
        goto      $-1
        bcf       STATUS, RP0

        return

; Wait for an operation end by waiting for the R/W bit

I2CRWWait
        bsf       STATUS, RP0
        btfsc     SSPSTAT, I2CRW
        goto      I2CRWWait
        bcf       STATUS, RP0

        return

; Wait for an operation end by waiting for the BF bit in SSPSTAT

I2CAckWait
        bsf       STATUS, RP0
        btfsc     SSPSTAT, ACKSTAT
        goto      $-1
        bcf       STATUS, RP0

        return

; Wait for end of I2C operation by watching the SSPIF flag

I2CWait
        btfss      PIR1, SSPIF
        goto       I2CWait
        bcf        PIR1, SSPIF        ; clear for next operation
        return



; ----------------------------------------------------------
; Display routines

; Routine to display something on the LED bank

DispLedBar

; Enable the led bar and put the value in W there.

        movwf     Temp             ; save W
        movlw     0x12
        movwf     PORTA

        comf      Temp,W
        movwf     PORTD

        return

; Display something on the Led Bar and wait for one second - 
; handy for debugging

DisplayDebug
        call      DispLedBar
        movlw     1
        call      Delay_sec

; -------------------------
; Delay routines

; Delay microseconds (usec)

Delay_us
       movwf    DTemp1
dloop_u1                     ; one loop = about 1 usec
       fill (nop), 3          
       decfsz   DTemp1,F
       goto     dloop_u1
       return;


; Delay milliseconds

Delay_ms

        movwf  	DTemp1
dloop_0	                ; number of ms to delay
        movlw  	250
        movwf  	DTemp2
dloop_1	                ; 1 ms delay (approximately)
        fill (nop), 17
        decfsz 	DTemp2,F
        goto    dloop_1
        decfsz 	DTemp1,F
        goto   	dloop_0

        return

; Delay seconds

Delay_sec
        movwf  	DTemp1         ; number of seconds to delay
dloop_s0	              
        movlw  	250            ; 1 second delay
        movwf  	DTemp2
dloop_s1
        movlw     250            ; 4 ms delay
        movwf     DTemp3
dloop_s2	            
        fill (nop), 78
        decfsz 	DTemp3,F
        goto      dloop_s2
        decfsz 	DTemp2,F
        goto   	dloop_s1
        decfsz    DTemp1,F
        goto      dloop_s0

        return

        END

⌨️ 快捷键说明

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