Страница 1 из 1

attiny2313+ds18b20 завышает показания

Добавлено: Вт мар 04, 2014 17:01:06
afen
attiny2313 и ds18b20 показания температуры при выводе на индикатор завышает градусов на 10, программа в CodeVision, прошиваю с помощью arduinoISP командой
avrdude -p t2313 -P COM4 -c avrisp -b 19200 -U flash:w:aquaterm3.hex
на табло вижу 36 грд вместо ожидаемых 25-26 грд при нагревании рукой температура растет градусов до 47 а потом начинаются скачки 54, 65
ds18b20 иправен пробовал подключать к ардуине все работает норм

!!!!!Может кто подскажет в чем дело и в какую сторону копать!!!!!!

ЗЫ в Протеусе прошика работает нормально

Исходник: (код не весь мой части касаемые ds18b20 надерганы с инета)
#define F_CPU 1000000UL // частота синхронизации микроконтроллера 1МГц

#include <delay.h>
#include <tiny2313.h>
#include <1wire.h>

#define DQ 1

#define SKIP_ROM 0xCC
#define WRITE_SCRATCHPAD 0x4E
#define CONVERT_T 0x44
#define READ_SCRATCHPAD 0xBE

char CONFIG_REGISTER[] = {0x1F, 0x3F, 0x5F, 0x7F};
//------------------0---------------------2----------3---------4----------5------------6---------7--------8----------9----------E------------r
char digit[] = {0b00111111,0b00000110,0b01011011,0b01001111,0b011 00110,0b01101101,0b01111101,0b00000111,0b01111111, 0b01101111,0b01000000,0b01010000};
//char digit[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90 ,0b10000110,0b10101111}; //битовые маски для сегментов индикатора
char okDS18B20 = 0; //ошибка чтения датчика
int tempVal; //глобальная переменная для вывода цифры на дисплей
char maxTemp = 28; //максимальная температура в аквариуме
int secondHeaterOn = 0; //сколько секунд включен нагреватель
int maxSecondHeaterOn = 300; //300 секунд или 5 минут
volatile unsigned char segcounter = 0;


void WriteNumber(void);


interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0 = 0xA0;
WriteNumber();
}

void WriteNumber(void)
{
// Тушим
PORTD.5 = 1;
PORTD.6 = 1;
delay_us(10);
switch (segcounter){
case 0:
if ((tempVal / 10) == 0) PORTD.6 = 1; else
{
if (okDS18B20) PORTB = digit[10]; else //если ошибка выведем -
PORTB = digit[(tempVal / 10)];
PORTD.6 = 0;
}
break;
case 1:
if (okDS18B20) PORTB = digit[10]; else //если ошибка выведем -
PORTB = digit[(tempVal % 10)];
PORTD.5 = 0;
break;
}
segcounter++;
if (segcounter > 1) segcounter = 0;
}

/*** Инициализация DS18B20 ***/
unsigned char DS18B20_init(void){
PORTA &= ~(1 << DQ); // устанавливаем низкий уровень
DDRA |= (1 << DQ);
delay_us(490);
DDRA &= ~(1 << DQ);
delay_us(68);
okDS18B20 = (PINA & (1 << DQ)); // ловим импульс присутствия датчика
// если OK_Flag = 0 датчик подключен, OK_Flag = 1 датчик не подключен
delay_us(422);
return okDS18B20;
}
/*** Функция чтения байта из DS18B20 ***/
unsigned char read_18b20(void){
unsigned char i;
unsigned char dat = 0;
for(i = 0;i < 8;i++){
DDRA |= (1 << DQ);
delay_us(2);
DDRA &= ~(1 << DQ);
delay_us(4);
//dat = dat >> 1;
dat |= ((PINA & (1<<DQ))<<i); // Читаем бит
// if(PINA & (1 << DQ)){dat |= 0x80;}
delay_us(62);
}
return dat;
}
/*** функция записи байта в DS18B20 ***/
void write_18b20(unsigned char dat){
unsigned char i;
// for(i = 0;i < 8;i++){
// DDRA |= (1 << DQ);
// delay_us(2);
// if(dat & 0x01){DDRA &= ~(1 << DQ);}
// else {DDRA |= (1 << DQ);}
// dat = dat >> 1;
// delay_us(62);
// DDRA &= ~(1 << DQ);
// delay_us(2);
// }
#asm("cli");
for (i = 0; i < 8; i++)
{
if (dat & (1<<i))
{
DDRA |= (1<<DQ); // переводим линию в низкий уровень
delay_us(4); // Для записи лог1 нужно подождать больше 1мкс, но меньше 5мкс
DDRA &= ~(1<<DQ); // отпускаем линию, переводим пин в режим Hi-Z, линия возвращается на высокий уровень
}
else
{
DDRA |= (1<<DQ); // переводим линию в низкий уровень
delay_us(65); // Для записи лог0 нужно держать линию на низком уровне от 60 до 120 мкс
DDRA &= ~(1<<DQ); // отпускаем линию, переводим пин в режим Hi-Z, линия возвращается на высокий уровень
//DDRA |= (1<<DQ); // отпускаем линию, переводим пин в режим Hi-Z, линия возвращается на высокий уровень
}
}
#asm("sei");
}

unsigned char GetTemperature(){
unsigned char Temp_L,Temp_H;
unsigned int answer;
#asm("cli");
DS18B20_init(); // инициализация DS18B20
write_18b20(SKIP_ROM); //0xCC проверка кода датчика
write_18b20(CONVERT_T); //0x44 запуск температурного преобразования
#asm("sei");
delay_ms(1000);
#asm("cli");
DS18B20_init(); // инициализация DS18B20
write_18b20(SKIP_ROM); // 0xCC проверка кода датчика
write_18b20(READ_SCRATCHPAD); // 0xBE считываем содержимое ОЗУ
answer = read_18b20(); // LS BYTE
answer |= (read_18b20()<<8); // MS BYTE
// Temp_L = read_18b20(); // читаем первые 2 байта блокнота
// Temp_H = read_18b20();
#asm("sei");
// Temp_H = Temp_H << 4;
// Temp_L = Temp_L >> 4;
// return (Temp_H & 0xF0) | (Temp_L & 0xF);
return ((answer >> 4) & 0x7F); // Целая часть
//-----------------
//temp = ((answer >> 4) & 0x7F);// * 100; // Целая часть
//return ((Temp_H << 4) & 0x70)|(Temp_L >> 4); // вычисляем целое значение температуры
}






void main(void)
{
DDRB = 0xFF;
DDRD = 0xFF;
PORTB = 0x00;
PORTD = 0x00;

DDRA = 0x00;
PORTA = 0x00;

// Разрешаем прерывание для таймера 0
TIMSK = (1<<TOIE0);
// Устанавливаем начальное значение таймера 0
TCNT0 = 0xFF;
// Выбираем источник тактового сигнала для таймера 0
// Регистр TCCR0B имеет структуру 0,0,0,0,0,CS02,CS01,CS00
// От значений флагов CS02,CS01,CS00 зависит поведение таймера
// Примеры:
// CS02,CS01,CS00 = [0,0,0] -> таймер выключен
// CS02,CS01,CS00 = [0,0,1] -> тактовый сигнал МК
// CS02,CS01,CS00 = [0,1,0] -> предделитель равен 8
TCCR0B = (1<<CS01) | (1<<CS00);

#asm("sei"); //глобально разрешаем прерывания

//ConfigSensor(12);
while(1)
{
tempVal = GetTemperature();
// tempVal = 17;
// if (tempVal < maxTemp) {PORTD.4 = 1; secondHeaterOn++;} //включаем нагрев
// else {PORTD.4 = 0; secondHeaterOn = 0;} //выключаем нагрев
// if (secondHeaterOn > maxSecondHeaterOn) {PORTD.4 = 0; secondHeaterOn = 0;} //выключаем нагрев
PORTD.4 = ~PIND.4;
// delay_ms(1000);
// PORTD.4 = 0;
//delay_ms(1000);

}
}

Re: attiny2313+ds18b20 завышает показания

Добавлено: Вт мар 04, 2014 20:17:55
vem566
Ну разбираться в программе, честно говоря, лениво. У DS1820 есть особенность - саморазогрев. Его рекомендуют дергать не чаще, чем раз в две секунды. Чем реже, тем лучше. Кроме того, его местоположение заметно меняет показания. У меня стоял в корпусе часов на плате, но сам датчик торчал из корпуса. Превышение порядка 2 градуса. Вынес на метр - все нормально.

Re: attiny2313+ds18b20 завышает показания

Добавлено: Ср мар 05, 2014 20:51:42
codenamehawk
Проверь протеусом, узнаешь где ошибка.

Re: attiny2313+ds18b20 завышает показания

Добавлено: Ср мар 05, 2014 23:10:10
Аlex