Температурный датчик от AD с частотным выходом. Принцип работы прост как двери...
Но почему выдает такой результат, не пойму никак... Пробовал режим работы
One Shot Mode и
Continuously Converting Mode.
Выкладываю исходники. Может со стороны видно ошибку.
Код
///////////////////////////////////
// tmp05.c
//------------------------------------
unsigned long T_high, T_low;
double Temperature;
unsigned Timer1OvfCount;
#pragma vector=INT0_vect
__interrupt void INT0_ISR()
{
if(!Flags.IsMeasure)
{
T_high = TCNT1 + Timer1OvfCount * 65536UL;
Timer1OvfCount = TCNT1 = 0; // Reset count
RISING_EDGE;
Flags.IsMeasure = true;
}
else
{
T_low = TCNT1 + Timer1OvfCount * 65536UL;
Timer1Stop();
Flags.IsMeasure = false;
DISABLE_INT0;
FALLING_EDGE;
}
}
#pragma vector=TIMER1_OVF_vect
__interrupt void TC1_OVF_ISR()
{
Timer1OvfCount++; // Keep a record of timer1 overflows
}
//------------------------------------------------------------------------------
void TMP05_Init()
{
SETBIT(TMP05_DDR, TMP05_FUNC); // One Shot Mode (FUNC = 0)
CLRBIT(TMP05_PORT, TMP05_FUNC);
FALLING_EDGE;
SETBIT(TIMSK1, TOIE1); // Enable timer1 interrupts
}
//------------------------------------------------------------------------------
void TMP05_Measure()
{
DISABLE_INT0;
// Toggle PA1 (OUT) to give start pulse
SETBIT(TMP05_DDR, TMP05_OUT); // Pull PA1 output (OUT = 0)
CLRBIT(TMP05_DDR, TMP05_OUT); // Pull PA1 high-Z (OUT -> Z)
// Start Timer1 to count the high period
Timer1OvfCount = TCNT1 = 0; // Reset count
Timer1Start();
ENABLE_INT0; // Pin Change Interrupt0 edge triggered
while(IsTimer1Runing());
Temperature = 421 - (751 * ((double)T_high / T_low));
}
//////////////////////
// tmp05.h
//------------------
#define TMP05_DDR DDRA
#define TMP05_PORT PORTA
#define TMP05_PIN PINA
#define TMP05_FUNC PA0
#define TMP05_OUT PA1
#define TMP05_START PA2
#define ENABLE_INT0 {EIFR = (1 << INTF0); EIMSK = (1 << INT0);} // Clear interrupt status flag, Enable INT0
#define DISABLE_INT0 EIMSK = 0 //&= ~(1 << INT0) // Disable pin change interrupt INT0
#define FALLING_EDGE EICRA = (1 << ISC01)
#define RISING_EDGE EICRA = (1 << ISC01) | (1 << ISC00)
__monitor inline void Timer1Start()
{
SETBIT(TIFR1, TOV1);
TCCR1B = (1 << CS10); // Normal mode, No prescaler
}
__monitor inline void Timer1Stop()
{
TCCR1B = 0;
}
__monitor inline bool IsTimer1Runing()
{
return TCCR1B != 0;
}
#define BIT(n) (1 << (n))
#define SETBIT(p, n) (p |= BIT(n))
#define CLRBIT(p, n) (p &= ~BIT(n))
#define TSTBIT(p, n) (p & BIT(n))
//////////////
// main.c
//------------------------
//==============================================================================
int main()
{
TMP05_Init();
__enable_interrupt();
for(;;)
{
TMP05_Measure();
LCD_Redraw();
delay_ms(500);
}
}
Управляющий контроллер - ATmega324P. Кварц 20 МГц.
В функции LCD_Redraw() вывожу на ЖКИ значения
T_high, T_low, Temperature.
Судя по даташиту TMP05
T_high должно быть меньше
T_low и быть неизменным по температуре... В общем, что не так, ребята?!!