VitalForce 67 Report post Posted October 11, 2015 Возникла необходимость записать число (пусть будет 377) в память. Методом проб, ошибок и эксперементов удалось получить желаемый результат, но думаю как-то это не правильно (в общем считаю, что у меня делается это через одно место). Мой вариант: Имеется переменная (O) со значением 377. Необходимо ее запомнить, потом считать при необходимости В ячейку EEPROM можно записать число 255 (максимум, как не пытался. может плохо пытался). Записываю 255 в 0 (нулевой) адрес. Остатки записываю в 1-й адрес. Считываю так читаем 0 адрес пишем в I читаем 1 адрес пишем в U O = I + U Что я получаю в итоге? Маленький диапазон температур с которыми можно работать от 25,5 до 51 градуса. ****************************************************************** Итак. Как же реализовать запись, чтоб можно было работать во всем диапазоне температур? (в диапазоне позволяющий датчиком) Может если выйдет урок по этой теме будет понятнее. Заранее всем спасибо. Share this post Link to post Share on other sites
v1ct0r 173 Report post Posted October 12, 2015 В ячейку EEPROM можно записать число 255 (максимум, как не пытался. может плохо пытался). больше и не получится максимальное значение в шестнадцатиричном коде FF, в двоичном коде 1111 1111 или в десятичном 255 Записываю 255 в 0 (нулевой) адрес. Остатки записываю в 1-й адрес. Считываю так читаем 0 адрес пишем в I читаем 1 адрес пишем в U O = I + U Что я получаю в итоге? Маленький диапазон температур с которыми можно работать от 25,5 до 51 градуса. ****************************************************************** Итак. Как же реализовать запись, чтоб можно было работать во всем диапазоне температур? (в диапазоне позволяющий датчиком) а если попробовать записывать в ячейку с "0" адресом записывать целые значения градусов, а ячейку с адресом "1" десятые доли градуса, правда не знаю как это реализовать программно, но думаю можно 1 VitalForce reacted to this Share this post Link to post Share on other sites
VitalForce 67 Report post Posted October 12, 2015 Было бы супер, уже думал. Целые значения извлечь могу, а как быть с десятыми... 377 получается из формулы = TerA * 10 + TerC (где TerA целые значения, TerC - десятичные). Вот с десятичными и загвоздка. Если бы значение приходило с датчика, то проблем нет. Но значение приходит от "пользователя" . То есть счетчик работает уже с преобразованным числом. Может есть какой-то вариант разложить число? Чую, что где-то близко ползаю, но пока не допендрил. Share this post Link to post Share on other sites
v1ct0r 173 Report post Posted October 12, 2015 Было бы супер, уже думал. Целые значения извлечь могу, а как быть с десятыми... 377 получается из формулы = TerA * 10 + TerC (где TerA целые значения, TerC - десятичные). Вот с десятичными и загвоздка. Если бы значение приходило с датчика, то проблем нет. Но значение приходит от "пользователя" . То есть счетчик работает уже с преобразованным числом. Может есть какой-то вариант разложить число? Чую, что где-то близко ползаю, но пока не допендрил. вряд ли я вам помогу чем то, программирование не мой профиль, может еще кто подтянется, но в любом случае вам следовало бы подробно объяснить суть проблемы. что значит: "от пользователя", преобразованное число, разложить число на какие части и т.д.? Share this post Link to post Share on other sites
VitalForce 67 Report post Posted October 12, 2015 Плюсовать получилось: 377=TerU = TerUC * 10 + TerUD plus: TerUD = TerUD + 1 if TerUD > 9 then TerUD = 0 TerUC = TerUC + 1 endif write 0, TerUC write 1, TerUD pause 1000 goto main С отниманием косяк: minus: TerUD = TerUD - 1 if TerUD < 0 then TerUD = 9 TerUC = TerUC - 1 endif write 0, TerUC write 1, TerUD pause 1000 goto main Что происходит при отнимании: На индикаторе TerUC=37 TerUD=7 TerU=377 Начинаю отнимать TerUC=37 TerUD=6 TerU=376 TerUC=37 TerUD=5 TerU=375 ....... TerUC=37 TerUD=0 TerU=370 TerUC=37 TerUD=5 TerU=369 То есть сразу же после "0" появляется "5". И если продолжить отнимание, то оно будет с 5, а не с 9, как должно быть. Я в ступоре. P.S. "от пользователя" Какое число понажимал пользователь по кнопкам. Share this post Link to post Share on other sites
v1ct0r 173 Report post Posted October 12, 2015 TerUC=37 TerUD=5 TerU=369 37 это опечатка? может 36 Share this post Link to post Share on other sites
VitalForce 67 Report post Posted October 12, 2015 Нет, не опечатка. Именно так выводится на экран. Хоть и "TerU" показывает правильно Share this post Link to post Share on other sites
VitalForce 67 Report post Posted October 12, 2015 TerUC=37 TerUD=5 TerU=369 Нажимаю "плюсик" TerUC=37 TerUD=0 TerU=370 Отнимаю TerUC=37 TerUD=5 TerU=369 TerUC=37 TerUD=4 TerU=368 TerUC=37 TerUD=3 TerU=367 TerUC=37 TerUD=2 TerU=366 TerUC=37 TerUD=1 TerU=365 TerUC=37 TerUD=0 TerU=364 TerUC=37 TerUD=9 TerU=363 TerUC=37 TerUD=8 TerU=362 TerUC=37 TerUD=7 TerU=361 TerUC=37 TerUD=6 TerU=360 TerUC=37 TerUD=5 TerU=359 TerUC=37 TerUD=4 TerU=358 TerUC=37 TerUD=3 TerU=357 TerUC=37 TerUD=2 TerU=356 TerUC=37 TerUD=1 TerU=355 TerUC=37 TerUD=0 TerU=354 Плюсую TerUC=38 TerUD=0 TerU=380 Отнимаю TerUC=38 TerUD=5 TerU=379 Плюсую TerUC=38 TerUD=0 TerU=380 Share this post Link to post Share on other sites
v1ct0r 173 Report post Posted October 12, 2015 т.е. получается что вычисляет программа правильно, а значения переменных TerUC и TerUD отображает при индикации не правильно? Share this post Link to post Share on other sites
Evgeniy 285 Report post Posted October 12, 2015 Числа выше 255 - это двухбайтовые числа, и при записи в EEPROM записываются 2 байта! Естественно переменные должны быть объявлены как WORD. 1 VitalForce reacted to this Share this post Link to post Share on other sites
Evgeniy 285 Report post Posted October 12, 2015 terUD меньше нуля неможет быть! Если от нуля отнять единицу, будет 255! Попробуй условие поменять на if terUD > 9.... 1 VitalForce reacted to this Share this post Link to post Share on other sites
VitalForce 67 Report post Posted October 12, 2015 Жень, ты прям чуял, что тебя тут ждут. И спасибо за видео урок Сча сделаю уроки (№9) потом буду ковырять у себя. Share this post Link to post Share on other sites
VitalForce 67 Report post Posted October 12, 2015 Получилось. minus: TerUd = TerUd - 1 if TerUd > 9 then '0-1=255 terud = 9 teruc = teruc - 1 endif write 0, TerUc write 1, TerUd pause 1000 goto main Share this post Link to post Share on other sites
VitalForce 67 Report post Posted October 12, 2015 Поэксперементировал немного. на экран выводил так LCDOUT " TerUD ",dec terud (то есть мне как бы больше одного значения не нужно) Если от нуля отнять единицу, будет 255! Решил проверить что же мне там выдавало. LCDOUT " TerUD ",dec5 terud (так и оказалось 255, а если "TerUD var WORD" - 65535) тоесть всеравно бы показывало мне "5" Это я так, на земетку, на будущее. Share this post Link to post Share on other sites
Evgeniy 285 Report post Posted October 15, 2015 Быстро учишся! Молодец! В некоторых программах я счёт повышают на единицу, а при индикации из переменной сначала вычитаю эту единицу. Это как вариант. Share this post Link to post Share on other sites
VitalForce 67 Report post Posted November 12, 2015 Есть ли другой способ (короче код) записать данные в EEPROM или это оптимально? data @8, $28,$30,$C7,$B8,$00,$00,$00,$0D,$28,$37,$C6,$B8,$00,$00,$00,$45,$28,$36,$C5,$B8,$00,$00,$00,$3C 'dlabel data @8, word 2896034153487138829 'Слишком большое число (макс 65535) 'dlabel data @16, word 2898003378812485701 'dlabel data @24, word 2897720804324147260 '2830C7B80000000D = 2896034153487138829 '2837C6B800000045 = 2898003378812485701 '2836C5B80000003C = 2897720804324147260 И как короче считать? ReadID: read 8, ID1[0] read 9, ID1[1] read 10, ID1[2] read 11, ID1[3] read 12, ID1[4] read 13, ID1[5] read 14, ID1[6] read 15, ID1[7] read 16, ID2[0] read 17, ID2[1] read 18, ID2[2] read 19, ID2[3] read 20, ID2[4] read 21, ID2[5] read 22, ID2[6] read 23, ID2[7] read 24, ID3[0] read 25, ID3[1] read 26, ID3[2] read 27, ID3[3] read 28, ID3[4] read 29, ID3[5] read 30, ID3[6] read 31, ID3[7] pause 50 return Share this post Link to post Share on other sites
VitalForce 67 Report post Posted November 12, 2015 Короче получилось одной строкой read 8, id1[0],ID1[1],ID1[2],ID1[3],ID1[4],ID1[5],ID1[6],ID1[7],id2[0],ID2[1],ID2[2],ID2[3],ID2[4],ID2[5],ID2[6],ID2[7],id3[0],ID3[1],ID3[2],ID3[3],ID3[4],ID3[5],ID3[6],ID3[7] А еще как-то короче можно? Share this post Link to post Share on other sites
VitalForce 67 Report post Posted November 12, 2015 В общем хочу код поджать, ато уже не влезает в камень 628А. А в планах еще пару условий... Share this post Link to post Share on other sites
Evgeniy 285 Report post Posted November 13, 2015 Используя цикл for i=0 to 7 Read i, id1 Next i для второго датчика Read 7+i,id2 Как то так. 1 VitalForce reacted to this Share this post Link to post Share on other sites
VitalForce 67 Report post Posted November 13, 2015 Пробовал, получается длиннее, чем одной строкой читать. А вот не получается сделать цикл на измерение температуры. На третий датчик не хватает места. DS18B20: OWOUT DQ, 1, [$55, str ID1\8, $44] ' Çàïðîñ íà ïîëó÷åíèå äàííûõ ReadBusy: OWIN DQ, 4, [busy] ' If Busy = 0 Then ReadBusy ' Æäåì îêàí÷àíèÿ îáðàáîòêè OWOUT DQ, 1, [$55, str ID1\8, $BE] ' ×èòàåì äàííûå OWIN DQ, 2, [RAWTEMP.LowByte, RAWTEMP.HighByte] ' ×èòàåì òåìïåðàòóðíûå äàííûå 'return '*******************************Êîíâåðòàöèÿ òåìïåðàòóðû ñ äàò÷èêà*************** 'CalcC: If SignBit <> 1 Then TerC1 = rawtemp / 16 TerD1 = (rawtemp // 16) * 10 / 16 TempA1 = TerC1 * 10 + TerD1 Else TerC1 = 65535 - rawtemp tempdat1 = TerC1 + 1 TerC1 = tempdat / 16 TerD1 = ((tempdat1 + 1) // 16) * 10 / 16 TempA1 = TerC1 * 10 + TerD1 EndIf If SignBit = 0 Then SignC1 = "+" Else SignC1 = "-" EndIf if tempa1 = 0 then signc1 = " " endif RETURN И такой код 3 раза, для 3 датчиков. Плюс переменные для каждого. В общем тут у меня "раздутое" место. Даже если убрать условие для определения "+\-", не влезею буквально на 2 адреса. Так еще и условие не задано для 3-го датчика. Share this post Link to post Share on other sites
VitalForce 67 Report post Posted November 13, 2015 Наверное над отдохнуть, моск кипит Share this post Link to post Share on other sites
Evgeniy 285 Report post Posted November 13, 2015 Тут либо камень менять на pic16f88, появиться куча памяти, по ногам проц совпадает с 628. Либо оптимизировать программу. Если 4 датчика, значит делать цикл в 4 прохода. При каждом проходе меняться будут только адреса считывания id датчиков и переменные температуры с признаком -. Остальные переменные общие. Программа немного будет отличаться от программы для одного датчика. Зачем считывать id датчика в переменные? Можно циклом за раз считать и тут же отправить одно число в датчик, и так 8 раз. В цикле писать так For i = adr to adr+8 Read adt,temp Owout.... [Temp] Next i Так мы отправил датчиками нужный id В самом начале создаём цикл изходя из количества датчиков. Например For proh = 0 to 3 Lookup proh,[0,7,15,23], adr 'адреса id в EEPROM Потом читаем и отправляем id Идём на подпрограмму измерения температуры Tempcel[proh] = tempcel ' переписывания температуру в индивидуальную переменную Tempdes[proh] = tempdes Cold[proh] = cold Next proh По окончании цикла мы будем иметь 4 значения температуры из 4датчиков Temp1 Temp2 Temp3 Temp4 Потом заморачиваемся с отображением температур и остального. Как то так 1 VitalForce reacted to this Share this post Link to post Share on other sites