DS18B20을 연결한 뒤 음수가 큰 양수로 보이거나 간헐적으로 온도가 튄다면, 9바이트 scratchpad의 CRC와 온도 부호를 먼저 검증하세요. 이 글은 1-Wire 수신이 끝난 바이트 배열을 해석하는 MCU 코드에 집중합니다. 명령 타이밍·배선·기생 전원 제어는 Analog Devices DS18B20 데이터시트의 별도 절차에 따라 구현해야 합니다.
9바이트를 받은 뒤 검증하는 순서
| 바이트 인덱스 | 내용 | 처리 |
|---|---|---|
| 0·1 | 온도 LSB·MSB | LSB 먼저 결합한 16비트 2의 보수 |
| 2·3 | TH·TL | 사용자 알람 설정 |
| 4 | 설정 레지스터 | 비트 6·5로 9~12비트 해상도 확인 |
| 5·6·7 | 예약 바이트 | CRC 계산에 포함 |
| 8 | CRC | 원본 바이트 0~7 계산값과 비교 |
수신 길이가 9인지 확인하고 받은 바이트를 그대로 CRC 검사한 뒤 해상도에 따른 미정의 하위 비트를 제거합니다. CRC 전에 온도 바이트를 수정하면 유효한 수신 데이터도 불일치로 판단할 수 있습니다. 설정 레지스터는 bit7=0, bit4~0=1이라는 예약 비트 형식도 검사합니다. 모든 바이트가 0인 배열은 CRC만 보면 통과할 수 있으므로 CRC를 유일한 유효성 조건으로 삼지 않습니다.
CRC-8과 부호 확장
공식 1-Wire CRC 설명의 생성 다항식은 x^8 + x^5 + x^4 + 1입니다. 초기값 0에서 각 바이트의 LSB부터 처리하는 오른쪽 이동 구현에는 반사된 상수 0x8C를 사용합니다. SHT3x 등 다른 센서의 CRC 상수와 초기값을 그대로 가져오지 마세요. CRC는 전송 오류 검출용이며 보안 인증이나 측정 시각 검증 기능은 없습니다.
온도는 12비트 해상도에서 1LSB=1/16°C입니다. 0x0191은 401/16=25.0625°C, 0xFF5E는 (65374-65536)/16=-10.125°C입니다. C에서 범위를 넘는 unsigned 값을 signed 16비트로 바로 캐스팅하는 대신, 32비트 정수에서 부호 비트가 있으면 65,536을 빼면 변환 의도가 명확합니다.
| 해상도 | 설정 비트 R1:R0 | 제거할 하위 비트 | 최대 변환 시간 |
|---|---|---|---|
| 9비트 | 00 | bit2~0 | 93.75ms |
| 10비트 | 01 | bit1~0 | 187.5ms |
| 11비트 | 10 | bit0 | 375ms |
| 12비트 | 11 | 없음 | 750ms |
해상도와 최대 시간은 데이터시트의 설정 표를 기준으로 합니다. 전원이 들어온 직후 온도 레지스터의 85°C 초기값은 CRC가 맞을 수 있습니다. 85°C라는 값만으로 무조건 센서 오류라고 단정하지 말고, 해당 센서에서 새 변환이 시작·완료됐는지 확인해야 합니다.
PC에서 검증할 C11 예제
아래 함수는 온도를 q16, 즉 1/16°C 단위의 정수로 반환합니다. 실수 계산이나 음수 정수 반올림을 섞지 않아 변환 규칙을 확인하기 쉽습니다. 인자로 받은 온도 출력은 성공할 때만 갱신되므로 호출자는 false일 때 이전 온도를 새 측정으로 사용하지 않아야 합니다. -55~125°C 범위를 벗어난 값도 거부합니다.
ds18b20_decode.c로 저장하고 gcc -std=c11 -Wall -Wextra -Werror ds18b20_decode.c -o ds18b20_decode로 빌드합니다. Linux는 ./ds18b20_decode, Windows는 ./ds18b20_decode.exe를 실행합니다.
검증 출력:
DS18B20: +25.0625C, -10.125C, 9-bit mask and 72 bit flips passed
ASCII 123456789의 독립 CRC 검증값 0xA1, 고정 scratchpad의 CRC 0x70, 양수·음수 변환, 9비트 하위 비트 제거, 짧은 프레임, 0으로 채운 프레임, 범위 초과를 검사했습니다. 9바이트 각 비트를 하나씩 바꾼 72가지 오류도 모두 거부했습니다. 이 검증은 합성 데이터 해석 시험이며 실제 1-Wire 파형을 측정한 결과는 아닙니다.
MCU 드라이버에 붙일 때
- Reset 후 Presence 응답을 확인하고 대상 ROM을 선택합니다. 여러 센서가 있는 버스에서 Skip ROM으로 모두의 scratchpad를 동시에 읽으면 충돌할 수 있습니다.
- Convert T 명령 이후 사용한 전원 방식과 해상도에 맞춰 변환 완료를 확인합니다. 기생 전원에서는 변환 동안 필요한 strong pull-up과 제한 시간을 데이터시트대로 적용합니다.
- 대상 센서의 scratchpad 9바이트를 읽고 위 함수를 호출합니다. 실패 시 실패 카운터와 센서 식별자를 기록하고 제한된 횟수로 다시 읽습니다.
- 정상 데이터에는 ROM ID·측정 시각·변환 완료 상태를 함께 보관합니다. CRC가 맞더라도 전원 투입 초기값이나 이전 변환 값일 수 있습니다.
- CRC 오류가 계속되면 1-Wire 슬롯 타이밍, 케이블 길이, 풀업·전원, 버스 충돌을 점검합니다. 소프트웨어 재시도만 늘리면 배선 문제를 가릴 수 있습니다.
공식 자료 확인: 2026-10-11. 본문의 C 예제는 실제 컴파일·실행해 검증했습니다.
댓글
첫 댓글을 남겨 보세요.