// ATTiny2313
// компаратор
// 12-я нога AIN0 — RC-цепочка
// 13-я нога AIN1 — измеряемый сигнал
// 14-я нога PB2 — выход вкл. заряда конденсатора
#include <avr/io.h>
#include <avr/interrupt.h>
const byte conCh = 2; // линия зарядки конденсатора
uint32_t t=micros();
const uint32_t maxChrgTime=100000; // время тайминга для АЦП
void setup () {
ACSR |= 0x03; // вкл компаратор
DIDR |= 0x3; // выключить цифровой буфер на пинах компаратора
DDRB |= (1 << conCh);// включаем pb2 на выход
PORTB &= ~(1 << conCh);// выключить линию зарядки
}
uint32_t a;
void loop () {
// старт АЦП
t = micros (); // сбросить счетчик времени заряда
PORTB |= (1 << conCh); // вкл зарядку конденсатора
do { } // ждем прерывания или тайминга
while ((ACSR & (1 << 5))==0) || (micros()-t>=maxChrgTime);
t = micros () - t; // время зарядки конд.
PORTB &= ~(1 << conCh); // выкл зарядку конд.
delayMicroseconds (16000); // задержка для разряда емкости
a = approx(t); // результат измерения
}
/* Аппроксимация измеренных значений
*************************************/
const byte numP = 18; // количество точек аппроксимации
const uint16_t mkV[numP] = { 11, 34, 51, 69, 87, 105, 124, 143, 163, 182, 202, 225, 245, 268, 290, 313, 338, 362 };
const uint16_t realV[numP] = { 0, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500, 1600, 1700, 1800 };
uint32_t approx (uint32_t n) {
byte i;
for (i=1; i<=numP; i++) if (mkV[i] > n) break;
n = map (n, mkV[i-1], mkV[i], realV[i-1], realV[i]);
return n;
}