Examples Index

' =========================================================================
'
'   File...... THERMOMETER.SXB
'   Purpose... Dual-mode digital thermometer
'   Author.... (c) Parallax, Inc. -- All Rights Reserved
'   E-mail.... support@parallax.com
'   Started...
'   Updated... 05 JUL 2006
'
' =========================================================================

' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------
'
' Displays the temperature from a DS1620 thermo chip on a multiplexed 7-
' segment display.  The display is multiplexed by interrupt code so that
' no additional components are required.  A mode input allows the temper-
' ature to be displayed in Celsius or Fahrenheit.
'
' When the temperature falls below 0C (32F) "-Lo-" is displayed.  When the
' temp is above 49C (120 F) "-Hi-" is displayed.

' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------

DEVICE          SX28, OSC4MHZ, TURBO, STACKX, OPTIONX
FREQ            4_000_000
ID              "THERMO"

' -------------------------------------------------------------------------
' IO Pins
' -------------------------------------------------------------------------

DQ              VAR     RC.7                    ' DS1620.1
Clock           VAR     RC.6                    ' DS1620.2
Rst             VAR     RC.5                    ' DS1620.3
DispMode        VAR     RC.4                    ' display mode, C or F
Segs            VAR     RB                      ' display segments
DigCtrl         VAR     RA                      ' digit control (cathode)

' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------

Blank           CON     %00000000               ' blank display
Dash            CON     %01000000               ' pattern for "-"
Ltr_C           CON     %00111001               ' pattern for "C"
Ltr_F           CON     %01110001               ' pattern for "F"
Ltr_L           CON     %00111000               ' pattern for "L"
Ltr_o           CON     %01011100               ' pattern for "o"
Ltr_H           CON     %01110110               ' pattern for "H"
Ltr_i           CON     %00010000               ' pattern for "i"

TC              CON     0                       ' mode = Celsius
TF              CON     1                       ' mode = Fahrenheit

' *** DS1620 Commands ***

RdTmp           CON     $AA                     ' read temperature
WrHi            CON     $01                     ' write TH (high temp)
WrLo            CON     $02                     ' write TL (low temp)
RdHi            CON     $A1                     ' read TH
RdLo            CON     $A2                     ' read TL
StartC          CON     $EE                     ' start conversion
StopC           CON     $22                     ' stop conversion
WrCfg           CON     $0C                     ' write config register
RdCfg           CON     $AC                     ' read config register

' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------

display         VAR     Byte(4)                 ' multiplexed segments
digPntr         VAR     Byte                    ' digit pointer
digLimit        VAR     Byte                    ' 0 - 3
theTemp         VAR     Byte                    ' temperature
tSign           VAR     Byte                    ' sign in bit 0
work            VAR     Byte

tmpB1           VAR     Byte                    ' subroutine work vars
tmpB2           VAR     Byte
tmpW1           VAR     Word

' =========================================================================
  INTERRUPT 200
' =========================================================================

' Points to next digit of display every 5 milliseconds (200 times/sec).

ISR_Start:
  INC digPntr                                   ' point to next digit
  IF digPntr < digLimit THEN Update_Segs        ' update digit
  digPntr = 0                                   ' wrap if needed

Update_Segs:
  Segs = Blank                                  ' blank segs
  READ DigMap + digPntr, DigCtrl                ' select display element
  Segs = display(digPntr)                       ' output new digit segs

ISR_Exit:
  RETURNINT

' =========================================================================
  PROGRAM Start
' =========================================================================

' -------------------------------------------------------------------------
' Subroutines
' -------------------------------------------------------------------------

INIT_1620       SUB     0                       ' initialize DS1620
RD_1620         SUB     0                       ' get temp from DS1620
NEW_DISPLAY     SUB     2                       ' update display

' -------------------------------------------------------------------------
' Program Code
' -------------------------------------------------------------------------

Start:
  DigCtrl = %1111                               ' disable all digits
  TRIS_A = %0000                                ' make dig pins outputs
  Segs = Blank                                  ' clear seg drivers
  TRIS_B = %00000000                            ' make seg pins outputs
  TRIS_C = %10011111                            ' clock and rst are outputs
  INIT_1620
  PUT display(0), Blank, Blank, Blank, Blank    ' clear display
  digLimit = 4                                  ' use all digits (1 - 4)
  digPntr = 3

Main:
  DO
    theTemp = RD_1620                           ' read temperature
    NEW_DISPLAY theTemp, tSign                  ' display value
    PAUSE 500                                   ' delay between reads
  LOOP

' -------------------------------------------------------------------------
' Subroutine Code
' -------------------------------------------------------------------------

' Initialize DS1620 for free-run mode and for use with a host CPU

INIT_1620:
  Rst = 1                                       ' select device
  SHIFTOUT DQ, Clock, LSBFIRST, WrCfg           ' write to config register
  SHIFTOUT DQ, Clock, LSBFIRST, %00000010       ' with CPU; free-run
  Rst = 0                                       ' deselect device
  PAUSE 10                                      ' allow DS1620 EE to write
  Rst = 1                                       ' reselect
  SHIFTOUT DQ, Clock, LSBFIRST, StartC          ' start conversion
  Rst = 0                                       ' deselect
  RETURN

' -------------------------------------------------------------------------

' Use: theTemp = RD1620
' -- returns temp in whole degrees C in 'theTemp'

RD_1620:
  Rst = 1                                       ' select device
  SHIFTOUT DQ, Clock, LSBFIRST, RdTmp           ' send read temp command
  SHIFTIN DQ, Clock, LSBPRE, tmpB1              ' get temp (C x 0.5)
  SHIFTIN DQ, Clock, LSBPRE, tSign\1            ' get sign bit
  Rst = 0                                       ' deselect device
  tmpB1 = tmpB1 + tmpB1.0                       ' round up
  tmpB1 = tmpB1 >> 1                            ' remove half bit
  RETURN tmpB1

' -------------------------------------------------------------------------

' Use: NEW_DISPLAY temperature, sign
' -- puts 'temperature' in display (pass value in degrees C)
' -- display mode (C or F) controlled by RC.4 input

NEW_DISPLAY:
  tmpB1 = __PARAM1                              ' temperature
  tmpB2 = __PARAM2                              ' sign bit

  IF tmpB2 = 1 THEN                             ' negative temp?
    digLimit = 4
    PUT display(0), Dash, Ltr_o, Ltr_L, Dash    ' show "-Lo-"
    GOTO Display_Done
  ENDIF

  IF tmpB1 > 49 THEN                            ' too high?
    digLimit = 4
    PUT display(0), Dash, Ltr_i, Ltr_H, Dash    ' show "-Hi-"
    GOTO Display_Done
  ENDIF

Check_Mode:
  IF DispMode = TC THEN                         ' check mode input switch
    display(0) = Ltr_C
  ELSE
    display(0) = Ltr_F
    tmpW1 = tmpB1 */ $1CC                       ' temp x 1.8 (9/5)
    tmpB1 = tmpW1_LSB + 32
  ENDIF

Set_Display:                                    ' blank leading zeros
  digLimit = 2                                  ' 1-digit temp
  IF tmpB1 < 10 THEN Show_Temp
  INC digLimit                                  ' 2-digit temp
  IF tmpB1 < 100 THEN Show_Temp
  INC digLimit                                  ' 3-digit temp

Show_Temp:
  tmpB2 = tmpB1 / 100                           ' get hundreds digit
  tmpB1 = __REMAINDER                           ' save 10's and 1's
  READ SegMap + tmpB2, display(3)               ' get segment map 100's
  tmpB2 = tmpB1 / 10                            ' get 10's digit
  tmpB1 = __REMAINDER                           ' save 1's
  READ SegMap + tmpB2, display(2)               ' get segment map for 10's
  READ SegMap + tmpB1, display(1)               ' get segment map for 1's

Display_Done:
  RETURN

' =========================================================================
' User Data
' =========================================================================

SegMap:                                         ' segments maps
'       .gfedcba
  DATA %00111111                                ' 0
  DATA %00000110                                ' 1
  DATA %01011011                                ' 2
  DATA %01001111                                ' 3
  DATA %01100110                                ' 4
  DATA %01101101                                ' 5
  DATA %01111101                                ' 6
  DATA %00000111                                ' 7
  DATA %01111111                                ' 8
  DATA %01100111                                ' 9

DigMap:                                         ' digit select map
  DATA %11111110
  DATA %11111101
  DATA %11111011
  DATA %11110111