Да, нужно выводить с точностью до десятых. Но нужно получать температуру с 12-битным расширением (с точностью до 1/10000) и потом вытаскивать первую цифру (как раз число тысяч). Я никак не могу понять почему код косячит, ведь алгоритм то в другом проекте работает как надо.
Но нужно получать температуру с 12-битным расширением (с точностью до 1/10000)
дискретность преобразования ds18b20 - 1/16 градуса, а точность еще ниже (см. datasheet ), так что 1/10000 - из области фантастики. А все манипуляции с 1000 просто не нужны - разделите температуру на дробную и целую часть - при этом обработка станет проще и быстрее.
Извините, неправильно выразился, да там дискретность 0,0625. Я получаю отдельно целую часть и дробную. С целой проблем нет, а дробная как раз и не работает. Получив данные из LS я умножаю их на 0625 и получаю температуру с 4 знаками после запятой, вот нужно первую цифру вытащить. Посмотрите код если есть время, там все видно
Лень не позволяет мне ковыряться в чужих кодах, а нормальная суба приблизительно вот такая :
Код:
; R25,R24 / 1000, остаток ; там же, частное в R0. DivT: push r16 push r17 sub r0,r0 ldi r17,high(1000) ldi r16,low(1000) _10T3: sub r24,r16 sbc r25,r17 brcs _10T5 inc r0 rjmp _10T3 _10T5: add r24,r16 ; *** adc r25,r17 ; *** pop r17 pop r16 ret
Если остаток не важен, строчки со звездочками можно пропустить. А если не пропускать, то R25,R24 можно пропустить еще через п/п DivD и получить оставшиенся 3 цифры результата преобразования двоичного числа в 2-10
Получив данные из LS я умножаю их на 0625 и получаю температуру с 4 знаками после запятой....
... пытаюсь объяснить, что все эти умножения не нужны при хранении дробной части отдельно.......
Код:
; таблица дробной части (12-битное преобразование) table: .db '0','0','0',0' .db '0','6','2',5' .db '1','2','5','0' ....... .db '9','3','7',5' ; всего 16 строк по 4 символа ............... ............... ; дробная часть в temp - диапазон 0b0000...0b1111 ldi ZL,low(table*2) ldi ZH,high(table*2) rol temp rol temp ; temp=temp*4 add ZL,temp clr temp adc ZH,temp ; четыре команды LPM с инкрементом Z вытянут дробную часть из таблицы ..................
Последний раз редактировалось ChipKiller Пн май 02, 2011 13:39:38, всего редактировалось 1 раз.
To Jack_A, ваш код работает спасибо, но подобный вариант я уже пробовал. Проблема в том что при значении температуры XX.4 или XX.8 выдается значение на 0.1 больше действительного. В чем может быть проблема?
Перечитал последние две страницы ветки - полностью согласен с ChipKiller, никакие умножения-делиния тут совсем не нужны. А поскольку, опять же согласен с ChipKiller, 1/10000 градуса - это ненаучная фантастика, то десятые доли градуса для значений дробной части 0000...1111 будут 0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9 соответственно (с округлением в ближайшую сторону). И никаких сдвигов аргумента не надо ( 2 раза rol temp убрать ) А что иногда двум соседним значениям аргумента соответствуют одинаковые цифры - а как же может быть иначе, ведь вариантов аргумента 16 ( 0000...1111), а десятичных цифр всего 10.
Заголовок сообщения: Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн май 02, 2011 19:15:00
Встал на лапы
Зарегистрирован: Вс фев 27, 2011 01:01:11 Сообщений: 86 Откуда: Республика Крым
Рейтинг сообщения:0
Skyer писал(а):
Решил проблему. Косяк в протеусе, датчик выдает 15.5625 а на датчике 15.6. Поэтому показания плавали. Всем спасибо
Да, в общем-то никакого косяка там нет. Температура при симуляции выставляется с точностью 0,1 градус. Поскольку у датчика дискретность дробной части идет с шагом 0,0625 градуса, то в Scratchpad устанавливается значение, которое при округлении дает то, что вы выставляете в симуляторе. Округлите 15.5625 с точностью до 1 десятой (шаг симулятора) и получите 15.6
_________________ Опыт и мудрость приходят с годами... К некоторым годы приходят одни...
И никаких сдвигов аргумента не надо ( 2 раза rol temp убрать ....
... умножение на 4 (длина выводимой дробной части - 4 символа) нужно для правильного расчета смещения от начала таблицы и без него никак.....
Вы сами себе противоречите. Поскольку тут уже все пришли к консексусу , что выводить на табло, к примеру, 32.5625 гр. - это, мягко говоря, идиотизм, выводить будем после точки одну цифру - десятые доли градуса с округлением в ближайшую сторону. Для 16 возможных значений дробной части 0000...1111 возможны только 10 значений цифры после точки, как я и привел постом выше, а эта таблица и занимет ровно 16 байт с учетом того, что некоторые соседние цифры одни и те же. В этой таблице уже учтен и пересчет, и округление. Или я чего-то не догоняю, и мы собираеися, под дружное ржанье понимающей публики, все-таки выводить 41.8125 гр. ?
Заголовок сообщения: Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пн май 02, 2011 23:54:11
Встал на лапы
Зарегистрирован: Вс фев 27, 2011 01:01:11 Сообщений: 86 Откуда: Республика Крым
Рейтинг сообщения:0
Jack_A писал(а):
... выводить на табло, к примеру, 32.5625 гр. - это, мягко говоря, идиотизм... Или я чего-то не догоняю, и мы собираеися, под дружное ржанье понимающей публики, все-таки выводить 41.8125 гр. ?
Абсолютно согласен
Skyer писал(а):
ChipKiller, к сожалению только щас понял простоту и гениальность вашего метода. Но натыкаюсь на иероглифы при выводе. Вот код:
ChipKiller, к сожалению только щас понял простоту и гениальность вашего метода. Но натыкаюсь на иероглифы при выводе. Вот код:
... метод этот не мой и называется табличное преобразование. Преимущество - простота и скорость, недостаток - иногда ест чуть больше Flash. Теперь на счет иероглифов - в Вашей программе определение выводимых символов описано так:
PS. очень рекомендую чаще использовать определения через .egu и макросы, читать и изменять такую программу всегда проще... Когда "наиграетесь с супер точностью" сделайте величину дробной части 2-х символьной - вполне хватит и размер таблицы TempTable уменьшится вдвое
Chipkiller, насчет метода, в программировании всегда так: либо программа требует памяти и работает быстро, либо экономит память и жрет процессор. Поэтому после написания своего варианта, задумался как сделать это быстрее.
Что касаемо иероглифов, причем тут DcMatrix? Это матрица для преобразования в код 7-сегментного индикатора. Я планировал из TempTable вытаскивать цифры, округлять и потом выводить результат на индикацию.
P.S. Макросы пока не использую, в будущем пока. А что с equ? Сам стараюсь их использовать, так как это удобнее.
Что касаемо иероглифов, причем тут DcMatrix? Это матрица для преобразования в код 7-сегментного индикатора. Я планировал из TempTable вытаскивать цифры, округлять и потом выводить результат на индикацию.
... при том, что процедуру Display нужно переписать, а из TempTable нужно вытаскивать не цифры, а символы, иначе все "прелести табличного преобразования" теряют смысл....
Skyer писал(а):
А что с equ? Сам стараюсь их использовать, так как это удобнее.
Подскажите пожалуйста: SETB P1.3; (P1)=27H; (PC)=127H Команда производит запись 1 в бит. Какая используется адресация для операнда-источника и операнда-приемника? и что чему будет равно?
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 22
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения