реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> DS18B20 + ATMEGA8
isx
сообщение Dec 14 2013, 08:43
Сообщение #1





Группа: Участник
Сообщений: 12
Регистрация: 1-04-12
Пользователь №: 71 126



Здравствуйте! Помогмте пожалуйста с датчиком температуры. Что то не так с этой хернёй у меня...
Вот сделал проект в CVAVR и протеусе. Как видите, там единственная строка, и та работает с ошибкой. В протеусе выставляю температуру 20
градусов, и делаю проверку (если температура не равна 20, то PORTB.4 = 1)
С какого то чёрта значение температуры в один момент резко сглюкивает (раньше был у меня дисплей в проекте, он показывал в этот момент
хрень какую-то, а потом сразу значение температуры восстанавливалось). Убрал из кода всё пока искал в чём косяк. Косяк в строчке где присваивается значение переменной temper (больше там и ничего не осталось ) Кварц сделал 4МГц, как в хелпе на библиотеку - не помогло. Посмотрите пожалуйста свойства проекта и правильность использования библиотеки, ато я впервые с датчиком работаю этим, и уже часов 6 не могу причину найти.... Светодиод загорится не сразу. Нужно время от 1 до 5мин. Процесс ускоряется, если к любой ноге порта В подключить светодиод, катодом к
пину.

Файл проекта. Залить не могу на форум, та как с телефона сижу, поэтому ссылка(
radiokot.ru/forum/download/file.php?id=169462
Go to the top of the page
 
+Quote Post
domowoj
сообщение Dec 14 2013, 09:58
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1 548
Регистрация: 20-12-07
Из: г.Новосибирск
Пользователь №: 33 486



Цитата(isx @ Dec 14 2013, 15:43) *
Помогмте пожалуйста с датчиком температуры. Что то не так с этой хернёй у меня...

Если у вас с языками программирования так же как и с русским(не русским матерным),
то не мудрено.


--------------------
И на камнях растут деревья!
Go to the top of the page
 
+Quote Post
Abell
сообщение Dec 14 2013, 10:08
Сообщение #3


профессиональный дилетант
****

Группа: Участник
Сообщений: 866
Регистрация: 16-03-06
Из: Шебекино - Лысьва - Тюмень
Пользователь №: 15 292



Почитайте книгу хорошую, что-то типа "Микроконтроллеры AVR: от простого к сложному", "Микроконтроллеры AVR семейств Tiny и Mega фирмы Atmel", а для начала неплохо бы "Электроника - шаг за шагом" sm.gif
А так - "Учиться, учиться и учиться" (с) В.И.Ленин


--------------------
Скоро дело сказывается, да не скоро сказка делается, или тише будешь - дальше уедешь...

Go to the top of the page
 
+Quote Post
isx
сообщение Dec 14 2013, 10:37
Сообщение #4





Группа: Участник
Сообщений: 12
Регистрация: 1-04-12
Пользователь №: 71 126



За слово плохое прошу прощения. Торопился когда писал и не заметил.
А по существу предложения есть?
Go to the top of the page
 
+Quote Post
kovigor
сообщение Dec 14 2013, 11:21
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(isx @ Dec 14 2013, 13:37) *
А по существу предложения есть?

Есть. Протеус - в сторону. Похоже на то, что от датчика приходит битый пакет с неправильным CRC, а ваша программа к этой ситуации не готова.
В CodeVision есть библиотека, которая поддерживает этот датчик. С ней все делается за один вечер ...
Go to the top of the page
 
+Quote Post
domowoj
сообщение Dec 14 2013, 11:27
Сообщение #6


Профессионал
*****

Группа: Участник
Сообщений: 1 548
Регистрация: 20-12-07
Из: г.Новосибирск
Пользователь №: 33 486



И проверьте времянки.

Сообщение отредактировал domowoj - Dec 14 2013, 11:28


--------------------
И на камнях растут деревья!
Go to the top of the page
 
+Quote Post
kovigor
сообщение Dec 14 2013, 11:29
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(domowoj @ Dec 14 2013, 14:27) *
И проверьте времянки.

И прерывания надо бы запрещать на время обращения к датчику ...
Go to the top of the page
 
+Quote Post
isx
сообщение Dec 14 2013, 11:32
Сообщение #8





Группа: Участник
Сообщений: 12
Регистрация: 1-04-12
Пользователь №: 71 126



Дык у меня какмраз родная библиотека и используется(выше я давал ссылку на архив с проектом cvavr и протеуса).
А что-за времянки?
Go to the top of the page
 
+Quote Post
kovigor
сообщение Dec 14 2013, 11:45
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(isx @ Dec 14 2013, 14:32) *
Дык у меня какмраз родная библиотека и используется ...
А что-за времянки?

Тогда временные диаграммы должны быть корректными, если вы впаяли кварц, на который рассчитан проект, и фьюзами не задали никаких делителей.
Остается одно - запрещать прерывания, как я только что писал.
И еще, подтяните линию данных датчика к питанию резистором на 4.7К. Питание, надеюсь, не паразитное ?
Go to the top of the page
 
+Quote Post
isx
сообщение Dec 14 2013, 13:36
Сообщение #10





Группа: Участник
Сообщений: 12
Регистрация: 1-04-12
Пользователь №: 71 126



Кварца нет впаянного. Используется внутренний на 4 МГц (фьюзами выставлен разумеется). Питание не паразитное. Резистор имеется, без него датчик бы вообще не опазнался.
И о каких прерываниях идёт речь? Стандартная библиотека чтоли их использует?
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Dec 14 2013, 13:54
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(isx @ Dec 14 2013, 17:36) *
Кварца нет впаянного. Используется внутренний на 4 МГц (фьюзами выставлен разумеется).


Откалибруйте тогда тактовый генератор, если Вы это ещё не сделали. По старту программы в OSCCAL заносятся калибровочные константы для выбранной частоты RC-цепочки.
Go to the top of the page
 
+Quote Post
kovigor
сообщение Dec 14 2013, 14:23
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295



Цитата(mempfis_ @ Dec 14 2013, 16:54) *
Откалибруйте тогда тактовый генератор, если Вы это ещё не сделали.

И приготовьтесь к тому, что его частота крепко плывет с изменением температуры, посему сбои почти наверняка будут повторяться. Впаяйте кварц и не мучайтесь.


Цитата(isx @ Dec 14 2013, 16:36) *
И о каких прерываниях идёт речь?

Если ваша программа не использует прерываний, то дело не в них. Вот если бы использовала, например, от таймера, тогда было бы сложнее ...
Go to the top of the page
 
+Quote Post
isx
сообщение Dec 14 2013, 16:34
Сообщение #13





Группа: Участник
Сообщений: 12
Регистрация: 1-04-12
Пользователь №: 71 126



Дык протеус на это не отреагировал бы....
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Dec 14 2013, 17:15
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(isx @ Dec 14 2013, 19:34) *
Дык протеус на это не отреагировал бы....


Знать бы что происходит в процедурах w1_init(), ds18b20_init( 0, -50, 60, DS18B20_10BIT_RES ) и ds18b20_temperature( 0 );
Например для того, чтобы прочитать температуру, предварительно нужно подать команду CONVERT_TEMP и выждать время конвертирования, и только потом можно читать.
Касательно AVR - на нём очень легко самостоятельно реализовать поддержку 1-wire.
Посмотрите как это реализовано в одной из моих программ. В ней правда нет чтения температуры, но зато есть всё, чтобы самостоятельно ввести его.

CODE
#ifndef _1wire_h
#define _1wire_h

#define BUF_SIZE 16
#define MASK (BUF_SIZE-1)

// Message "Error CRC" == -77.7
#define ERROR_CRC -(77<<4)// 0xFB25//175
//Location 1 Wire Net in PORTE B pin 0.
#define OW_PIN PINB
#define OW_DDR DDRB
#define OW_PORT PORTB

#define OW_DQ_1 PINB0


// 1 Wire Commands
#define WRITE_ROM 0x4e
#define COPY_ROM_TO_EE 0x48
#define SKIP_ROM 0xCC
#define MATCH_ROM 0x55
#define CONVERT_T 0x44
#define READ_SCRATCHPAD 0xBE
#define WRITE_SCRATCHPAD 0x4E


//--------------------------------------------
//таблица уонстант для записи в термодатчик
__flash unsigned char sens_val[5][3] =
{
{0, 172, 127},
{1, 157, 127},
{2, 206, 127},
{3, 255, 127},
{4, 104, 127}
};
//--------------------------------------------

#endif //_1wire_h


CODE
//--------------------------------------------
//Вычисляет CRC8
unsigned char OW_ComputeCRC8(unsigned char inData, unsigned char seed)
{
unsigned char bitsLeft;
unsigned char temp;

for (bitsLeft = 8; bitsLeft > 0; bitsLeft--)
{
temp = ((seed ^ inData) & 0x01);
if (temp == 0)
{
seed >>= 1;
}
else
{
seed ^= 0x18;
seed >>= 1;
seed |= 0x80;
}
inData >>= 1;
}
return seed;
}
//--------------------------------------------

//--------------------------------------------
//Сброс шины 1-wire: 2 таймслота 480мкс - мастер тянет шину вниз (RESET PULSE)
//480 мкс - датчик тянет шину вниз (присутствие на шине)
unsigned char OW_reset(void)
{
unsigned char answer;
//формируем RESET PULSE
OW_PORT &= ~(1<<OW_DQ_1); //set PORT in 0
OW_DDR |= (1<<OW_DQ_1); //set DDR in 1
//удерживаем 480 мкс
delay_us(240);
delay_us(240);

//переводим линию DQ на вход с подтяжкой
OW_PORT |= (1<<OW_DQ_1); //set PORT in 1
OW_DDR &=~(1<<OW_DQ_1); //set DDR in 0
//установление pull-up + установление состояния шины термодатчиком
delay_us(100);

//считываем состояние линии DQ
answer = (OW_PIN & (1<<OW_DQ_1));

// выжидаем время необходимое для завершения операции
delay_us(190);
delay_us(190);
return (answer&(1<<OW_DQ_1)); //0-есть устройства, 1-нет устройств

}
//--------------------------------------------

//--------------------------------------------
//Запись бита
void OW_write_bit(unsigned char bit)
{
//формируем 0 (START OF SLOT)
OW_PORT &= ~(1<<OW_DQ_1); //set PORT in 0
OW_DDR |= (1<<OW_DQ_1); //set DDR in 1
delay_us(10);

//устанавливаем состояние выхода
if(bit)
{
//формируем 1
OW_PORT |= (1<<OW_DQ_1); //set PORT in 0
}
else
{
//формируем 0
OW_PORT &= ~(1<<OW_DQ_1); //set PORT in 1
}

//время захвата данных термодатчиком
delay_us(45);

//переводим линию DQ на вход с подтяжкой
OW_PORT |= (1<<OW_DQ_1); //set PORT in 1
OW_DDR &=~(1<<OW_DQ_1); //set DDR in 0

}
//--------------------------------------------


//--------------------------------------------
//Чтение бита
unsigned char OW_read_bit()
{

unsigned char result;

//формируем 0 (START OF SLOT)
OW_PORT &= ~(1<<OW_DQ_1); //set PORT in 0
OW_DDR |= (1<<OW_DQ_1); //set DDR in 1
//задержка на
delay_us(2);

//переводим линию DQ на вход с подтяжкой
OW_PORT |= (1<<OW_DQ_1); //set PORT in 1
OW_DDR &=~(1<<OW_DQ_1); //set DDR in 0
//ожидаем установление данных
delay_us(10);

//захват данных с шины
result = (OW_PIN & (1<<OW_DQ_1));



//время ожидания завершения операции
delay_us(45);
return(result);


}
//--------------------------------------------

//Запись байта
void OW_write_byte(unsigned char command)
{
for (unsigned char i = 0; i < 8; i++)
{
OW_write_bit(command & 0x01); //send one bit
command >>= 1; //shift to next bit
}
//__delay_cycles(0.00012*F_CLK);
//delay_us(120);
}
//--------------------------------------------

//--------------------------------------------
//Чтение байта
unsigned char OW_read_byte()
{
unsigned char i;
unsigned char value = 0;
/*~~~~~~~~~~~~~~~~~~~~~~*/

for(i = 0; i < 8; i++)
{
if(OW_read_bit()) value |= 0x01 << i;/* читаем один бит и записываем его в разряд i */

/* ожидаем окончания временного интервала */
//__delay_cycles(F_CLK*0.00012);
//delay_us(120);

}

return(value);

}
//--------------------------------------------



//--------------------------------------------
//Чтение Scratchpad
unsigned char ReadScratchpad(unsigned char* scratchpad)
{
unsigned char crc = 0;

// initiate array to 0
for (unsigned char a1 = 0; a1 < 9; a1++) scratchpad[a1] = 0;


OW_reset();
OW_write_byte(SKIP_ROM); // skip ROM
OW_write_byte(READ_SCRATCHPAD); // read scratchpad 0xBE

//Recive data in 1 Wire
for (unsigned char c1 = 0; c1 < 9; c1++)
{
scratchpad[c1] = OW_read_byte();
}

//Check CRC8 to 1 Wire data
for(unsigned char i = 0; i < 8; i++)
{
crc = OW_ComputeCRC8(scratchpad[i], crc);
}

if (crc == scratchpad[8])
{
return 1;
}
else
{
return 0;
}

}
//--------------------------------------------

//--------------------------------------------
//запись данных в сенсор
unsigned char writeTsens(unsigned char index)
{

//запись данных в сенсор
OW_reset();
OW_write_byte(SKIP_ROM); // skip ROM
OW_write_byte(WRITE_SCRATCHPAD); // write scratchpad 0xBE
OW_write_byte(sens_val[index][0]); // нижний триггер
OW_write_byte(sens_val[index][1]); // верхний триггер
OW_write_byte(sens_val[index][2]); // разрешение 9 бит

OW_reset();
OW_write_byte(SKIP_ROM); // skip ROM
OW_write_byte(COPY_ROM_TO_EE);


//верификация записи
unsigned char buff[9];

if(ReadScratchpad(buff) != 0)
{
//данные считаны корректно

//проверям реальные данные
if(buff[2] != sens_val[index][0]) return 0; //ошибка соответствия
if(buff[3] != sens_val[index][1]) return 0; //ошибка соответствия
if(buff[4] != sens_val[index][2]) return 0; //ошибка соответствия

return 1; //полное совпадение данныех
}

return 0;
}
//--------------------------------------------


Кстати temper в вашей программе float. Я не знаю в каком виде возвращает температуру ds18b20_temperature, но от самого датчика она приходит как знаковое число, в котором 4 младших бита определяют доли градуса, а все остальные биты - градусы.
Go to the top of the page
 
+Quote Post
isx
сообщение Dec 15 2013, 11:48
Сообщение #15





Группа: Участник
Сообщений: 12
Регистрация: 1-04-12
Пользователь №: 71 126



Сегодня гонял собранную в железе схему. За 2 часа глюков не было. Теперь вот только решить проблему с миганием индикатора.
Как я понимаю, пока выполняется преобразование МК висит в delay все 350мс., отсюда и мигание. Можно ли переделать задержку с delay на программный таймер?
По поводу кода. Спасибо конечно, но я вообще там не понимаю что происходит sad.gif
По поводу float. Если оставить int, то дробная часть отсекается... Библиотека походу формирует готовое число с дробной частью.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 6th July 2025 - 15:14
Рейтинг@Mail.ru


Страница сгенерированна за 0.01506 секунд с 7
ELECTRONIX ©2004-2016