#include // LCD #define CLK 0 #define DAT 1 #define WAIT 30 #define FIG4(X) (((X) & 0xf000) >> 12) #define FIG3(X) (((X) & 0xf00) >> 8) #define FIG2(X) (((X) & 0xf0) >> 4) #define FIG1(X) ((X) & 0xf) volatile uint16_t adin; ISR(ADC_vect) { adin = ADCL; adin |= ADCH << 8; } void setup() { DDRB = 0b00000011; PORTB = 0b00000011; // 省エネ設定 ACSR |= _BV(ACD); // アナログ比較器電力削減 DIDR0 |= _BV(ADC3D); // ADC3(PB3)デジタル入力禁止 // AD変換 ADMUX |= _BV(REFS0) | _BV(MUX1) | _BV(MUX0); // 内部1.1V基準電圧 ADCSRA |= _BV(ADEN) | _BV(ADIE) | _BV(ADPS1); // 分周値1/4 150kHz // スリープ設定 set_sleep_mode(SLEEP_MODE_ADC); // A/D変換雑音低減動作 sleep_enable(); // スリープ許可 delay(200); // LCD準備待ち sei(); // 割り込み許可 } void loop() { ADCSRA |= _BV(ADSC); // A/D変換開始 sleep_mode(); calcTemp(adin); delay(500); } // LCD表示(自作デバイス) void sendChar(uint8_t chr) { for(int n = 0; n < 8; n++) { digitalWrite(DAT, (chr >> n) & 1); delayMicroseconds(WAIT); digitalWrite(CLK, LOW); delayMicroseconds(WAIT); digitalWrite(CLK, HIGH); } } void calcTemp(uint16_t ain) { uint16_t one, hundred; char temp[5]; uint8_t c, n; // 0℃のとき500mV 温度係数10.0mV/℃ // A/D入力値を電圧に変換 電圧 = A/D入力値 * 1100 / 1024 // 電圧を温度に変換 温度 = (電圧 - 500) / 10 // アナログ入力値 * 107 1100 / 1024 = 1.07421875を100倍 one = hex2dec(ain * 7); // アナログ入力値 * 1の位 hundred= hex2dec(ain); // アナログ入力値 * 100の位 // 5桁の10進数に変換 temp[4] = FIG1(one); temp[3] = FIG2(one); n = FIG3(one) + FIG1(hundred); temp[2] = n % 10; c = n / 10; // 繰り上げ n = FIG4(one) + FIG2(hundred) + c; temp[1] = n % 10; c = n / 10; // 繰り上げ n = FIG3(hundred) + c; temp[0] = n % 10; temp[0] -= 5; // 500mVのオフセット (マイナスの温度は考えない) // 小数点(1桁)表示に戻す sendChar(0x80); // カーソル先頭へ(独自コマンド) sendChar(temp[0] + '0'); sendChar(temp[1] + '0'); sendChar('.'); sendChar(temp[2] + '0'); } // 16進数→10進数 uint16_t hex2dec(uint16_t hex) { uint16_t dec = 0, d = 1, n; n = hex; while(true) { dec += (n % 10) * d; n /= 10; if(n == 0) break; d *= 16; } return dec; }