1. DS18B20 센서 개요
DS18B20은 반이중(Half-duplex), 비동기(Asynchronous), 직렬(Serial) 통신을 지원하는 디지털 온도 센서입니다.
분해능 설정
분해능은 센서가 온도 변화를 감지하는 민감도를 나타냅니다. 실제 온도 값은 센서에서 감지한 값에 분해능을 곱해서 계산합니다.
| 분해능 (비트) | 온도당 단계 (°C) |
|---|---|
| 9 | 0.5 |
| 10 | 0.25 |
| 11 | 0.125 |
| 12 | 0.0625 |
2. 주요 사양
| 기능 | 측정 범위 (°C) | 정밀도 (°C) | 분해능 | 동작 전압 |
|---|---|---|---|---|
| 온도 측정 | -55 ~ +125 | ±0.5 | 0.0625 | 3V ~ 5V |
3. ROM 명령어
DS18B20은 고유한 64비트 ROM 코드를 가지며, 다음과 같은 ROM 명령어를 지원합니다:
- ROM 읽기 (0x33): 내부에 저장된 고유 시리얼 번호读取
- ROM 검색 (0xF0): 연결된 모든 장치의 시리얼 번호 탐색
- ROM 일치 (0x55): 특정 장치만 선택적으로 통신
- ROM 건너뛰기 (0xCC): 단일 장치 시스템에서 ROM 확인 생략
- 알림 검색 (0xEC): 알람 상태의 장치만 검색
4. 주요 특성
- 단일 와이어(1-Wire) 통신 방식 채택
- "선-AND(Wire-AND)" 특성 지원
- 대기 상태 시 0전력 소모
5. 풀업 저항 연결 목적
DS18B20의 데이터 라인은 오픈 드레인(Open-Drain) 출력 구조를 가지고 있습니다. 이 구조는 데이터 라인이 능동적으로 구동되지 않을 때 고임피던스 상태가 되어, 높지도 않고 낮지도 않은 불안정한 상태가 됩니다. 마이크로컨트롤러에 직접 연결하면 신호가 올바르게 전송되지 않을 수 있으며, 외부 회로가 없으면 데이터 라인이 안정적인 논리 상태를 유지하지 못합니다.
따라서 외부 풀업 저항(일반적으로 4.7KΩ ~ 10KΩ)을 연결하여 다음과 같은 효과를 얻습니다:
- 능동 드라이브가 없을 때 데이터 라인이.logic high 상태를 유지하도록 보장
- 외부 노이즈에 대한 신호 강도 개선
- 통신 신뢰성 향상
6. 온도 측정流程
- 마이크로컨트롤러가复位 펄스 전송
- ROM 건너뛰기 명령어 (0xCC) 전송
- 온도 변환 시작 명령어 (0x44) 전송
- 변환 완료 대기 (최대 750ms)
- 다시复位 펄스 전송
- ROM 건너뛰기 명령어 (0xCC) 전송
- 스케치 메모리 읽기 명령어 (0xBE) 전송
- 하위 바이트와 상위 바이트 순차적으로 읽기
7. 타이밍 프로토콜
7.1复位 시퀀스
마스터(마이크로컨트롤러)가 버스를 최소 480µs 이상 로우로拉动한 후 버스를 놓으면(높은 상태로),复位 펄스가 전송됩니다. 마스터는 60~240µs 내에 버스가 로우로 떨어지는지 감지해야 합니다. 이는 DS18B20이 존재 펄스를 응답했음을 의미하며, 센서가 정상 동작 중임을 확인합니다. 그 후 DS18B20이 버스를 놓으면 버스는 다시 높은 상태가 됩니다.
#include <reg51.h>
#include <intrins.h>
#define DQ_PORT P3
#define DQ_BIT 7
#define DQ_HIGH (DQ_PORT |= (1 << DQ_BIT))
#define DQ_LOW (DQ_PORT &= ~(1 << DQ_BIT))
#define DQ_READ ((DQ_PORT & (1 << DQ_BIT)) != 0)
void Delay60Cycles(unsigned int count) {
unsigned char i;
while(count--) {
for(i = 0; i < 6; i++) {
_nop_();
}
}
}
int sensor_reset(void) {
unsigned int timeout = 0;
DQ_LOW;
Delay60Cycles(80);
DQ_HIGH;
Delay60Cycles(5);
while(DQ_READ && timeout < 30) {
Delay60Cycles(1);
timeout++;
}
if(timeout >= 30) return -1;
timeout = 0;
while(!DQ_READ && timeout < 30) {
Delay60Cycles(1);
timeout++;
}
if(timeout >= 30) return -2;
return 0;
}
void Delay1ms(unsigned int ms) {
while(ms--) Delay60Cycles(125);
}
7.2 쓰기 시퀀스
0 쓰기: 마스터가 버스를 60µs 이상 로우로 당깁니다. DS18B20은 60µs 내에 샘플링하여 로우를 감지하면 0으로 해석합니다. 그 후 마스터가 버스를 놓습니다.
1 쓰기: 마스터가 버스를 1µs 이상 로우로 당긴 후 즉시 놓습니다. DS18B20은 45µs 내에 샘플링하여 하이를 감지하면 1로 해석합니다.
void write_byte(unsigned char value) {
unsigned char i = 0;
for(i = 0; i < 8; i++) {
if(value & 0x01) {
DQ_LOW;
_nop_();
_nop_();
DQ_HIGH;
Delay60Cycles(5);
} else {
DQ_LOW;
Delay60Cycles(6);
DQ_HIGH;
}
value >>= 1;
}
}
7.3 읽기 시퀀스
마스터가 버스를 1µs 이상 로우로 당기고 버스를 놓습니다(하이 상태). 마스터는 이후 15µs 내에 버스 상태를 샘플링합니다. 하이가 감지되면 1, 로우가 감지되면 0으로 해석합니다. DS18B20이 버스를 놓으면 통신이 종료됩니다.
unsigned char read_byte(void) {
unsigned char value = 0;
unsigned char i = 0;
for(i = 0; i < 8; i++) {
DQ_LOW;
_nop_();
_nop_();
DQ_HIGH;
_nop_();
_nop_();
_nop_();
if(DQ_READ) {
value |= (1 << i);
}
Delay60Cycles(6);
}
return value;
}
7.4 온도 값 읽기
float read_temperature(void) {
unsigned char low_byte = 0;
unsigned char high_byte = 0;
short raw_value = 0;
sensor_reset();
write_byte(0xCC);
write_byte(0x44);
Delay1ms(750);
sensor_reset();
write_byte(0xCC);
write_byte(0xBE);
low_byte = read_byte();
high_byte = read_byte();
raw_value = (high_byte << 8) | low_byte;
return raw_value * 0.0625f;
}
8. 응용 시 고려사항
- 장거리 전송 시 풀업 저항 값을 낮게 설정(선 길이에 따라 3.3KΩ~5.1KΩ)
- 복수의 DS18B20 연결 시 각 센서의 고유 ROM 코드 관리 필요
- 정밀한 온도 측정이 필요한 경우 12비트 분해능 권장
- 전원 안정성을 위해 VDD와 GND 사이에 0.1µF 바이패스 커패시터 권장