Форум » Для начинающих. » Сравнить два байта » Ответить

Сравнить два байта

Ivan555: Всем привет! Помогите сравнить два байта. Что-то у меня не получается. Как сравнить один байт я могу, а вот с двумя байтами результат получается не тот, который ожидаю. Есть контроллер 16F676. У него 10 -ти разрядный АЦП. Измеряю напряжение, считываю результат в два байта. Как их сравнить правильно. Помогите, пожалуйста. В нете описывается команда cmp, а MPLAB на нее ругается. И очень много описаний для AVR. Для PIC я ничего конкретного не нашел.

Ответов - 21

lowbyte: Речь, вероятно, об АСМе. Сравнение - это ВЫЧИТАНИЕ. Соманды CMP в системе команд 16-х ПИКов нет. Для сравнения нужно произвести вычитание с результатом в аккумуляторе (чтобы не испортить исходные операнды). И по состоянию флага C регистра STATUS определить больше или равно (больше), т.е. ЗНАК результата. В 18-х ПИКах есть команды сравнения с пропуском следующей команды по условию: CPFSEQ, CPFSLT, CPFSGT

Alex: Ivan555 пишет: Помогите сравнить два байта.Сравнить с чем ? И что значит сравнить? Больше, меньше, равно .... ? Поподробнее можно...

MAZ: [pre2] Простое сравнения двух беззнаковых 16-разрядных чисел ; X и Y. старший байт H, младший байт L movf HX, W subwf HY, W btfss STATUS, C goto Xbol ; результат: X> Y btfss STATUS, Z goto Ybol ; результат: Y> X movf LX, W subwf LY, W btfss STATUS, C goto Xbol ; результат: X> Y btfss STATUS, Z goto Ybol ; результат: Y> X goto XequY ; результат: X = Y [/pre2]


Ivan555: Спасибо всем за ответы. Огромное спасибо MAZ за конкретный пример. Буду пробовать. То что нужно. Alex пишет: Сравнить с чем ? И что значит сравнить? Больше, меньше, равно .... ? Поподробнее можно... Полученный результат два байта от АЦП мне нужно сравнить с двумя байтами вставки и относительно ее принять решение о результате больше, меньше или равно. Если еще подробнее, то мне необходимо, помимо основной задачи, измерять температуру внутри корпуса. Температуру меряю с помощью термистора. Мне нужно чтоб при напряжении примерно 1 В (87 град) сработала защита, а при напряжении примерно 2,5 В (50 град) выключилась. Напряжение 2,5 В выходит за границы одного байта и вот тут у меня возникли трудности. Еще раз всем спасибо. Очень помогли.

SanSanich: MAZ Прикольная сравниловка, главное исчерпывающая и конкретная. По любому в базу ПП надо. Только коменты проставить, чтоб алгоритм при использовании в мозгах начинающих "прописывался". А на её основе и с большей байтностью не проблема составить. Кстати, есть код по температуре как раз при работе с термосопротивлением. Может пригодится, правда он для работы с куллером и включения защиты. Ещё там есть небольшой нюанс с отрицательной температурой и выводом на ЖК (если температура выходит из диаппазона 0-100 грд). Но отработка работает. [pre2] ;TERMO_CONTROL bsf ADCON0,2 ;start ADC btfsc ADCON0,2 goto $-1 movf ADRESH,w movwf TRM_H bsf STATUS,RP0 movf ADRESL,w bcf STATUS,RP0 movwf TRM_L CHK_TRM movf TRM_H,w movwf ARG_H movf TRM_L,w movwf ARG_L bcf STATUS,C ;divide by 2 rrf ARG_H,f rrf ARG_L,f movlw HIGH(.87) ;вычитаем xxx* movwf TEMP movlw LOW(.87) subwf ARG_L,f ;SUB THE LOW BYTE movf TEMP,w btfss STATUS,C incfsz TEMP,w subwf ARG_H,f ;SUB THE HIGH BYTE call BCD movf R1,w movwf TRM_1 movf R2,w movwf TRM_2 movf TRM_H,w ;датчик отвалился ? addwf TRM_L,w btfss STATUS,Z goto CHK_70 bsf LEDOUT,E_TMR ;yes, blink LED btfsc SEC,0 bcf LEDOUT,E_TMR clrf TRM_2 ;set TERM to 00"C goto CHK_TRM_END CHK_70 bcf LEDOUT,E_TMR movf TRM_H,w movwf ARG_H movf TRM_L,w movwf ARG_L movlw HIGH(TEMP_70) ;вычитаем 70* movwf TEMP movlw LOW(TEMP_70) subwf ARG_L,f ;SUB THE LOW BYTE movf TEMP,w btfss STATUS,C incfsz TEMP,w subwf ARG_H,f ;SUB THE HIGH BYTE btfss STATUS,C goto CHK_55 ;<70* btfsc ERR_TMR ;set ERR_TMR ? goto CHK_TRM_END ;yes, exit clrf FLAG ;>70* bsf ERR_TMR goto SHUT_OFF ;power OFF CHK_55 movf TRM_H,w movwf ARG_H movf TRM_L,w movwf ARG_L movlw HIGH(TEMP_55) ;вычитаем 55* movwf TEMP movlw LOW(TEMP_55) subwf ARG_L,f ;SUB THE LOW BYTE movf TEMP,w btfss STATUS,C incfsz TEMP,w subwf ARG_H,f ;SUB THE HIGH BYTE btfss STATUS,C ;<55* goto CHK_40 bsf COOL ;yes, cooler ON goto CHK_TRM_END CHK_40 bcf ERR_TMR movf TRM_H,w movwf ARG_H movf TRM_L,w movwf ARG_L movlw HIGH(TEMP_40) ;вычитаем 40* movwf TEMP movlw LOW(TEMP_40) subwf ARG_L,f ;SUB THE LOW BYTE movf TEMP,w btfss STATUS,C incfsz TEMP,w subwf ARG_H,f ;SUB THE HIGH BYTE btfss STATUS,C ;<40* bcf COOL ;cooler OFF CHK_TRM_END [/pre2]

Alex: SanSanich пишет: Прикольная сравниловка, главное исчерпывающая и конкретная.Да, прикольная получилась На её основе сделал макрос, позволяющий сравнивать 2 переменные n-ного размера. Ссылка

SanSanich: Alex Алекс, хорошо бы алгоритмы в коментах.

Ivan555: Спасибо SanSanich и Alex . Очень помогли. MAZ еще раз спасибо! SanSanich пишет: А на её основе и с большей байтностью не проблема составить. Полностью согласен. Спасибо. На выходных буду заниматься изучением.

MAZ: SanSanich пишет: Только коменты проставить, А я и поставил по результату. Что писать, вычесть старший байт числа Х из старшего байта числа Y? Кажется и так понятно. Если свойства флагов С и Z известно, то и писать нечего. На мой взгляд. А вот про эти свойства наверно можно отдельно написать. Ivan555 На здоровье. Чем можем, поможем. Еще совет. При работе с термистором. Возможно на границах контрольных температур, нужно сделать небольшой гистерезис. Особенно если используется регулировка. Например, температура скачет 50 -51 град. Исполнительное устройство включается/выключается. Гистерезис хотя бы в 2 градуса, устранит эту неприятность.

SanSanich: MAZ пишет: Кажется и так понятно. Здесь да. Но иногда используются нестандартные подходы. Автору всё понятно, а вот новичёк может не догнать, почему именно так. Кстати, lowbyte и написал метод, вычитанием, но вот как всё это организовать не всегда понятно. По сути, вычитаем старшие байты и проверяем флаг переноса C и на 0 флаг Z. Если не 0, сравнение однозначно и по результату уходим на соответствующую метку. Если старшие байты равны, таким же образом проверяем младшие байты. Во всяком случае, не помешает. Вы заметили, что на PIC Microcontoller Basic Math Methods вначале прописан алгоритм, затем код. Вот только языковой барьер существенно осложняет понимание!

Ivan555: Спасибо за совет MAZ. У меня задумка была такая. Основная часть программы исполняется до тех пор, пока температура не выйдет за верхний предел (87 град). Опрос делаю с периодичностью 0,5 с. Если есть факт превышения, то устанавливаю флаг и ухожу в подпрограмму. В этой подпрограмме у меня идет индикация защиты от превышения температуры и с частотой 0,5 с идет опрос температуры. Если она станет ниже 50 град, тогда выйду. Иначе буду крутиться "вечно", пока температура не станет ниже 50 град. Особой точности мне тут не нужно. Нижний предел пока расчетный. На практике будет видно. Может подниму до 60. Если что-то не так, то подправьте. SanSanich пишет: Автору всё понятно, а вот новичёк может не догнать, почему именно так. Я тоже новичок. Делаю первые шаги в этом не простом деле, но ПП MAZa мне без лишних комментариев стала понятна. Главное здесь четко представлять работу флагов С и Z. Мое личное мнение.

lowbyte: Помимо программных изысков по сравнению чисел, автору стоит помнить так же, что любая САУ (а имеем в наличии именно систему автоматического управления температурой) может самовозбуждаться. И получить такой колебательный процесс в цифровой САУ совсем не трудно...

MAZ: Ivan555 Я просто рассуждаю. 87 градусов. Значит есть какой нагреватель, который чем то управляется (реле, тиристор, транзистор и т.п.) Превышение 87 градусов, следует выключение нагревателя. Как будто логично. Температура немного повышается и начинать уменьшаться. На 86 опять включение нагревателя. Немножко не понятно. Вы говорите про только индикацию, но не про действия. Индикация вторично. Как правильно заметил lowbyte, если у Вас система с обратной связью? Как будто просматривается. Посмотрите здесь. Может поможет.

fox: MAZ пишет: И получить такой колебательный процесс в цифровой САУ совсем не трудно... То есть МК может стать генератором колебаний? Даже при наличии отрицательной обратной связи? А что для этого нужно?

MAZ: Это не я писал. Вопрос к lowbyte. Думаю, имелась ввиду ошибка самовозбуждения любой системы с ОС. Из теории автоматики.

fox: Дааа? Я-то думал, что это как-то связано с проблемой сравнения двух байтов

lowbyte: Вопрос об устойчивости возник в связи с упоминанием ТС НАЗНАЧЕНИЯ проектируемого устройства, есличо. К вычитанию и сравнению байтов это не имеет прямого отношения. Однако косвенное имеет. Устойчивость петли регулирования определяется ее петлевым усилением в диапазоне частот (возмущающих воздействий). И задержкой в этой петле. Отрицательная или положительная будет обратная связь - автор темы даже не выяснял. Фаза ОС на постоянном токе может быть и отрицательной, что не гарантирует ее сохранение при изменении сигнала возмущения с различной скоростью.

Ivan555: Спасибо за ответы. MAZ пишет: Немножко не понятно. Вы говорите про только индикацию, но не про действия. Индикация вторично. Как правильно заметил lowbyte, если у Вас система с обратной связью? Как будто просматривается. . Вообщем есть задумка сделать некий универсальный таймер с температурной защитой от перегрева внутри корпуса. В последнее время это стало очень актуально. Все больше и больше различных приборов появляются с таким дополнением. Вот и я захотел потренироваться в этом направлении. Основная задача устройства это универсальный таймер. Основным исполнительным элементом таймера является электромагнитное реле. Нагрузка подключается в встроенную розетку корпуса таймера. При плохом контакте или перегрузки исполнительного элемента температура в корпусе будет увеличиваться. Вот ее я в основной программе таймера и отслеживаю. Если она выйдет за допустимый предел, то мне нужно выключить исполнительный механизм, вывести на индикацию это событие, заблокировать управление таймером, подождать когда она вернется в допустимый предел и выйти на исходную позицию таймера. lowbyte пишет: Помимо программных изысков по сравнению чисел, автору стоит помнить так же, что любая САУ (а имеем в наличии именно систему автоматического управления температурой) может самовозбуждаться. И получить такой колебательный процесс в цифровой САУ совсем не трудно... Спасибо за замечание. Теперь я думаю хватит ли одного сравнения с вставкой или необходимо несколько сравнений. Если нужно несколько сравнений и вычисления среднего, то это для меня пока трудно. Можно было поставить цифровой датчик DS18B20, но это сильно удорожает устройство. С датчиком DS18B20 и 1-wire я знаком. Теперь особый интерес вызывает работа с аналоговым датчиком.

MAZ: Поставьте термопару. Дешево и сердито.

Ivan555: Ура! Все заработало. Всем спасибо за ценные ответы. Очень помогли. Сделал по примеру MAZ. Теперь работает как нужно. Сделал еще дополнительную проверку на кз или обрыв термодатчика.

Photographer:



полная версия страницы