|
DS18B20 + ATMEGA8 |
|
|
|
Dec 14 2013, 08:43
|
Группа: Участник
Сообщений: 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
|
|
|
|
|
Dec 14 2013, 10:37
|
Группа: Участник
Сообщений: 12
Регистрация: 1-04-12
Пользователь №: 71 126

|
За слово плохое прошу прощения. Торопился когда писал и не заметил. А по существу предложения есть?
|
|
|
|
|
Dec 14 2013, 11:32
|
Группа: Участник
Сообщений: 12
Регистрация: 1-04-12
Пользователь №: 71 126

|
Дык у меня какмраз родная библиотека и используется(выше я давал ссылку на архив с проектом cvavr и протеуса). А что-за времянки?
|
|
|
|
|
Dec 14 2013, 13:36
|
Группа: Участник
Сообщений: 12
Регистрация: 1-04-12
Пользователь №: 71 126

|
Кварца нет впаянного. Используется внутренний на 4 МГц (фьюзами выставлен разумеется). Питание не паразитное. Резистор имеется, без него датчик бы вообще не опазнался. И о каких прерываниях идёт речь? Стандартная библиотека чтоли их использует?
|
|
|
|
|
Dec 14 2013, 14:23
|
Гуру
     
Группа: Свой
Сообщений: 5 273
Регистрация: 30-03-10
Пользователь №: 56 295

|
Цитата(mempfis_ @ Dec 14 2013, 16:54)  Откалибруйте тогда тактовый генератор, если Вы это ещё не сделали. И приготовьтесь к тому, что его частота крепко плывет с изменением температуры, посему сбои почти наверняка будут повторяться. Впаяйте кварц и не мучайтесь. Цитата(isx @ Dec 14 2013, 16:36)  И о каких прерываниях идёт речь? Если ваша программа не использует прерываний, то дело не в них. Вот если бы использовала, например, от таймера, тогда было бы сложнее ...
|
|
|
|
|
Dec 14 2013, 16:34
|
Группа: Участник
Сообщений: 12
Регистрация: 1-04-12
Пользователь №: 71 126

|
Дык протеус на это не отреагировал бы....
|
|
|
|
|
Dec 14 2013, 17:15
|

Профессионал
    
Группа: Свой
Сообщений: 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 младших бита определяют доли градуса, а все остальные биты - градусы.
|
|
|
|
|
Dec 15 2013, 11:48
|
Группа: Участник
Сообщений: 12
Регистрация: 1-04-12
Пользователь №: 71 126

|
Сегодня гонял собранную в железе схему. За 2 часа глюков не было. Теперь вот только решить проблему с миганием индикатора. Как я понимаю, пока выполняется преобразование МК висит в delay все 350мс., отсюда и мигание. Можно ли переделать задержку с delay на программный таймер? По поводу кода. Спасибо конечно, но я вообще там не понимаю что происходит  По поводу float. Если оставить int, то дробная часть отсекается... Библиотека походу формирует готовое число с дробной частью.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|