(x-115)*4/10 - (при нуле градусов датчик дает 500мВ) - получаю значение температуры в градусах. В протеусе работает, но выдает ошибку в 1-3 градуса, чем больше температура тем больше ошибка. Как я понимаю ошибка эта возникает за-за того, что умножаю на 4, а не на 4.3.
Что скажете в целом по схеме и программе? И будет ли все это работать от источника в 3 вольта?
Нажмите для просмотра прикрепленного файла
CODE
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#define _0 0b11111100 // 0 на индикаторе
#define _1 0b01100000 // 1 на индикаторе
#define _2 0b11011010 // 2 на индикаторе
#define _3 0b11110010 // 3 на индикаторе
#define _4 0b01100110 // 4 на индикаторе
#define _5 0b10110110 // 5 на индикаторе
#define _6 0b10111110 // 6 на индикаторе
#define _7 0b11100000 // 7 на индикаторе
#define _8 0b11111110 // 8 на индикаторе
#define _9 0b11110110 // 9 на индикаторе
#define ADC_start() ADCSRA|=(1<<6)
#define dig_1_off() PORTB|=(1<<4) //выключение 1 элемента индикатора
#define dig_1_on() PORTB&=(~(1<<4)) //включение 1 элемента индикатора
#define dig_2_off() PORTB|=(1<<0) //выключение 2 элемента индикатора
#define dig_2_on() PORTB&=(~(1<<0)) //включение 2 элемента индикатора
#define strob_h() PORTB|=(1<<1) //строб на регистр в 1
#define strob_l() PORTB&=(~(1<<1)) //строб на регистр в 0
static unsigned char temperature_dig_h=0;
static unsigned char temperature_dig_l=0;
ISR(ADC_vect)
{
volatile unsigned char temp=0,temp_h=0,temp_l=0;
temp=ADCH-115; //из полученного значения вычли значение при 0 градусов
if (temp>=17) temp++;
if (temp>=24) temp++;
if (temp>=31) temp++;
if (temp>=38) temp++;
if (temp>=50) temp++;
if (temp>=60) temp++;
temp=(temp*4)/10; //умножаем на шаг преобр. ацп (~4мВ) и делим на шаг преобр. датчика (10мВ/градус)
temp_h=temp/10;
temp_l=temp-(temp_h*10);
switch (temp_h)
{
case 0: temperature_dig_h=_0; break;
case 1: temperature_dig_h=_1; break;
case 2: temperature_dig_h=_2; break;
case 3: temperature_dig_h=_3; break;
case 4: temperature_dig_h=_4; break;
case 5: temperature_dig_h=_5; break;
case 6: temperature_dig_h=_6; break;
break;
}
switch (temp_l)
{
case 0: temperature_dig_l=_0; break;
case 1: temperature_dig_l=_1; break;
case 2: temperature_dig_l=_2; break;
case 3: temperature_dig_l=_3; break;
case 4: temperature_dig_l=_4; break;
case 5: temperature_dig_l=_5; break;
case 6: temperature_dig_l=_6; break;
case 7: temperature_dig_l=_7; break;
case 8: temperature_dig_l=_8; break;
case 9: temperature_dig_l=_9; break;
break;
}
}
int main(void)
{
//Начальная инициализация
//Инициализация АЦП
ADCSRA=0b11101110; //включение ацп, режим однократного преобразования, разрешение прерывания от ацп,
ADCSRB=0b00000000; //частота преобразования clk/128=9.6MHz/128=75KHz
ADMUX=0b01100011; //опорное напряжение - внутренний ИОН 1.1В, рез-т выравнивается влево, вх. канал - ADC3
//Настройка ввода/вывода
DDRB=0b00010111;
sei();
_delay_us(100);
cli();
while(1)
{
//вывод данных на 7-сегм. индикаторы. сначала выводится старшая цифра, затем младшая
//*****
for (unsigned char counter=1; counter!=0; counter=counter<<1 )
{
if ((temperature_dig_h & counter)==0)
PORTB&=(~(1<<2));
else
PORTB|=(1<<2);
strob_h();
_delay_us(1);
strob_l();
}
dig_1_on(); //активирована 1 цифра
//sei();
_delay_us(100);
//cli();
dig_1_off();
for (unsigned char counter=1; counter!=0; counter=counter<<1 )
{
if ((temperature_dig_l & counter)==0)
PORTB&=(~(1<<2));
else
PORTB|=(1<<2);
strob_h();
_delay_us(10);
strob_l();
}
dig_2_on();
sei();
_delay_us(100);
dig_2_off();
cli();
//*****
}
}
#include <avr/interrupt.h>
#include <avr/delay.h>
#define _0 0b11111100 // 0 на индикаторе
#define _1 0b01100000 // 1 на индикаторе
#define _2 0b11011010 // 2 на индикаторе
#define _3 0b11110010 // 3 на индикаторе
#define _4 0b01100110 // 4 на индикаторе
#define _5 0b10110110 // 5 на индикаторе
#define _6 0b10111110 // 6 на индикаторе
#define _7 0b11100000 // 7 на индикаторе
#define _8 0b11111110 // 8 на индикаторе
#define _9 0b11110110 // 9 на индикаторе
#define ADC_start() ADCSRA|=(1<<6)
#define dig_1_off() PORTB|=(1<<4) //выключение 1 элемента индикатора
#define dig_1_on() PORTB&=(~(1<<4)) //включение 1 элемента индикатора
#define dig_2_off() PORTB|=(1<<0) //выключение 2 элемента индикатора
#define dig_2_on() PORTB&=(~(1<<0)) //включение 2 элемента индикатора
#define strob_h() PORTB|=(1<<1) //строб на регистр в 1
#define strob_l() PORTB&=(~(1<<1)) //строб на регистр в 0
static unsigned char temperature_dig_h=0;
static unsigned char temperature_dig_l=0;
ISR(ADC_vect)
{
volatile unsigned char temp=0,temp_h=0,temp_l=0;
temp=ADCH-115; //из полученного значения вычли значение при 0 градусов
if (temp>=17) temp++;
if (temp>=24) temp++;
if (temp>=31) temp++;
if (temp>=38) temp++;
if (temp>=50) temp++;
if (temp>=60) temp++;
temp=(temp*4)/10; //умножаем на шаг преобр. ацп (~4мВ) и делим на шаг преобр. датчика (10мВ/градус)
temp_h=temp/10;
temp_l=temp-(temp_h*10);
switch (temp_h)
{
case 0: temperature_dig_h=_0; break;
case 1: temperature_dig_h=_1; break;
case 2: temperature_dig_h=_2; break;
case 3: temperature_dig_h=_3; break;
case 4: temperature_dig_h=_4; break;
case 5: temperature_dig_h=_5; break;
case 6: temperature_dig_h=_6; break;
break;
}
switch (temp_l)
{
case 0: temperature_dig_l=_0; break;
case 1: temperature_dig_l=_1; break;
case 2: temperature_dig_l=_2; break;
case 3: temperature_dig_l=_3; break;
case 4: temperature_dig_l=_4; break;
case 5: temperature_dig_l=_5; break;
case 6: temperature_dig_l=_6; break;
case 7: temperature_dig_l=_7; break;
case 8: temperature_dig_l=_8; break;
case 9: temperature_dig_l=_9; break;
break;
}
}
int main(void)
{
//Начальная инициализация
//Инициализация АЦП
ADCSRA=0b11101110; //включение ацп, режим однократного преобразования, разрешение прерывания от ацп,
ADCSRB=0b00000000; //частота преобразования clk/128=9.6MHz/128=75KHz
ADMUX=0b01100011; //опорное напряжение - внутренний ИОН 1.1В, рез-т выравнивается влево, вх. канал - ADC3
//Настройка ввода/вывода
DDRB=0b00010111;
sei();
_delay_us(100);
cli();
while(1)
{
//вывод данных на 7-сегм. индикаторы. сначала выводится старшая цифра, затем младшая
//*****
for (unsigned char counter=1; counter!=0; counter=counter<<1 )
{
if ((temperature_dig_h & counter)==0)
PORTB&=(~(1<<2));
else
PORTB|=(1<<2);
strob_h();
_delay_us(1);
strob_l();
}
dig_1_on(); //активирована 1 цифра
//sei();
_delay_us(100);
//cli();
dig_1_off();
for (unsigned char counter=1; counter!=0; counter=counter<<1 )
{
if ((temperature_dig_l & counter)==0)
PORTB&=(~(1<<2));
else
PORTB|=(1<<2);
strob_h();
_delay_us(10);
strob_l();
}
dig_2_on();
sei();
_delay_us(100);
dig_2_off();
cli();
//*****
}
}