Как перевести код (DS18B20)
Как перевести код (DS18B20)
Доброго времени суток!
Начал осваивать DS18B20, помогите разобраться как перевести 2 байтный код в численный ASCI код LCD.
SSSS SXXX XXXX XXXX - исходный код с DS18B20
SXXX XXXX X - тот что хочу преобразовывать (биты 0,1,2 откинул), где S - показатель знака, S=0 температура положительна, S = 1 - температура отрицательна. На LCD хочу получить что-то типа SXXX,X ,где S - знак.
Только хотелось бы увидеть код на ассемблере.
Начал осваивать DS18B20, помогите разобраться как перевести 2 байтный код в численный ASCI код LCD.
SSSS SXXX XXXX XXXX - исходный код с DS18B20
SXXX XXXX X - тот что хочу преобразовывать (биты 0,1,2 откинул), где S - показатель знака, S=0 температура положительна, S = 1 - температура отрицательна. На LCD хочу получить что-то типа SXXX,X ,где S - знак.
Только хотелось бы увидеть код на ассемблере.
- Реклама
Re: Как перевести код (DS18B20)
В CVAVR что-то типа этого sprintf(buf,"t%u=%i.%u\xdfC",++i,temp/10,abs(temp%10));
если температура отрицательная,будет знак - минус.
если температура отрицательная,будет знак - минус.
- Вложения
-
- Новая папка (8).rar
- (30.81 КБ) 240 скачиваний
Re: Как перевести код (DS18B20)
Vov123, спасибо конечно, но с CVAVR я не работаю.
Может кто сможет объяснить на ассемблере?
Может кто сможет объяснить на ассемблере?
- Pavel V.
- Мявтор!
- Сообщения: 384
- Зарегистрирован: Ср май 17, 2006 18:39:01
- Откуда: Москва
- Контактная информация:
Re: Как перевести код (DS18B20)
Я до градусов округляю, десятые не использую. Вот пример:
Код: Выделить всё
uint16_t fullTemperature = (scratchpad[1] << 8) | scratchpad[0];
if(m_Roms[i].Bytes[0] == DS18B20) {
m_Temperature[i] = (int8_t)(fullTemperature >> 4);
} else if (m_Roms[i].Bytes[0] == DS1920) {
m_Temperature[i] = (int8_t)(fullTemperature >> 1);
} else {
- Хатуль_мадан
- Электрический кот
- Сообщения: 1007
- Зарегистрирован: Ср мар 03, 2010 11:48:00
- Откуда: Уфа
Re: Как перевести код (DS18B20)
Вам нужен пример реализации или понять принцип преобразования? В свое время тоже начинал его изучение и тоже на ассемблере для термостата, очень помогло русское описание на датчик от Чернова Г. посмотреть можно тут http://www.masterkit.ru/zip/ds18b20-rus.pdf. Там и примеры есть (тоже на ассемблере).
- Реклама
Re: Как перевести код (DS18B20)
Всё в одном флаконе.Вам нужен пример реализации или понять принцип преобразования?
Итак у меня есть SXXX XXXX X (биты 11-3 для DS18B20) , где S - показатель знака, далее я разложил:
S - при 1 состоянии вывожу минус на дисплей, с этим проблем нет, остаётся
XXXX XXXX(биты 10-3) - лежит в регистре TEMP, теперь как этот ТЕМР преобразовать в численные значения LCD ??
тоесть чтобы получилось SXXX,X, так как S - это знак температуры и его вывести проблем не составит, остаётся преобразовать ТЕМР для получения численного значения в формате XXX,X Кто что предложит?
- Хатуль_мадан
- Электрический кот
- Сообщения: 1007
- Зарегистрирован: Ср мар 03, 2010 11:48:00
- Откуда: Уфа
Re: Как перевести код (DS18B20)
Ну если на пальцах, то датчик дает 12 разрядов измеряемой температуры (по умолчанию), причем 4 младших это дробная часть градуса, т.е 1/16=0,0625 дискретность замера. оставшиеся 8 разрядов (со знаком) это число соответствующее целым градусам в замере. В зависимости от того, что Вам нужно, такое количество разрядов и используете. Как реализовать, это дело вкуса каждого. Когда сам начинал изучение программирования, тоже искал свои пути решения. Вот предлагаю кусочек своей программы по Вашей задаче. Знатоков прошу не судить стого, возможно кое-что коряво, но работает.
PS:
Ну если кому интересно как, то это реализовано тут: http://radiokot.ru/konkurs/012/
PS:
Ну если кому интересно как, то это реализовано тут: http://radiokot.ru/konkurs/012/
Последний раз редактировалось Хатуль_мадан Вт янв 18, 2011 14:42:10, всего редактировалось 1 раз.
- Rimsky
- Грызет канифоль
- Сообщения: 299
- Зарегистрирован: Вт июн 15, 2010 07:16:42
- Откуда: Иркутск
- Контактная информация:
Re: Как перевести код (DS18B20)
кое что из моего опыта
- Вложения
-
- 1wire_dr.asm
- (6.96 КБ) 434 скачивания
Re: Как перевести код (DS18B20)
.
Последний раз редактировалось Tom91 Ср янв 19, 2011 09:38:32, всего редактировалось 1 раз.
Re: Как перевести код (DS18B20)
Tom91, вам нужно сначала преобразовать двоичное значение температуры в двоично-десятичное, поищите процедуры вроде bin2bcd, вот мой пример для беззнакового 8-бит целого:
в r16 кладете двоичное значение, вызываете процедуру, из r18, r17, r16 забираете десятичные цифры. Поскольку у Вас число со знаком, то в случае если оно отрицательно (старший бит = 1), предварительно нужно взять его модуль (инвертировать и добавить единицу), а знак сохранить где-нибудь в другом регистре.
Дальше к каждой полученной двоично-десятичной цифре добавляете 0x30, получаете ASCII коды этих цифр. Дальше отправляете их на индикатор, тут уже сами разбирайтесь. Минус и запятую в виде ASCII кодов тоже отправляете в нужном месте.
Код: Выделить всё
_bin2bcd:
ldi r17,255
ldi r18,255
_calc_hundreds:
inc r18
subi r16,100
brbc sreg_c,_calc_hundreds
subi r16,156
_calc_tens:
inc r17
subi r16,10
brbc sreg_c,_calc_tens
subi r16,246Дальше к каждой полученной двоично-десятичной цифре добавляете 0x30, получаете ASCII коды этих цифр. Дальше отправляете их на индикатор, тут уже сами разбирайтесь. Минус и запятую в виде ASCII кодов тоже отправляете в нужном месте.
Вероятно, это значение лучше сперва прокрутить влево на 4 бита, чтобы старший байт был целой частью, младший - дробной (SXXXXXXX XXXX0000)Tom91 писал(а):SSSS SXXX XXXX XXXX
Re: Как перевести код (DS18B20)
тоесть если число отрицательное, то:Поскольку у Вас число со знаком, то в случае если оно отрицательно (старший бит = 1), предварительно нужно взять его модуль (инвертировать и добавить единицу), а знак сохранить где-нибудь в другом регистре.
Код: Выделить всё
com lbyte
inc lbyte я старшие 4 бита даже считывать не собираюсь, а первые 3 пропускаю, S хранится отдельноВероятно, это значение лучше сперва прокрутить влево на 4 бита, чтобы старший байт был целой частью, младший - дробной (SXXXXXXX XXXX0000)
непонятно почему тогда (код ниже) прибавляют не 30 ??? (исходник выше)Дальше к каждой полученной двоично-десятичной цифре добавляете 0x30, получаете ASCII коды этих цифр.
Код: Выделить всё
subi digit1, -48 ; подготовка к пересылке
subi digit2, -48
subi digit3, -48
subi digit4, -48
Re: Как перевести код (DS18B20)
Да. Но корочеTom91 писал(а): тоесть если число отрицательное, то:Код: Выделить всё
com lbyte inc lbyte
Код: Выделить всё
neg lbyteУверены, что правильный результат получится? Я просто не работал с этими датчиками, не знаю в каком виде он данные дает.Tom91 писал(а): я старшие 4 бита даже считывать не собираюсь, а первые 3 пропускаю, S хранится отдельно
Как раз 30 и прибавляютTom91 писал(а): непонятно почему тогда (код ниже) прибавляют не 30 ??? (исходник выше)Код: Выделить всё
subi digit1, -48 ; подготовка к пересылке subi digit2, -48 subi digit3, -48 subi digit4, -48
Код: Выделить всё
ori digit1, 0x30Re: Как перевести код (DS18B20)
Тогда диапазон корректного измерения температуры будет от минус 16 до плюс 15 градусов, устраивает?Tom91 писал(а):я старшие 4 бита даже считывать не собираюсь, а первые 3 пропускаю, S хранится отдельно
Re: Как перевести код (DS18B20)
stas00n, а не могли бы вы пояснить свой код преобразований, тоесть описать алгоритм его работы...
SSSS SXXX XXXX XXXX - это 2байтный код с датчика обеспечивает 12разрядное разрешение, где S - показатель знака
Для 9 разрядного разрешения биты 0,1,2 откидываются что я и сделал, старшие 4 бита просто повторяют значения S, посути они ненужны, или я что-то не так понял?
В результате у меня остаётся только 9бит: S XXXX XXXX (приращение 0,5"С)
Код: Выделить всё
_bin2bcd:
ldi r17,255
ldi r18,255
_calc_hundreds:
inc r18
subi r16,100
brbc sreg_c,_calc_hundreds
subi r16,156
_calc_tens:
inc r17
subi r16,10
brbc sreg_c,_calc_tens
subi r16,246
Почему?stas00n писал(а):Тогда диапазон корректного измерения температуры будет от минус 16 до плюс 15 градусов, устраивает?Tom91 писал(а):я старшие 4 бита даже считывать не собираюсь, а первые 3 пропускаю, S хранится отдельно
SSSS SXXX XXXX XXXX - это 2байтный код с датчика обеспечивает 12разрядное разрешение, где S - показатель знака
Для 9 разрядного разрешения биты 0,1,2 откидываются что я и сделал, старшие 4 бита просто повторяют значения S, посути они ненужны, или я что-то не так понял?
В результате у меня остаётся только 9бит: S XXXX XXXX (приращение 0,5"С)
Re: Как перевести код (DS18B20)
Так наверное будет понятней:Tom91 писал(а):stas00n, а не могли бы вы пояснить свой код преобразований, тоесть описать алгоритм его работы...
Код: Выделить всё
_bin2bcd:
ldi r17, -1
ldi r18, -1
_calc_hundreds:
inc r18
subi r16,100
brbc sreg_c,_calc_hundreds
subi r16, -100
_calc_tens:
inc r17
subi r16,10
brbc sreg_c,_calc_tens
subi r16, -10Алгоритм такой: сперва считаем сотни, для этого вычитаем из преобразуемого числа 100; если результат положительный (не было переноса) инкрементируем разряд сотен, если перенос случился, значит результат отрицательный и подсчет сотен закончен, переходим к подсчету десятков, предварительно вернув последнюю вычтенную сотню "назад"; аналогично с десятками, инкрементируем регистр десятков вычитая из числа по 10 и сравнивая результат с нулем (смотрим на бит переноса); потом возвращаем "назад" последний вычтенный десяток, после этого единицы получаются сами собой в r16. Регистры десятков и сотен инициализируются значением минус один, т.к. инкрементируются они до первой операции вычитания (так цикл короче получается).
Дык, "откидывать" надо младшие биты младшего байта, а вы откинули старшие, которые имеют наибольший вес. Там 12-битное знаковое число, содержащее целую (8 бит) и дробную (4 бита) части выровнено вправо, что в принципе, верно, а запятая получается между 3 и 4 битом младшего байта. Если сдвинуть значение влево на 4 бита, запятая придется аккурат между старшим и младшим байтом. Надо смотреть, как удобней считать будет.Tom91 писал(а):Для 9 разрядного разрешения биты 0,1,2 откидываются что я и сделал, старшие 4 бита просто повторяют значения S, посути они ненужны, или я что-то не так понял?
Последний раз редактировалось stas00n Ср янв 19, 2011 00:02:18, всего редактировалось 1 раз.
Re: Как перевести код (DS18B20)
Рекомендую к прочтению: Представление чисел в дополнительном коде.
Re: Как перевести код (DS18B20)
Вот именно что число 12 битное, а выгоняем из него 16 битное, тоесть:Дык, "откидывать" надо младшие биты младшего байта, а вы откинули старшие, которые имеют наибольший вес. Там 12-битное знаковое число, содержащее целую (8 бит) и дробную (4 бита) части выровнено вправо, что в принципе, верно, а запятая получается между 3 и 4 битом младшего байта. Если сдвинуть значение влево на 4 бита, запятая придется аккурат между старшим и младшим байтом. Надо смотреть, как удобней считать будет.
SSSS SXXX XXXX XXXX - исходное число (16бит), откинул старшую тетраду:
SXXX XXXX XXXX - сама температура (12бит), откинул 0,1,2 биты :
S XXXX XXXX - температура (9бит)
Или я что-то не так понял?
+125'C 0000 0111 1101 0000
+25.0625'C 0000 0001 1001 0001
-55'C 1111 1100 1001 0000
Re: Как перевести код (DS18B20)
В принципе и так можно, тогда двигать лучше на 3 бита вправо, заполняя старшие биты знаками (S). Вообще, как угодно, зависит от того, где предпочтительней запятую ставить. В любом случае, в один байт не укладываетесь, значит вычисления будут уже 16-битные..
Re: Как перевести код (DS18B20)
Так SXXXX XXXX это сдвигаю вправо и кладу в r16 (S-учёт знака, тоесть если отриц перевожу, инверсия + 1), на выходе получаю
r18,r17,r16 - целые грудусы, но как быть с дробными, к тому же приращение при 9 битах 0,5"С Тоесть если всё правильно понимаю после запятой 0 или 5
Как реализовать такой алгорит
r18,r17,r16 - целые грудусы, но как быть с дробными, к тому же приращение при 9 битах 0,5"С Тоесть если всё правильно понимаю после запятой 0 или 5
Как реализовать такой алгорит
Последний раз редактировалось Tom91 Ср янв 19, 2011 01:41:42, всего редактировалось 1 раз.
Re: Как перевести код (DS18B20)
Выровняйте, как я в начале рекомендовал сдвигом влево на 4 бита, младшие биты заполнить нулями, получится старший байт - целая часть, младший - дробная, запятая посередине; если старший бит целой части (15-й) равен единице, то бишь число отрицательно, берем модуль. Целую часть преобразуем вышеописанной процедурой, дробную еще проще - смотрим на старший бит дробной части (7-й), если он равен 0, то десятичная цифра после запятой 0, иначе - 5. Вообще, веса разрядов дробной части располагаются (слева направо) так: 1/2, 1/4, 1/8, 1/16, 1/32, 1/64, 1/128, 1/256, - суть так же как и целой части, - следующий (влево) вдвое больше предыдущего, поэтому оперировать числами с фиксированной запятой можно так же как целыми.


