Von Miguel Köhnlein
und Michael
Gaus
symbol I2C_ADDR_HTU21D = 0x80
; HTU21D commands
symbol HTU21D_REQ_TEMP = 0xF3
symbol HTU21D_REQ_HUM = 0xF5
;*****************************************************************
symbol I2C_ADDR_HT16K33 = 0xE0
; HT16K33 register addresses
symbol REG_DIGIT0 = 0
symbol REG_DIGIT1 = 2
symbol REG_DIGIT2 = 6
symbol REG_DIGIT3 = 8
symbol REG_COLON = 4
; definitions for EEPROM table EE_ADDR_DIGITS
symbol DIGIT_OFF = 0x10
symbol DIGIT_DEGREE = 0x11
symbol DIGIT_R = 0x12
symbol DIGIT_H = 0x13
symbol DIGIT_MINUS = 0x14
symbol EE_ADDR_DIGITS = 0
; 7segment digit values for 0-9, A-F, OFF, degree, r, H, -
EEPROM EE_ADDR_DIGITS, (0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, _
0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, _
0x00, 0x63, 0x50, 0x76, 0x40)
#macro SET_BRIGHTNESS(x) ; x=0..F
param = x and 0xF or 0xE0
hi2cout (param)
#endmacro
; set 7segment digit
#macro SET_DIGIT(dig, val) ; dig=REG_DIGIT0..REG_DIGIT3, val=0..F or DIGIT_xxx
param = Val
reg_addr = dig
GoSub setDigit
#endmacro
; set decimal point of a 7segment digit
#macro SET_DP(dig) ; dig=REG_DIGIT0..REG_DIGIT3
reg_addr = dig
GoSub setDp
#endmacro
; clear decimal point of a 7segment digit
#macro CLEAR_DP(dig) ; dig=REG_DIGIT0..REG_DIGIT3
reg_addr = dig
GoSub clearDp
#endmacro
; activate colon of 7segment display
#macro SET_COLON_ON
hi2cout (REG_COLON, 0xFF)
#endmacro
; deactivate colon of 7segment display
#macro SET_COLON_OFF
hi2cout (REG_COLON, 0x00)
#endmacro
;*****************************************************************
symbol Value = w0
symbol value_lsb = b0
symbol value_msb = b1
symbol temperature = w1
symbol humidity = w2
symbol crc = b6
symbol value_nk = b7
symbol mode = b8
symbol reg_addr = b9
symbol param = b10
symbol read_value = b11
symbol negativeValue = b12
symbol dec3 = b13
symbol dec2 = b14
symbol dec1 = b15
symbol nk1 = b16
symbol nk2 = b17
GoSub initDisplay
main_loop:
GoSub i2cGetTemperature
GoSub i2cGetHumidity
GoSub printTemperature
GoSub printHumidity
sertxd(cr,lf)
If mode = 0 Then
GoSub displayTemperature
ElseIf mode = 1 Then
GoSub displayHumidity
End If
inc mode
If mode = 2 Then
mode = 0
End If
pause 1000
GoTo main_loop
i2cGetTemperature:
hi2csetup i2cmaster, I2C_ADDR_HTU21D, i2cslow, i2cbyte ; setup I2C
hi2cout (HTU21D_REQ_TEMP)
pause 60 ; wait until measurement complete
hi2cin (value_msb, value_lsb, crc)
value = value & 0xFFFC ; discard bit0 and bit1
; Temp = -46.85 + 175.72 * S_TEMP / 2^16
temperature = 17572 ** value - 4685
Return
i2cGetHumidity:
hi2csetup i2cmaster, I2C_ADDR_HTU21D, i2cslow, i2cbyte ; setup I2C
hi2cout (HTU21D_REQ_HUM)
pause 60 ; wait until measurement complete
hi2cin (value_msb, value_lsb, crc)
value = value & 0xFFFC ; discard bit0 and bit1
; RH = -6 + 125 * S_RH / 2^16
humidity = 125 ** value - 6
if humidity >= 0x8000 then
humidity = 0 ; negative result => limit to 0%
ElseIf humidity > 99 Then
humidity = 99 ; limit to 99%
End If
Return
printTemperature:
sertxd ("T [dC]: ")
Value = temperature
if value >= 0x8000 then
value = -value; negative temperature
sertxd ("-")
End If
value_nk = value % 100 / 10
Value = Value / 100
sertxd(#value, ",", #value_nk, cr, lf)
Return
printHumidity:
sertxd ("rH [%]: ")
sertxd(#humidity, cr, lf)
Return
initDisplay:
hi2csetup i2cmaster,I2C_ADDR_HT16K33,i2cslow,i2cbyte ; setup I2C
hi2cout(0x21) ; Normal operation mode
hi2cout(0x81) ; Display On
SET_BRIGHTNESS(0xF) ; max. brightness
GoSub clearDisplay
Return
clearDisplay:
hi2csetup i2cmaster,I2C_ADDR_HT16K33,i2cslow,i2cbyte ; setup I2C
For reg_addr = 0 To 15
hi2cout (reg_addr, 0) ; clear all segments
Next reg_addr
Return
setDigit:
If param >= "0" And param <= "9" Then
param = param - "0"
End If
param = param + EE_ADDR_DIGITS
read param, param ; get 7segment digit value from onchip EEPROM
hi2cin reg_addr, (read_value) ; read old value from HT16K33
param = read_value and 0x80 or param ; keep decimal point (bit 7) and change digit value
hi2cout(reg_addr, param) ; write new value value to HT16K33
Return
setDp:
hi2cin reg_addr,(read_value) ; read old value from HT16K33
param = read_value or 0x80 ; set decimal point (bit 7) and keep digit value
hi2cout(reg_addr, param) ; write new value value to HT16K33
Return
clearDp:
hi2cin reg_addr,(read_value) ; read old value from HT16K33
param = read_value and 0x7F ; clear decimal point (bit 7) and keep digit value
hi2cout(reg_addr, param) ; write new value value to HT16K33
Return
displayTemperature: ; temperature xxx.xx (multipled with 100 because of 2 decimal places)
hi2csetup i2cmaster,I2C_ADDR_HT16K33,i2cslow,i2cbyte ; setup I2C
GoSub clearDisplay
Value = temperature
if value >= 0x8000 then
negativeValue = 1
value = -value; negative temperature
SET_DIGIT(REG_DIGIT0, DIGIT_MINUS)
Else
negativeValue = 0
End If
bintoascii Value, dec3, dec2, dec1, nk1, nk2
SET_DIGIT(REG_DIGIT3, DIGIT_DEGREE)
Value = Value / 100
If Value < 10 Then
SET_DIGIT(REG_DIGIT1, dec1)
SET_DP(REG_DIGIT1)
SET_DIGIT(REG_DIGIT2, nk1)
ElseIf Value < 100 Then
If negativeValue = 1 Then
SET_DIGIT(REG_DIGIT1, dec2)
SET_DIGIT(REG_DIGIT2, dec1)
Else
SET_DIGIT(REG_DIGIT0, dec2)
SET_DIGIT(REG_DIGIT1, dec1)
SET_DP(REG_DIGIT1)
SET_DIGIT(REG_DIGIT2, nk1)
End If
Else
If negativeValue = 1 Then
SET_DIGIT(REG_DIGIT1, dec3)
SET_DIGIT(REG_DIGIT2, dec2)
SET_DIGIT(REG_DIGIT3, dec1)
Else
SET_DIGIT(REG_DIGIT0, dec3)
SET_DIGIT(REG_DIGIT1, dec2)
SET_DIGIT(REG_DIGIT2, dec1)
End If
End If
Return
displayHumidity: ; humdity xx (0..99)
hi2csetup i2cmaster,I2C_ADDR_HT16K33,i2cslow,i2cbyte ; setup I2C
GoSub clearDisplay
Value = humidity
bintoascii Value, dec3, dec2, dec1
If Value >= 10 Then
SET_DIGIT(REG_DIGIT0, dec2)
End If
SET_DIGIT(REG_DIGIT1, dec1)
SET_DIGIT(REG_DIGIT2, DIGIT_R)
SET_DIGIT(REG_DIGIT3, DIGIT_H)
Return