온도센서를 다루기 위해서는 기본적인 소스를 알고 가야한다.
//Aduino ver.
OneWire::OneWire(uint8_t pin)
{
pinMode(pin, INPUT); //INPUT MODE로 설정
bitmask = PIN_TO_BITMASK(pin);
baseReg = PIN_TO_BASEREG(pin);
#if ONEWIRE_SEARCH
reset_search();
#endif
}
uint8_t OneWire::read_bit(void)
{
IO_REG_TYPE mask=bitmask;
volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;
uint8_t r;
noInterrupts();
DIRECT_MODE_OUTPUT(reg, mask); //Input을 Output로 변경
DIRECT_WRITE_LOW(reg, mask);
delayMicroseconds(3);
DIRECT_MODE_INPUT(reg, mask); // Output에서 Input으로 변경
delayMicroseconds(10);
r = DIRECT_READ(reg, mask); //1bit를 읽어드림
interrupts();
delayMicroseconds(53);
return r;
}
Q : 분명 Input Mode로 설정했는데 왜 다시 Output Mode로 설정해주는 걸까?
A : Data선이 한 개이므로 Read/Wrtie를 같이하는 거다.
uint8_t OneWire::read() {
uint8_t bitMask;
uint8_t r = 0;
for (bitMask = 0x01; bitMask; bitMask <<= 1)
{
if ( OneWire::read_bit() )
{
r |= bitMask;
}
}
return r;
}
uint8_t OneWire::read() {
uint8_t bitMask;
uint8_t r = 0;
for (int = 0; i<8; i++) //위아래는 동일한 코드
{
if ( OneWire::read_bit() )
{
r |= bitMask;
}
bitMask <<=1;
}
return r;
}
위의 for문을 되게 독특한 형식을 가지고 있다. 일반적인 for문 같으면 " for(i=1;i<5;i++) "이런 형식이겠지만 위 코드는 조건이 붙어 있지 않다.
Q : bitMask가 uint8_t(=unsigned char/8bit 정수형)인데 이건 무슨 의미를 갖는걸까?
A : bitMask <<= 1를 쭉 하다보면 9번째 순간부터 0이 될 것이다. 0이 된다면 for문을 탈출한다.
(for문은 true일때 계속 돌고 false가 된다면 탈출한다.)
[bitMask]
00000001 << 1번째~8번째(true)
00000010
00000100
00001000
00010000
00100000
01000000
10000000
00000000 << 9번째(false)
[r = r | bitMask]
첫 번째 : 00000001 ← 00000000 | 00000001(if문 true)
두 번째 : 00000011 ← 00000001 | 00000010(if문 true)
세 번째 : 00000111 ← 00000011 | 00000100(if문 true)
첫 번째 : 00000001 ← 00000000 | 00000001(if문 true)
두 번째 : 00000001 ← 00000001 | 00000010(if문 false, 첫 번째 r값이 유지된다,)
세 번째 : 00000101 ← 00000001 | 00000100(if문 true)
**for문이 참일때는 "r =| bitMask"를 수행하고 거짓일때는 r값을 반환한다.