Работа с 1 wire устройствами на С

Работа с однопроводным интерфейсом (one wire, 1 wire) на примере датчика температуры DS1820 (DS1821) и контроллера от фирмы Atmel (ATMEGA8).


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
// настройки 1wire
#define OW_PORT D //указываем порт, которому подлючено 1wire устройство
#define OW_PIN 2 //указываем ножку порта, которой подлючено 1wire устройство
 
#include "onewire.h" //подключем наш файл onewire.h
uint8_t TempBuffer[2]; //массив для хранения полученной температуры
 
//пример работы с датчиком температуры DS1820
 
int TEMP(void) {
    _delay_us(100); //небольшая задержка (можно убрать)
 
    ow_reset(); //сбрасываем линию, смотрим чтобы на ней никого не было
 
    ow_byte_wr(0xCC); //пересылаем комманду на соединение
    ow_byte_wr(0x44); //даем комманду на расчет температуры
 
    _delay_us(100); //ждем пока датчик обработает данные со своих сенсеров 
                               //(зависит от настройки датчика, может быть до 1сек)
 
    ow_reset(); //сбрасываем линию
    ow_byte_wr(0xCC); //обращаемся к устройству
    ow_byte_wr(0xBE); // просим отдать нам значение полученной температуры
 
    TempBuffer[0] = ow_byte_rd(); //принимаем первый байт
    TempBuffer[1] = ow_byte_rd(); //принимаем второй байт
 
    return (0);
}
 
// преобразование полученных байт в значение температуры со знаком
float Conv(uint8_t H, uint8_t L) {
    int16_t g = (int16_t) ((H << 8) | L);
    float t = (float) g / 16;
    return (t);
}

 

 

Работа с 1 wire на С для ATMEL onewire.h 
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
62
63
64
65
66
67
68
69
70
#define OW_CONCAT(a, b) a ## b
#define OW_ECONCAT(a, b) OW_CONCAT(a, b)
 
#define OW_IN   OW_ECONCAT(PIN, OW_PORT)
#define OW_OUT  OW_ECONCAT(PORT, OW_PORT)
#define OW_DDR  OW_ECONCAT(DDR, OW_PORT)
 
#define OW_GET_IN()   ( OW_IN & (1 << OW_PIN))
#define OW_OUT_LOW()  ( OW_OUT &= (~(1 << OW_PIN)) )
#define OW_OUT_HIGH() ( OW_OUT |= (1 << OW_PIN) )
#define OW_DIR_IN()   ( OW_DDR &= (~(1 << OW_PIN )) )
#define OW_DIR_OUT()  ( OW_DDR |= (1 << OW_PIN) )
 
uint8_t ow_bit_io(uint8_t b);
 
uint8_t ow_reset() {
    uint8_t err;
 
    OW_OUT_LOW();
    OW_DIR_OUT();
    _delay_us(500);
 
    OW_DIR_IN();
    _delay_us(60);
 
    err = OW_GET_IN();
    _delay_us(300);
 
    if (OW_GET_IN() == 0)
        err = 1;
 
    return err;
}
 
uint8_t ow_bit_io(uint8_t bit) {
    cli();
 
    OW_DIR_OUT();
    _delay_us(1);
 
    if (bit)
        OW_DIR_IN();
    _delay_us(1);
 
    bit = (OW_GET_IN() != 0);
 
    sei();
 
    _delay_us(45);
    OW_DIR_IN();
 
    return bit;
}
 
uint8_t ow_byte_wr(uint8_t byte) {
    uint8_t i = 8, bit_read;
 
    do {
        bit_read = ow_bit_io(byte & 1);
        byte >>= 1;
        if (bit_read)
            byte |= 0x80;
    } while (--i);
 
    return byte;
}
 
uint8_t ow_byte_rd() {
    return ow_byte_wr(0xFF);
}