ds18b20 выдает значение -9999.00 на lcd

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Сообщения: 7
Зарегистрирован: Вс апр 06, 2014 19:24:00

Сообщение ZEugene »

Доброго времени суток, форумчане!
Обращаюсь к Вам с просьбой помочь решить проблему - термодатчик ds18b20, подключенный к микроконтроллеру atmega168, выдает на жк значение -9999.00 при любой установленной температуре.
Подскажите, в чем может быть косяк? Я относительно недавно занимаюсь программированием контроллеров и, возможно, что-то упускаю из виду.
Спойлер

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

Chip type               : ATmega168
Program type            : Application
AVR Core Clock frequency: 20,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/

#include <mega168.h>

#include <delay.h>
// 1 Wire Bus interface functions
#include <1wire.h>

// DS1820 Temperature Sensor functions
#include <ds18b20.h>

// maximum number of DS1820 devices
// connected to the 1 Wire bus
#define MAX_DS18b20 1
// number of DS1820 devices
// connected to the 1 Wire bus
unsigned char ds18b20_devices;
// DS1820 devices ROM code storage area,
// 9 bytes are used for each device
// (see the w1_search function description in the help)
unsigned char ds18b20_rom_codes[MAX_DS18b20][9];

// Alphanumeric LCD functions
#include <alcd.h>

// Standard Input/Output functions
#include <stdio.h>
#include <stdlib.h>

// Declare your global variables here
//unsigned char i,j;
float temp;
char lcd_buf[17];
//unsigned char lcd_out;


void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2A output: Disconnected
// OC2B output: Disconnected
ASSR=0x00;
TCCR2A=0x00;
TCCR2B=0x00;
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=0x00;
EIMSK=0x00;
PCICR=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x00;

// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=0x00;

// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=0x00;


// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;
DIDR1=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=0x00;

// 1 Wire Bus initialization
// 1 Wire Data port: PORTC
// 1 Wire Data bit: 0
// Note: 1 Wire port settings are specified in the
// Project|Configure|C Compiler|Libraries|1 Wire menu.
w1_init();

ds18b20_devices=w1_search(0xf0,ds18b20_rom_codes);
// Determine the number of DS18b20 devices
// connected to the 1 Wire bus


// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTD Bit 3
// RD - PORTC Bit 5
// EN - PORTC Bit 4
// D4 - PORTC Bit 3
// D5 - PORTB Bit 3
// D6 - PORTB Bit 2
// D7 - PORTB Bit 1
// Characters/line: 16
lcd_init(16);
 
while(1)                 
      {   
          lcd_clear();
          temp=ds18b20_temperature(ds18b20_rom_codes[0][0]);
            
          sprintf(lcd_buf,"t=%.2f\xdfC",temp);                    
          lcd_puts(lcd_buf);
          delay_ms(250);
                       
      }; 
}
Скрин из протеуса
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

это сделано?
Note: 1 Wire port settings are specified in the
Project|Configure|C Compiler|Libraries|1 Wire menu.
почему #define MAX_DS18b20 1
датчиков 2 вроде
Реклама
Родился
Сообщения: 7
Зарегистрирован: Вс апр 06, 2014 19:24:00

Сообщение ZEugene »

oleg110592 писал(а):это сделано?
Note: 1 Wire port settings are specified in the
Project|Configure|C Compiler|Libraries|1 Wire menu.
почему #define MAX_DS18b20 1
датчиков 2 вроде
Да, выставил, все равно такая же проблема.


А то, что MAX_DS18b20 было определено как 1 - это я уже когда пытался бороться с проблемой выставил, не поменял просто обратно на 2 :)
Собутыльник Кота
Аватара пользователя
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев

Сообщение BCluster »

Если отключить датчик вообще, тоже будет показывать -999 насколько я помню в кодвижне.
Попробуйте :)
Резистор подтяжки есть на датчике?
упд: вижу что резистор есть

и я не вижу вот этого в коде:

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

#asm
.equ __w1_port=0×15 ;PORTC
.equ __w1_bit=0
#endasm
не знаю, может это какой-то новый кодвижн...
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

в новом CV это не обязательно. Это проверял в протеусе - работало (один датчик):
Спойлер

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

#include <alcd.h> // Alphanumeric LCD Module functions
#include <ds18b20.h>
#include <delay.h>
#include <stdio.h>

char lcd_buffer[33];
/* maximum number of DS18B20 connected to the 1 Wire bus */
#define MAX_DEVICES 1

/* DS18B20 devices ROM code storage area */
unsigned char rom_code[MAX_DEVICES][9];

main()
{
lcd_init(16);
lcd_putsf("CodeVisionAVR\n1 Wire Bus Demo");
delay_ms(200);
lcd_clear();

/* measure and display the temperature(s) */
while (1)
      {
          sprintf(lcd_buffer,"%+.3f\xdfC",ds18b20_temperature(0));
          lcd_clear();
          lcd_puts(lcd_buffer);
          delay_ms(100);
      };
}
СпойлерИзображение
Реклама
Родился
Сообщения: 7
Зарегистрирован: Вс апр 06, 2014 19:24:00

Сообщение ZEugene »

oleg110592, попробовал скомпилировать Ваш код, опять выскочило значение -9999.0 :cry:

Может в codevision есть какая-то настройка, которую нужно выставить, чтобы все заработало?

Прочитал еще в хелпе от codevision, что такая ошибка (значение -9999) возникает, если произошла ошибка при темп.преобразовании:
Изображение
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18785
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

я, конечно, в CVAVR не специалист, но в вашем коде в главном цикле стоит задержка в 250 миллисекунд, в то время как преобразование датчик DS1820 делает минимум 750 миллисекунд - не отсюда ли ошибка? сделайте задержку в 1 секунду - не ошибетесь.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение oleg110592 »

в то время как преобразование датчик DS1820 делает минимум 750 миллисекунд
внутри ds18b20_temperature(0) уже есть нужная задержка:

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

// temp. conversion time [ms] depending on the resolution
static flash int conv_delay[4]={100,200,400,800};
......
w1_write(0x44);
delay_ms(conv_delay[resolution]);
if (ds18b20_read_spd(addr)==0) return -9999;
......
опять выскочило значение -9999.0 :cry:
Тактовая частота микроконтроллера в проекте и протеусе одинаковы? Второй датчик лучше пока "отцепить".
Родился
Сообщения: 7
Зарегистрирован: Вс апр 06, 2014 19:24:00

Сообщение ZEugene »

Да, оказалось, что в codevision и в proteus были выставлены разные тактовые частоты контроллера.



Всем огромное спасибо за поддержу, особенно oleg110592 :)
Родился
Сообщения: 7
Зарегистрирован: Вс апр 06, 2014 19:24:00

Сообщение ZEugene »

ZEugene писал(а):Да, оказалось, что в codevision и в proteus были выставлены разные тактовые частоты контроллера.



Всем огромное спасибо за поддержу, особенно oleg110592 :)

Я смоделировал схему oleg110592 в протеусе, она заработала после установки одинаковых тактовых частот контроллера.
А с моим контроллером (Atmega168) протеус не захотел работать, все то же -9999.0
Не знаю, что за fuse-бит в протеусе - CLKDIV8, но выставление его в вид Unprogrammed решило проблему:

Изображение
Собутыльник Кота
Аватара пользователя
Сообщения: 2512
Зарегистрирован: Пн апр 06, 2009 19:33:29
Откуда: Молдова, Кишинев

Сообщение BCluster »

ZEugene писал(а): Не знаю, что за fuse-бит в протеусе - CLKDIV8, но выставление его в вид Unprogrammed решило проблему
он не в протеусе, а в МК. Делит тактовую частоту на 8.
Контактная информация:
Родился
Сообщения: 7
Зарегистрирован: Вс апр 06, 2014 19:24:00

Сообщение ZEugene »

Проблема (-9999.0 градусов на lcd) сохраняется при наличии более чем одного датчика на шине :( Когда один датчик, то все хорошо.
В чем еще может быть загвоздка??
Родился
Сообщения: 7
Зарегистрирован: Вс апр 06, 2014 19:24:00

Сообщение ZEugene »

ZEugene писал(а):Проблема (-9999.0 градусов на lcd) сохраняется при наличии более чем одного датчика на шине :( Когда один датчик, то все хорошо.
В чем еще может быть загвоздка??

Решил. Проблема была в одинаковых серийниках еще. Протеус оказывается выставляет одинаковые rom на все датчики ds18b20 :)
Грызет канифоль
Аватара пользователя
Сообщения: 281
Зарегистрирован: Пт ноя 15, 2013 20:58:23

Сообщение Halex »

ZEugene писал(а):
ZEugene писал(а): Протеус оказывается выставляет одинаковые rom на все датчики ds18b20 :)
Эт если Вы не позаботились о другом. Смею напомнить, а Вам рекомендую еще раз заглянуть в даташит DS18B20 и убедиться, что серийный номер - 48бит, т.е. 6 байт, а в модели DS18B20 в Протеусе заданы только 3 (???) - не наводит на размышления??? Пользователь самостоятельно должен дописать недостающее. Впрочем, Вы еще не обратили внимания и на следующую строку в параметрах модели - Automatic Serialization (по умолчанию она - No). Раз она НОУ (0), то симулятор хватает номер из строки ROM Serial Number и, если там пользователь не удосужился сам дополнить номер, добивает тремя нулёвыми байтами. Получаются одинаковые номера. Если там ЙЕЗ (1), то симулятор вообще игнорирует строку серийного номера, а "придумывает" свой, причем если датчиков много, то разный. Смотрим "весёлые картинки"...
Зачем такие тонкости и запутанность? Поясню. Задумано всё логически и профессионально:
Допустим, у Вас есть датчики с известными SN, т.е. в программе МК можно "опустить"(в хорошем смысле этого слова) первоначальный опрос, жёстко задать количество датчиков, их номера, последовательность опроса и т.п. - теряем на гибкости, но экономим на самой программе. Вот такое тоже можно отлаживать в Протеусе, задав строго номера каждого датчика (ест..нно для каждого разные и вручную).
Второй вариант написания программы - (вот, в кодевижной библе для DS18B20 она и реализована, хотя и кривовато, с точки зрения нормального программиста Си) - первоначальный опрос по принципу М.С. Горбачёва - "ху-из-кто", но под адреса оговорен массив определенного размера, задаваемого тоже строго на этапе программирования МК. Адреса заносятся в массив, а потом пошли "шнурить" - опрос его по кругу. Но!!! Максимальное количество датчиков (#define MAX_DEVICES ) Вы определяете заранее и под них (ИМХО их адреса) резервируется массив в ОЗУ определенного размера. Библа написана так, что если Вы задали количество датчиков 5, а на самом деле их 2, то потом при циклическом опросе по адресам из массива для несуществующих трех датчиков будет возвращаться значение температуры -9999. Ваша задача, как программиста (по замыслу Паши Гайдука - автора CVAVR) распознать такие гадости и пресечь их вывод на экран, в интерфейс и т.п., как неадекватные и для несуществующих датчиков. Это фича Кодевижна - не нравится, не пользуйтесь, пишите своё. Моё мнение по такой реализации я уже высказал в начале этого абзДЕца в скобках.
Уф..ф, стокА многА буКАФ давно не писал, но, надеюсь, пояснил доходчиво.
ИзображениеИзображение
P.S. На скриншотах приведен готовый пример из папки Протеуса Proteus 7 Professional\SAMPLES\VSM for AVR\One-Wire\DS18X20\. Только я там убрал датчик DS18S20. Это на случай самостоятельного осмысления... Впрочем, модель и этого похеренного датчика тоже построена по тому-же принципу. Рекомендую "не брезговать" существующими примерами из папки SAMPLES, особенно начинающим.
Ответить

Вернуться в «AVR»