Всё по DS18(B/S)20.

Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Amstron писал(а):У меня проблема с измерением температуры DS18b20.
Как Вы объясните, что это не глюк компилятора?
Если вы не видите ошибки у себя, это ещё не означает, что её нет. :)
Какой компилятор-то был до 4й студии? Какой в 4й студии используете? Какая библиотека для DS18b20?
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Нашел транзистор. Понюхал.
Сообщения: 173
Зарегистрирован: Вт дек 21, 2010 21:18:52

Сообщение Amstron »

Аlex писал(а):
программа в цикле даже и не заходит туда!
Зачем он (этот код) тогда вообще нужен, если программа туда не заходит ?
Что не понятного то? Я специально решил Вам показать что глюк действительно в компиляторе и сообщаю о том, что компиль глючит не смотря на то что код стоит в том месте где программа туда даже не заходит...
Реклама
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Amstron писал(а):Что не понятного то? Я специально решил Вам показать что глюк действительно в компиляторе и сообщаю о том, что компиль глючит не смотря на то что код стоит в том месте где программа туда даже не заходит...
Говорить пока не о чем! Полная картина не ясна! Повторюсь. Вы не сказали какой у вас компилятор (тип, версия), под какой МК, какой библиотекой пользуетесь, какие опции компиляции и т.д. Если хотите объективного ответа, то покажите полные исходники вашего проекта, тогда можно посмотреть, что у вас не так. Иначе разговор не имеет смысла.
Если ещё не читали, то будет полезно: http://bugtraq.ru/forum/faq/general/sma ... tions.html
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

компиль глючит не смотря на то что код стоит в том месте где программа туда даже не заходит...
Это ещё не означает, что глючит компиль. Я вообще поражаюсь на тех, кто накопипастит всякого говнокода в кучу, которую хрен разгребёшь, и начинают бить себя в грудь, на весь форум крича, что глючит компиль, считая себя умнее разрабов компиляторов.
Нельзя начинать свой пост со слов "Глючит компиль", тем более просить Вам это доказать. Докажите Вы, что он глючит, разложите всё по полочкам, приведите неоспоримые факты, тогда и будем обсуждать глюк компиля, а не брызги эмоций, возникших от первой программы.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Сообщения: 99
Зарегистрирован: Чт мар 08, 2012 18:05:49
Откуда: Пермь

Сообщение x8973 »

Третий день мучаюсь с "простым" термометром на ds18b20 - не могу нормально его инициализировать. attiny2313, частота 8 МГц, трехпроводная схема включения датчика. Датчик пробовал заменять - разницы никакой. При попытке инициализации датчик не отвечает. Вот код инициализации:

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

// Инициализация DS18B20
unsigned char DS_init(void)
{
	// устанавливаем низкий уровень
	PORTD &= ~_BV(6);
	_delay_us(490);
	PORTD |= _BV(6);
	_delay_us(68);
	// ловим импульс присутствия датчика
	unsigned char OK_Flag = 0;
	if (PIND & _BV(6))
		OK_Flag = 1;
	else
		OK_Flag = 0;
	// если OK_Flag = 0 датчик подключен, OK_Flag = 1 датчик не подключен
	_delay_us(422);
	return OK_Flag;
}
На выходе всегда получаю 1. Кто что думает?
Реклама
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Сообщение a_skr »

// устанавливаем низкий уровень
PORTD &= ~_BV(6);
_delay_us(490);
PORTD |= _BV(6);
_delay_us(68);
- неверно.

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

PORTD = 0;
...
DDRD |= _BV(PD6); // устанавливаем низкий уровень
...
DDRD &= ~_BV(PD6); // отпускаем линию на внешнюю подтяжку
Реклама
Встал на лапы
Сообщения: 99
Зарегистрирован: Чт мар 08, 2012 18:05:49
Откуда: Пермь

Сообщение x8973 »

a_skr писал(а):

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

PORTD = 0;
...
DDRD |= _BV(PD6); // устанавливаем низкий уровень
...
DDRD &= ~_BV(PD6); // отпускаем линию на внешнюю подтяжку
Благодарю, стало адекватно реагировать на наличие/отсутствие датчика. Но всплыла другая проблема.
После получения двух байт с температурой я отсылаю их по ЮАРТу. В терминале же почему-то вместо двух байт приходят пять-шесть :shock: Значения чаще всего 0xF8 или 0x78. Чую я, что с задержками у меня что-то не так.
Частота контроллера 8 Мгц с делителем CKDIV8=0. Если поставить делитель, то данные в ЮАРТ будут отсылаться два раза в секунду, несмотря на _delay_ms(1000) между замерами температуры. Сам ЮАРТ настроен на работу на 8 Мгц. F_CPU задефайнил на 8000000.
Спойлер

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

/*
 * termometer.cpp
 *
 * Created: 08.09.2013 19:25:03
 *  Author: x-8973
 */ 


#include <avr/io.h>
#include <math.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define F_CPU 8000000

unsigned char byChr[13] = {0x22, 0x7B, 0x46, 0x4A, 0x1B, 0x8A, 0x82, 0x7A, 0x02, 0x0A, 0xFF, 0xFD, 0x20};
//                                         0------1------2------3------4------5------6------7------8------9----blank--'------ --

void USART_Init( unsigned int baudrate ) //Функция инициализации USART
{
	UBRRH = (unsigned char) (baudrate>>8);                  
	UBRRL = (unsigned char) baudrate;
	UCSRA = (1<<U2X); //Удвоение скорости
	UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE); //Разрешение на прием и на передачу через USART, разрешение прерываний RX*
	UCSRC = (1<<USBS)|(3<<UCSZ0); //Формат кадра: 8 бит данных, 2 стоп-бита.
}

void USART_Transmit( unsigned char data ) //Функция отправки данных
{
	while (!(UCSRA&(1<<UDRE))); //Ожидание опустошения буфера приема
	UDR = data; //Начало передачи данных			        
}

// Инициализация DS18B20
unsigned char DS_init(void)
{
	unsigned char device;
	PORTD = 0;
	DDRD |= _BV(PD6); // устанавливаем низкий уровень
	_delay_us(485);
	DDRD &= ~_BV(PD6); // отпускаем линию на внешнюю подтяжку
	_delay_us(65);

	if((PIND & (1<<PD6)) ==0x00)
		device = 1;
	else
		device = 0;
	_delay_us(420);
	return device;
}

// Функция чтения байта из DS18B20
unsigned char read_18b20(void)
{
	unsigned char data;
	for(unsigned char i = 0; i < 8; i++)
	{
		DDRD |= 1<<PD6;
		_delay_us(2);
		DDRD &= ~(1<<PD6) ;
		_delay_us(7);

		if((PIND & (1<<PB6)) == 0x00)
			data &= ~(1<<i);
		else
			data |= 1<<i;
		_delay_us(50);
	}
 return data;
}
 
// функция записи байта в DS18B20
void write_18b20(unsigned char cmd)
{
	for(unsigned char i = 0; i < 8; i++)
	{
		if((cmd & (1<<i)) == 1<<i)
		{
			DDRD |= 1<<PD6;
			_delay_us(2);
			DDRD &= ~(1<<PD6); 
			_delay_us(65);
		} 
		else
		{
			DDRD |= 1<<PD6;
			_delay_us(65);
			DDRD &= ~(1<<PD6);
			_delay_us(5); 
		}
	}
}

/*ISR(TIMER1_OVF_vect)
{
	//TCNT1 = 0x0000;
}*/

int main(void)
{
	USART_Init(103);
	
	//TCCR1A = 0x00;
	//TCCR1B |= (1<<WGM12)|(1<<WGM13)|(1<<CS12); //Режим "сброс при совпадении", предделитель 256
	//ICR1 = 0x7A12; //Считать до 31250 (8 000 000 / 256)
	//TIMSK = (1<<TOIE1); //Разрешить прерывание по переполнению таймера 1
	
	//sei();
	
    while(1)
    {
		if (DS_init()) 		// инициализация DS18B20
		{
			write_18b20(0xCC);     // проверка кода датчика
			write_18b20(0x44);     // запуск температурного преобразования
			_delay_ms(1000);
			DS_init();        // инициализация DS18B20
			write_18b20(0xCC);     // проверка кода датчика
			write_18b20(0xBE);     // считываем содержимое ОЗУ
			Temp_L = read_18b20(); // читаем первые 2 байта блокнота
			Temp_H = read_18b20();
			USART_Transmit(Temp_L);
			USART_Transmit(Temp_H);
			_delay_ms(1000);
		}			
		
		//Динамическая индикация
		/*int j = i;
		if (i < 0)
			j *= (-1);
		PORTD = 0x10;
		PORTB = byChr[j%10];
		_delay_ms(10);
		PORTD = 0x20;
		if (i < 0)
		{
			PORTB = byChr[j/10] & byChr[11];
		}
		else
		{
			PORTB = byChr[j/10];
		}
		_delay_ms(10);*/
        //TODO:: Please write your application code 
    }
}
Друг Кота
Аватара пользователя
Сообщения: 6324
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

x8973 писал(а): В терминале же почему-то вместо двух байт приходят пять-шесть :shock: Значения чаще всего 0xF8 или 0x78.
Такое может быть, если UART на передающем и приемном конце линии настроены на разные скорости. Нужно безотносительно датчика погонять по тракту тестовые посылки известного содержания и посмотреть что получится.
Опытный кот
Сообщения: 758
Зарегистрирован: Вс фев 10, 2013 15:26:00

Сообщение nirq »

тестовые посылки известного содержания
сначала сто раз "1000 0000", потом сто раз "1000 1000", потом сто раз "1010 1010"... нутыпонел. частота следования единичек (или ноликов, без разницы) - которую для наглядности можно осциллографом, и совсем не обязательно для этого иметь его азиатский модный.
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1438
Зарегистрирован: Вт окт 28, 2008 09:00:18
Откуда: Украина, Харьков

Сообщение Dr. Alex »

У меня не получается запитать датчик паразитным питанием, кто что пподскажет??? И когда именно передавать в датчик 0xB$?????
Порой мне кажется, что я делаю какое-то дерьмо, но когда я вижу, что делают другие, то я чувствую себя гением...
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 7360
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

B4 ? После одной из команд search ROM, Match ROM, Skip ROM итп. Но эта команда только скажет, как по мнению датчика он запитан. А для паразитного питания, просто после команды "convert T" надо на шину выдать питание в течении 10 мкс после поступления этой же команды (правда так никто мне и не пояснил, когда этот момент наступает, поэтому, можно его давать сразу же после окончания удерживания лог.0 в последнем тайм-слоте) и держать не менее указанного времени для выбранного датчика и разрешения. Одной секунды хватает для всех случаев.После чего напряжение снимаем (подтяжку оставляем) и выполняем сброс, выбор, чтение скратчпада.
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1438
Зарегистрирован: Вт окт 28, 2008 09:00:18
Откуда: Украина, Харьков

Сообщение Dr. Alex »

Просто нигде я не могу толком докопаться до истины) Нигде не пишут, как правильно питать датчик паразитным питанием!
Порой мне кажется, что я делаю какое-то дерьмо, но когда я вижу, что делают другие, то я чувствую себя гением...
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 7360
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

Я понимаю, что трудно найти справочную информацию на изделия отечественного радиопрома, но на далласовскую (максимовскую) продукцию найти, как правило, проблем не составляет.
http://www.maximintegrated.com/datashee ... vp/id/2815 <-- там справа, есть ссылка "download" с иконкой pdf-документа, так вот там скачивается даташит, содержащий всю необходимую информацию. Но если, еще что-то не ясно, то можно посмотреть раздел application notes, с поясняющими некоторые моменты статьями.

Конкретно подача паразитного питания приведена на рис.4 "Figure 4. Supplying the Parasite-Powered DS18S20 During Temperature Conversions"
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1438
Зарегистрирован: Вт окт 28, 2008 09:00:18
Откуда: Украина, Харьков

Сообщение Dr. Alex »

Я подключаю датчик паразитным питанием и мне сразу показывает темп. 127, а при нормальном питании - нормальную, комнатную;) Вопрос: ЧТО НЕ ТАК?
Порой мне кажется, что я делаю какое-то дерьмо, но когда я вижу, что делают другие, то я чувствую себя гением...
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 7360
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

Паразитное питание надо включать только на время преобразования! Во время выполнения сбросов и чтения-записи, должна быть только подтяжка.

т.е. делаем сброс, шлём (для примера) SkipROM, Convert, включаем Сильное питание на шину и держим секунду. Затем выключаем этот Strong PullUp, делаем сброс, SkipROM, Read Scratchpad и... вот оно.
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1438
Зарегистрирован: Вт окт 28, 2008 09:00:18
Откуда: Украина, Харьков

Сообщение Dr. Alex »

Мда... морока))))))) Уж лучше питать нормально, тем более датчик планируется выносить на 5-7м. так что во избежании помех сделаю по-нормальному.
Порой мне кажется, что я делаю какое-то дерьмо, но когда я вижу, что делают другие, то я чувствую себя гением...
Контактная информация:
Держит паяльник хвостом
Сообщения: 927
Зарегистрирован: Вт сен 07, 2010 19:27:48
Откуда: Ташкент

Сообщение borys »

Очень правильный вывод сделал Dr.Alex. Тем более, что сама фирма-изготовитель (правда не очень громко)
рекомендует то же самое.
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1438
Зарегистрирован: Вт окт 28, 2008 09:00:18
Откуда: Украина, Харьков

Сообщение Dr. Alex »

borys - респект!!!!!!! :))) :))) :))) :)))
Порой мне кажется, что я делаю какое-то дерьмо, но когда я вижу, что делают другие, то я чувствую себя гением...
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 7360
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

Сообщение uldemir »

Этот виноград зелен. Ничего не напоминает :)) ?
Родился
Аватара пользователя
Сообщения: 17
Зарегистрирован: Чт апр 12, 2012 17:35:15
Откуда: Украина Николаев

Сообщение grung »

Прошу меня простить за поднятие такой избитой темы. Но ни как не могу найти ответ, уже обходил кучу форумов.

Задача такая:
1. Получить температуру от датчика ds18b20
2. Из ходя из полученного значения сделать Логическое действие.

МК должен шевелить ШД. При изменении температуре поворачивать его на нужный угол.

Использую стандартную библиотеку 1wire.h, ds18b20.h.

Вот кусочек кода, начинаю только программировать так что не пинайте сильно.

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

void main(void)
{             
      
   w1_init();
   ds18b20_init(0,-20,50,DS18B20_12BIT_RES);
    // Бесконечный цикл
  while (1)    {  
   
  
       delay_ms(750);
       t1=ds18b20_temperature(0);        
        
       if (t1>1000){ //если датчик выдаёт больше 1000
        t1=4096-t1; //отнимаем от данных 4096
        t1=-t1; //и ставим знак “минус”
}  
    
     
     if (t1 < 90 ) poz=0; 
     if (t1 < 50 ) poz=1;
     if (t1 < 40 ) poz=2;
     if (t1 < 30 ) poz=3;
     if (t1 < 20 ) poz=4;
     if (t1 < 10 ) poz=5;
      }
В Протеуси проходи все на ура. ШД поворачивается на нужный шаг.
В железе в никакую, стоит как вкопаный, перепроверил схему подключения все отлично.

Есть подозрение о необходимости преобразования значения полученного от датчика.

Ни где не могу найти что фактически мы получаем в переменной, использую библиотеку ds18b20.h
Ответить

Вернуться в «Периферия»