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

ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Вс сен 08, 2013 20:01:35
andrey_ims
Всем привет!

Собрал измеритель температуры с использованием ATiny2313 и ds18b20.
По обращению через UART контроллер опрашивает ds18b20 и возвращает значение UARTу. Отделение целой части температуры от дробной происходит уже на сервере.
В основном, измерение происходит корректно, но где-то 1 из 10 замеров возвращает температуру "-1.9". Никак не могу понять в чем дело, насколько я понял ds18b20 или работает правильно или вообще не работает. Откуда это -1.9? Еще,очень редко, бывает -625.0

Код обращения к датчику:

Код: Выделить всё

#include <tiny2313.h>
#include <delay.h>
#include <string.h> 
#include <stdlib.h>    
#include <1wire.h>
#include "ds18x20_v2.h"
...
int get_temperature(){   
    int temperature = -1; 
    if (w1_init() > 0) { 
        temperature = ds18b20_temperature(0); 
        if (temperature > 1000){               
            temperature=(-1)*4096-temperature;            
        }                          
   }         
   return temperature; 
}
...
Полный код

Схема
СпойлерИзображение

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Пн сен 09, 2013 09:25:07
Gudd-Head
andrey_ims писал(а):Еще,очень редко, бывает -625.0
Датчик физически не может столько выдать:
Изображение
Вывод: код-говно.

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Пн сен 09, 2013 10:15:10
Vov123
Мне кажется ответ нужно искать как в схемном решении,так и в библиотеке

Код: Выделить всё

#include "ds18x20_v2.h"

содержимое которой известно только Вам.

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Пн сен 09, 2013 17:43:55
andrey_ims
Vov123 писал(а): содержимое которой известно только Вам.
Увы мне ее содержимое не известно, я ее в где-то скачал

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Пн сен 09, 2013 18:18:38
Garin
Вот содержимое

Код: Выделить всё

/*
  CodeVisionAVR C Compiler
*/
#ifndef _DS18X20_INCLUDED_
#define _DS18X20_INCLUDED_
#include <1wire.h>
//-------------------------------------------------
#define DS18S20_FAMILY_CODE 0x10
#define DS18S20_SEARCH_ROM_CMD 0xf0
#define DS18S20_ALARM_SEARCH_CMD 0xec
//-------------------------------------------------
#define DS18B20_FAMILY_CODE 0x28
#define DS18B20_SEARCH_ROM_CMD 0xf0
#define DS18B20_ALARM_SEARCH_CMD 0xec
//-------------------------------------------------
#define DS18B20_9BIT_RES 0  // 9 bit thermometer resolution
#define DS18B20_10BIT_RES 1 // 10 bit thermometer resolution
#define DS18B20_11BIT_RES 2 // 11 bit thermometer resolution
#define DS18B20_12BIT_RES 3 // 12 bit thermometer resolution
//-------------------------------------------------
#pragma used+
//-------------------------------------------------
extern struct __ds18x20_scratch_pad_struct
       {
       unsigned char temp_lsb,temp_msb,
                temp_high,temp_low,
                conf_register,
                x1,
                x2,
                x3,
                crc;
       } __ds18x20_scratch_pad;
//-------------------------------------------------
//-------------------------------------------------
unsigned char ds18x20_select(unsigned char *addr);
unsigned char ds18x20_read_spd(unsigned char *addr);
//-------------------------------------------------
//-------------------------------------------------
int ds18s20_temperature(unsigned char *addr);
int ds18b20_temperature(unsigned char *addr);
//-------------------------------------------------
#pragma used-
#pragma library ds18x20_v2.lib
#endif

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Вт сен 10, 2013 09:51:58
urry
это ничего не дает.
#pragma library ds18x20_v2.lib - вещь в себе, монопольно захватывает ресурсы контроллера. Включая прерывания - по фигу, таймер, уарт, тем самым вы вмешиваетесь в его работу, нарушая времянки выдачи и приема бита.
Признаком являются варнинги протеуса на то, что выдан код, который он не может распознать - должна быть выдана "1", скажем, это 7 микросекунд, в это время прошло прерывание, вернулось - и у нас уже 15 микросекунд натикало. И выдался "0".
Лечение одно - самому написать библиотеку, в которой на выдачу "1" и прием бита запрещать прерывания - в первом случае - микросекунд 7, во втором - 15. Это не больно.
зы Посмотрел код.
Шокирован.

Код: Выделить всё

interrupt [EXT_INT0] void ext_int0_isr(void)

        blink6(50);
    // Antichatter
    delay_ms(100);
    
Никогда не ставьте задержку в прерываниях. Прерывание должно быть коротким, как тост.

Код: Выделить всё

interrupt [USART_RXC] void usart_rx_isr(void)
{
    #asm("cli");
не нужно здесь запрещать прерывания, они и так уже запрещены, когда вы туда вошли. Последняя команда возврата из прерывания их разрешает, компилятор эту работу делает самостоятельно, не нужно ему помогать.

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Вт сен 10, 2013 10:47:39
Vov123
Судя по заголовкам компилятор CVAVR,почему не взять его библу?Там вроде всё просто.

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Вт сен 10, 2013 20:24:53
andrey_ims
Vov123 писал(а):Судя по заголовкам компилятор CVAVR,почему не взять его библу?Там вроде всё просто.
Пробовал, не влезло в память

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Чт сен 12, 2013 00:00:22
andrey_ims
urry писал(а):это ничего не дает.
#pragma library ds18x20_v2.lib - вещь в себе, монопольно захватывает ресурсы контроллера. Включая прерывания - по фигу, таймер, уарт, тем самым вы вмешиваетесь в его работу, нарушая времянки выдачи и приема бита.
Признаком являются варнинги протеуса на то, что выдан код, который он не может распознать - должна быть выдана "1", скажем, это 7 микросекунд, в это время прошло прерывание, вернулось - и у нас уже 15 микросекунд натикало. И выдался "0".
Лечение одно - самому написать библиотеку, в которой на выдачу "1" и прием бита запрещать прерывания - в первом случае - микросекунд 7, во втором - 15. Это не больно.
зы Посмотрел код.
Шокирован.

Код: Выделить всё

interrupt [EXT_INT0] void ext_int0_isr(void)

        blink6(50);
    // Antichatter
    delay_ms(100);
    
Никогда не ставьте задержку в прерываниях. Прерывание должно быть коротким, как тост.

Код: Выделить всё

interrupt [USART_RXC] void usart_rx_isr(void)
{
    #asm("cli");
не нужно здесь запрещать прерывания, они и так уже запрещены, когда вы туда вошли. Последняя команда возврата из прерывания их разрешает, компилятор эту работу делает самостоятельно, не нужно ему помогать.
Спасибо! Не знаю с какого перепугу я это написал))

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Чт сен 12, 2013 22:01:52
andrey_ims
А кто может подсказать, почему объявленные у меня в проге unsigned long int electricCounter = 0 переполняется как обычный int(32768)?

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Пт сен 13, 2013 07:02:35
urry
попробуйте signed long .
Это было одной из причин, почему я не пишу на кодевижин. :) Вторая - что-то с юнионами намучено было.

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Пт сен 13, 2013 09:53:50
andrey_ims
urry писал(а):попробуйте signed long .
Увы, не помогло

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Пт сен 13, 2013 10:00:22
C@at
Глючный компилятор?

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Пт сен 13, 2013 10:21:07
andrey_ims
Та как бы это не ограничение плохо крякнутой программы

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Пт сен 13, 2013 10:29:35
Vov123
А может параметр функции itoa идет всего лишь как signed int?

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Пт сен 13, 2013 10:38:40
Аlex
urry писал(а):попробуйте signed long . Это было одной из причин, почему я не пишу на кодевижин. :)
Кстати, это проблема протеуса. Беззнаковый long он показывает как int. Достаточно объявить переменную знаковой, и она в протеусе начинает видиться нормально. Хотя компиляторы, не смотря на то, что протеус врёт, работают с переменной нормально.
andrey_ims писал(а):А кто может подсказать, почему объявленные у меня в проге unsigned long int electricCounter = 0 переполняется как обычный int(32768)?
long не может никак переполняться после 32768, т.к. её размер = 4 байта. Это всего-лишь иллюзия.

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Пт сен 13, 2013 10:40:50
andrey_ims
andrey_ims писал(а):А кто может подсказать, почему объявленные у меня в проге unsigned long int electricCounter = 0 переполняется как обычный int(32768)?
long не может никак переполняться после 32768, т.к. её размер = 4 байта. Это всего-лишь иллюзия.[/quote]

Ну вот эта вот иллюзия, в железе, считает до 32768, а потом начинает выдавать -32768 итд

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Пт сен 13, 2013 10:45:10
Аlex
начинает выдавать -32768 итд
Куда выдавать, откуда, где код ?
Перестаньте говорить тайнами, прикрепляйте свои слова фактами, кодом, подробными объяснениями, и т.д...

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Пт сен 13, 2013 10:47:44
andrey_ims

Re: ATiny2313+ds18b20 ошибка при измерении температуры

Добавлено: Пт сен 13, 2013 10:49:12
andrey_ims
Vov123 писал(а):А может параметр функции itoa идет всего лишь как signed int?
Кстати да, исправил на ltoa, но все равно не помогло