mcp9808_driver.c 1.65 KB
Newer Older
Rafal Babski's avatar
Rafal Babski committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "mcp9808_driver.h"

#include "msp430_i2c.h"

#define THERMOMETER_ADDRESS (0x18)

#define THERMOMETER_REGISTER_RFU (0x00)
#define THERMOMETER_REGISTER_CONFIG (0x01)
#define THERMOMETER_REGISTER_ALERT_UPPER (0x02)
#define THERMOMETER_REGISTER_ALERT_LOWER (0x03)
#define THERMOMETER_REGISTER_CRITICAL_TEMP (0x04)
#define THERMOMETER_REGISTER_TEMPERATURE (0x05)
#define THERMOMETER_REGISTER_MANUFACTURER_ID (0x06)
#define THERMOMETER_REGISTER_DEVICE_ID (0x07)
#define THERMOMETER_REGISTER_RESOLUTION (0x08)

/**
 * Mask to access data bits from temperature register.
 *
 * MCP9808 offers 12 bits of data.
 */
#define THERMOMETER_DATA_MASK 0x0fff

/**
 * Mask to access sign bit from temperature register.
 */
#define THERMOMETER_SIGN_MASK 0x1000

/**
 * Cofficient used to convert value from temperature register to decimal value.
 *
 * Thermometer resolution is 0.0625 (power-up default)
 */
#define THERMOMETER_RESOLUTION 16.0

float msp9808_get_temperature(void)
{
    // read temperature value register using I2C
    uint8_t data[2];
    msp430_i2c_read_data(THERMOMETER_ADDRESS, THERMOMETER_REGISTER_TEMPERATURE, data, 2);

    // revert bytes of returned value
    uint16_t value = (data[0] << 8) + data[1];

    // convert to decimal value
    // see MCP9808 datasheet for more details about conversion
    float temp = 0.0;

    if(value & THERMOMETER_SIGN_MASK)
    {
        // use conversion for negative temperature
        temp = 256.0 - (value & THERMOMETER_DATA_MASK) / THERMOMETER_RESOLUTION;
    }
    else
    {
        // use conversion for positive temperature
        temp = (value & THERMOMETER_DATA_MASK) / THERMOMETER_RESOLUTION;
    }

    return temp;
}