Перейти к содержанию

Алгоритм Обработки Потока Ds18B20 И Ds1820


Рекомендуемые сообщения

инвертируем побитно это число и прибавляем 1 (sic!!!) к младшему значащему разряду

Команду sic MPLab не распознает... я думаю, что так тоже можно будет сделать:

addlw b'00000001'

при этом младший бит будет находится в буфере...

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

  • Ответов 64
  • Создана
  • Последний ответ

Топ авторов темы

Топ авторов темы

Изображения в теме

sic - латынь - так (утверждающий предлог).

При выделении особо важного участка предложения применяется в сочетании с восклицательным знаком. Это означает ВНИМАНИЕ!!!

А по существу по моему я ясно сказал. Прибавлять 1 нужно к МЛАДШЕМУ значащему разряду, а не к целочисленной части.

Изменено пользователем my504

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

  • 2 недели спустя...

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Опять у меня проблема с восприятием этого мира... :lol: Вот модуль, в котором производится определение, больше или меньше 100 градусов температура, и если больше, то в первом символе отоброжается единица а дальше производятся какие то непонятные манипуляции...

T100_label bcf STATUS,C

rrf TL,W

addlw D'156'

btfss STATUS,C ; если нет переноса

goto Tshow_label ;Если температура меньше 100 градусов - переход далее

movlw D'200' ;

subwf TL,F ;Т не менее 100 градусов - сотню вычитаем

movlw B'11100111' ;Отобразить "1" во втором разряде

movwf FIG0X00

Tshow_label

.........

.........

........

Например датчик передает температуру в 100 градусов. Прибавляем 156 получаем ноль и флаг переноса устанавливается в 1. Аналогично и с 110 градусами - получаем 10. Теперь вопрос: Если температура выше 100 градусов, то в старшем разряде отображается единица, почему бы теперь этот "остаток" от переноса просто не отобразить как есть? Например 100 = 1 + 00; 110 = 1 + 10, зачем далее отнимать 200?

Изменено пользователем dimas5552
Ссылка на комментарий
Поделиться на другие сайты

  • 2 недели спустя...

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

Все таки эта загадка до сих пор не дает покоя моим мозгам... :( Почиму написанно "Т не менее 100 градусов - сотню вычитаем" а вычитаются все 200 ???

Полный текст кода вот здесь: http://pic16.nm.ru/site/thermometer/thermometer.html

Изменено пользователем dimas5552
Ссылка на комментарий
Поделиться на другие сайты

А как происходит Генерирование циклического контроля избыточности (CRC) DS18B20??? Есть переведенный датишит, но там эта глава на ОЧЕНЬ ломанном русском, ничего не понятно!

С уважением, Дмитрий

Ссылка на комментарий
Поделиться на другие сайты

Кстати в моем сообшении до Вашего, в ссылке на исходник есть алгоритм расчета crc суммы... ;)

Изменено пользователем dimas5552
Ссылка на комментарий
Поделиться на другие сайты

Я чужие проги плохо воспринимаю, а ПИКи уже подзабывать начал... Щас вот AVR осваиваю...

Если не трудно, напишите алгоритм вычисления или дайте ссылку, где можно почитать

С уважением, Дмитрий

Ссылка на комментарий
Поделиться на другие сайты

Народ, я уже начинаю сомневаться в правильности кода исходника, может быть изменить вычитаемое значение на сотню? Или скорее всего наверное вернее будет засунуть датчик в самое пекло и проверить опытным путём, двести или сто должно быть вычитаемое значение... :unsure:

Ссылка на комментарий
Поделиться на другие сайты

Правильно ли я понял вот этот алгоритм:

post-6787-0-32176000-1289108942_thumb.jpg

1. Очищаем 8-ми разрядный сдвиговый регистр

2. Подаем на вход алгоритма, первый принятый бит

3. Операция Исключающее ИЛИ между первым принятым битом и 8-м битом сдвигового рег-ра

4. Операция Исключ. ИЛИ между результатом операции пункта 3 и 4-м битом сдвигового рег-ра

5. операция Искл. ИЛИ между результатом операции пункта 3 и 4-м битом сдвигового рег-ра

6. Сдвиг на одну позицию вправо. Место нулевого бита занимает результат операции пункта 3

Повторяем столько раз, сколько принято бит (не считая бита CRC). То, что в итоге останется в сдвиговом рег-ре и ЕСТЬ CRC

С уважением, Дмитрий

Ссылка на комментарий
Поделиться на другие сайты

Вот код в амсме для пика:

;Подпрограмма обновления CRC. Параметр в W. Используются ячейки TEMP1, TEMP2

NewCRC clrwdt

movwf TEMP2 ;Сохранить W

movlw 08h

movwf COUNTER ;8 --> COUNTER

movf TEMP2,W ;Восстановить значение W

CRC_label xorwf CRCPIC,W ;Исключ.ИЛИ CRCPIC и W, результат в W

movwf TEMP1 ;Скопировать результат в TEMP1

rrf TEMP1,W ;Сдвиг TEMP1 вправо на 1, результат в W, младший бит в С

movf CRCPIC,W ;CRCPIC --> W (бит С не изменился)

btfsc STATUS,0

xorlw 018h ;Если С=0, то эту инструкцию не выполнять

movwf TEMP1 ;Результат в TEMP1

rrf TEMP1,W ;Снова сдвиг, результат в W

movwf CRCPIC ;Сохранить результат в CRCPIC

bcf STATUS,0 ;0 --> C

rrf TEMP2,F ;Сдвиг TEMP2 вправо на 1

movf TEMP2,W ;И скопировать полученное значение в W

clrwdt

decfsz COUNTER,F

goto CRC_label

return ;Конец подпрограммы обновления CRC

Ссылка на комментарий
Поделиться на другие сайты

  • 3 недели спустя...

Кто знает, почему после команды конкектирования температуры 44h в шине остаётся высокий уровень, ведь в датащите написанно, что на протяжении всего париода преобразования в шине должен быть низкий уровень?

Изменено пользователем dimas5552
Ссылка на комментарий
Поделиться на другие сайты

Прямое (трёхпроводное подключение). Ясно, что при паразитном питании речи об контроле конвектирования быть не может, так как питание в этом случае должно подаваться на протяжении всего времени конвектирования, а в моём случае идёт передача команды 0x44 и примерно через 5-10 микросекунд (через время, которое уходит на завершение подпрограммы передачи данных) я ставлю цикл:

btfss PORTA, DS

Goto $-1

где DS номер контакта порта A, подключенного к датчику, и при первом же проходе этот цикл заканчивается, о чем можно судить по считыванию из температурных байтов датчика значения по умолчанию (85 *С), то есть значения, ещё не подвергшегося изменению, так как конвектирование температуры ещё продолжается. А раз цикл заканчивается при первом же проходе можно судить о том, что в шине на момент конвектирования высокий логический уровень.

Или же низкий уровень в шине устанавливается через какое то время (более 10 мкс)?

Изменено пользователем dimas5552
Ссылка на комментарий
Поделиться на другие сайты

Сначала ожидайте нуля, а лишь потом единицу.

Кроме того, нужно предусмотреть выход по таймауту, например через 1...1,5 секунды, если ожидание затянулось (датчик не отвечает).

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

А через какое время наступает логический ноль в шине? И какая может быть речь об таймауте в 1 - 1,5 сек, если всё время конвектирования температуры датчика занимает 0,750 сек. По датащиту ноль в шине наступает сразу после передачи команды 0x44 на следующей микросекунде, но в реале получается, что шина остаётся в высоком уровне на время конвектирования... :blink: :blink: :blink:

Ссылка на комментарий
Поделиться на другие сайты

КонвеРтирование. Convert.

Таймаут - это выход из ожидания по отсутствию условия.

Поэтому время таймаута должно быть БОЛЬШЕ нормального периода ожидания.

Что бы говорить о состоянии шины, нужно зациклить команду Convert T с шагом в секунду и тогда осциллографом смотреть шину.

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

Коевектирование занимает 0,750 сек, а если проверять датчик через 1 секунду то ясное дело в байтах конвектирования будуд занесены уже конвектированные величины, я говорю о конторле датчика во время преобразования датчика... :blink:

Изменено пользователем dimas5552
Ссылка на комментарий
Поделиться на другие сайты

КоевеPтирование занимает 0,750 сек, а если проверять датчик через 1 секунду то ясное дело в байтах конвеPтирования будуд занесены уже конвеPтированные величины, я говорю о конторле датчика во время преобразования датчика... :blink:

Еще раз. Следите за ходом мысли. Моей мысли, а не своей.

1. Запускаете преобразование.

2. Ожидаете НУЛЯ на шине.

3. Ожидаете ЕДИНИЦЫ на шине.

4. снимаете данные с датчика.

Чтобы пункты 2 и 3 не вызывали зацикливания при не ответе датчика, необходимо сделать выход по таймауту.

Для этого при входе в ожидание запускают программный таймер на 1...1,5 секунды. Как только он переполнится, так выходят из ожидания с установкой флага ошибки и флага-бита состояния шины при выходе (ноль или единица).

Это позволит определить, происходило преобразование или нет.

Тогда и получите ответ на свой вопрос или уточните вопрос с учетом состояния этих двух программных флагов.

ЗЫ. Анлийское слово Convert пишется через R. Поэтому и русский глагол КОНВЕРТИРОВАТЬ пишется тоже через Р.

Изменено пользователем my504

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

1. Запускаете преобразование.

2. Ожидаете НУЛЯ на шине.

3. Ожидаете ЕДИНИЦЫ на шине.

4. снимаете данные с датчика.

Сделал по этой аналогии и написал такой цикл:

btfsc PORTA, DS

Goto $-1

btfss PORTA, DS

Goto $-1

здесь сначала ожидается низкий уровень в шине, а затем высокий. Цикл уходит в вечное кольцо на первом же условии (на втором условии уйти в зависание программа не может, так как при этом усливии происходит вылет при первом же проходе как было написанно ранее). Из всего этого следует, что низкий уровень в шине во время конвертирования вообще не наступает... :blink:

Может низкий уровень в шине на время конвертировая характерен только для DS18B20, а DS18S20 без него работает?

Изменено пользователем dimas5552
Ссылка на комментарий
Поделиться на другие сайты

Читаем даташит для использованного датчика:

If the DS18S20 is powered by an external supply, the master can issue read time slots after the Convert T command and the DS18S20 will respond by transmitting 0 while the temperature conversion is in progress and 1 when the conversion is done.

Так что должен быть ноль...

А преобразование то происходит? Данные снимаете корректные?

Изменено пользователем my504

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

Да, данные считываются нормально, только вот загвоздка во времени конвертирования - при включении термометра он на протяжении времени конвертирования показывает 85*С, затем реальную (корректную) температуру. Сколько исходников не перерыл, везде между командами 44h и BEh (считывание) идёт пауза в 0,8 - 1 сек. Не разу не встретил модуль ожидания завершения конвертирования, основанный на анализе состояния шины, решил написать его сам и вот что вышло :( По моему это миф про низкий уровень во время преобразования...

ЗЫ: Зачем я всё это задумал? - хочется сделать такой алгоритм, который бы "отлавливал" момент для снятия данных с датчика а не тупо считывал их через заданный максимальный промежуток времени, ведь как утверждают "максимовцы" максимальное время конвертирования DS18S20 - 0,75 сек, но сколько датчиков, столько и интервалов... Один конвертирует 0,7 сек, другой 0,3 сек третий... и т.д. Хочется сделать "интеллектуальную" прошивку, которая сама бы и контроллировала время конвертировая датчика...

Изменено пользователем dimas5552
Ссылка на комментарий
Поделиться на другие сайты

И когда Вы наконец остепенитесь?... Всякую ерунду изрекаете...

Первое.

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

У 18В20 время конвертации зависит от разрядности преобразования. 12 разрядов - 750 мс, 11 - 325 мс, 10 - 187,5 мс и 9 разрядов - 93,75 мс.

У датчиков с постфиксом PAR в названии вообще отсутствует режим подачи питания по отдельному выводу. Вывод есть, но он никуда не подключен. Соответственно и нуля на шине никакого не будет. Правда и без сильной подтяжки он корректно преобразование не произведет.

Второе.

Насчет мифов.

Все что не соответствует даташиту, а цитату из него я Вам привел, это повод для получения сатисфакции от производителя.

Поэтому все Ваши сентенции - это неописуемая глупость и неумение работать с элементной базой.

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

  • 1 месяц спустя...

Тут такое ... есть SD1820 он один на выводе порта ATtiny2313 тактовая 4МГц. в комнате на LCD выдает +73.0 или +73.5 при нагреве/охлаждении меняется только дробная часть, например нагреваю воздухом от паяльника 73.0 > 73.5 > 73.0 > 73.5 и тд... при охлаждении обратно. В дебаге принятые 16 бит температуры выглядят так:

+73.0 >> 0000 0000 1001 0010

+73.5 >> 0000 0000 1001 0011

Расчет температуры выполнен верно но почему такая лажа ? Настенный термометр показывает 22 С.

Тайминги проверил Ч3-57 все ОК.

Код в "main"

		// *************************************************
	// DS1820
	DS_reset();
	DS_write( 0xCC );  //SKIP ROM Command
	DS_write( 0x44 );  //Convert T Command
	for(i=0;i<750;i++){ _delay_loop_2(1000);};	//wait 750ms
	DS_reset();	
	DS_write( 0xCC );  //SKIP ROM Command
	DS_write( 0xBE );  //Read Scratcpad Command		
	DS_read_temp();
	// end DS1820 

код процедур:

// 1 Wire
void DS_setHigh()
{
DDRB |= (1<<DS_PIN);
PORTB |= (1<<DS_PIN);
}
// ********************
void DS_setLow()
{
DDRB |= (1<<DS_PIN);
PORTB &= ~(1<<DS_PIN);
}
// ********************
void DS_realeseLine()
{
DDRB &= ~(1<<DS_PIN);  // set input
PORTB |= (1<<DS_PIN);  // enable pull-up
}
// ********************
void DS_reset()
{
DS_setLow();
_delay_loop_2(480);	// wait 480us
DS_realeseLine();
_delay_loop_2(500);	// wait 500us
}
// ********************
void DS_write( unsigned char n )
{

for(bl=0; bl<8; bl++ )
{
	DS_setLow();
	if( bit_is_set(n,bl) )
	{ //write 1 to ds
		_delay_loop_2(6);
		DS_realeseLine();
	}
	_delay_loop_2(60);
	DS_realeseLine();
	_delay_loop_2(3);
}
}
// ********************
void DS_read_temp ()
{
unsigned int temp = 0;

ta = 0;
tb = 0;
tc = 0;
td = 0;

for(bl=0; bl<17; bl++)
{	
	//PORTB &= ~_BV(Debag);	// debag "0"
	DS_setLow();
	_delay_loop_2(3);
	DS_realeseLine();
	_delay_loop_2(8);
	if( bit_is_set(PINB, DS_PIN) )
	{ //affter 13us check line
		//bit is 1
		temp |= _BV(bl);
	}
	//PORTB |= _BV(Debag);	// debag "1"
	_delay_loop_2(60);
}
// debag **********************
write_comand(0x04);			// adres --
write_comand(0x8F);
for(bl=0; bl<17; bl++)
{		
	if(bit_is_set(temp,(bl)))
	{
		write_data(0x31);	// "1" debag
	}else{
		write_data(0x30);	// "0" debag
	}
}
write_comand(0x06);			// adres ++
// debag **********************
if(bit_is_set(temp,0))		// "00.0" OR "00.5"
{
	td = 5;
}

if(bit_is_set(temp,8))	// "-" OR "+"
{
	status |= _BV(0);   // "-"
}else{
	status &= ~_BV(0);  // "+"
}

temp = ( temp >> 1);

temp &= 0b0000000001111111;


while( temp >= 100) // "100"
{
	temp = temp - 100;
	ta++;
}

while( temp >= 10)  // "10"
{
	temp = temp - 10;
	tb++;
}

tc = temp; // "1"
}

Изменено пользователем tire
Ссылка на комментарий
Поделиться на другие сайты

Извините, если ошибусь, я очень бегло посмотрел код, но:

Преобразование из дробного двоичного числа в дробное двоично-десятичное делают проще.

На индикацию при фиксированной точке уходит не сама величина, а умноженная на 10n, где степень - это порядок десятичной дроби.

Значит на индикацию нужно посылать не 73 и 5, а 735, как единую величину. Т.е. исходное число в бинарном коде преобразуется в двоично-десятичное БЕЗ УЧЕТА ТОЧКИ:

0000 0000 1001 0011 = 147, а нужно 735, значит сначала домножим исходную величину на 5:

0000 0000 1001 0011 * 101 = 1011011111 преобразуем в двоично-десятичный код и получаем искомые 735

Их и выводим, попутно зажигая фиксированную точку между последним и предпоследним разрядом.

Вот и все...

戦う前に相手のベルトの色に注目

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...