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

Преобразование Знакового Числа Из Дополнительного Кода В Прямой


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

У меня термодатчик вырабатывает импульсы, а таймеры их считают.

Судя по программе, она считает скважность импульсов с датчика.

Никогда не спорьте с дураком - люди могут не заметить между вами разницы

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

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

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

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

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

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

Во, черт, новый удар.

Почему режим работы таймеров (16-разрядный) задается уже после условного перехода?

...
mov TL1,#0 ;обнуление таймера 1
WAIT_LO:
jb	 TMPIN,WAIT_LO ;ожидание низкого уровня сигнала
mov TMOD,#11h ;задание 16-разрядного режима работы таймеров
WAIT_HI:
...

Надо пораньше, косяк :)

Во, черт, новый удар.

Почему режим работы таймеров (16-разрядный) задается уже после условного перехода?

...
mov TL1,#0 ;обнуление таймера 1
WAIT_LO:
jb	 TMPIN,WAIT_LO ;ожидание низкого уровня сигнала
mov TMOD,#11h ;задание 16-разрядного режима работы таймеров
WAIT_HI:
...

Надо пораньше, косяк :)

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

В коде ..... В регистрах r5:r4 находится разница

Это они погорячились. Четыре байта нужно сохранять до конца вычислений.

а что, разве при делении у нас не 2 байта остается? Если мы 4-х байтовое на 2-хбайтовое делим, должно же 2 байта оставаться, или не? :)

Вот что в даташите написано. Да там правильно все, преподаватель проверял. Значит теперь вопрос в следующем: задействовать какой-нибудь флаг, чтобы знать знак на выходе. Такого скилла у меня нет :) Флаг переполнения, как я понял, мы здесь уже учесть не можем. А других флагов я и не знаю :)

post-180778-0-40476900-1400617382_thumb.jpg

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

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

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

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

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

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

а что, разве при делении у нас не 2 байта остается? Если мы 4-х байтовое на 2-хбайтовое делим, должно же 2 байта оставаться, или не?

Не. Если скважность очень мала, то может получиться и больше 2-х. В даташите должны быть указаны границы скважности. Но в данном случае, скорее всего 2-х байт хватит. Ведь это температура, она не может здесь быть выше 235 или ниже -273oC.

А других флагов я и не знаю

Используйте любой свободный регистр или ячейку памяти.

Нужно же индицировать знак температуры, а он у вас теряется в подпрограмме преобразования.

Изменено пользователем Григорий Т.

Никогда не спорьте с дураком - люди могут не заметить между вами разницы

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

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

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

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

Еще обратил внимание, что в регистры r4-r7 и r2-r3 заносятся константы, а не данные из регистров таймеров/счетчиков.

...
;заносим в сумму Х .
; берем из таймера0
mov r7,#00
mov r6,#00
mov r5,#10h
mov r4,#20h
...

; Деление	 сумма/Т2
; (r7:r6:r5:r4)/(r3:r2) = r5:r4
;
; делитель берем из таймера1
mov	 r3,#05h ; старший байт
mov	 r2,#10h ; младший байт

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

Сейчас рассмотрел на картинке, что необходимо рассчитывать скважность сигнала датчика, а не количество импульсов. Вы, Pragmatik91, изначально ввели в заблуждение о подсчете количества импульсов с датчика, вот и появились вопросы.

Наверное, это верный участок кода. Я повелся на комментарий, т.к. не помню команд. Комментарий для ясности можно было дополнить, что производится запуск счета.

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

Не. Если скважность очень мала, то может получиться и больше 2-х. В даташите должны быть указаны границы скважности. Но в данном случае, скорее всего 2-х байт хватит. Ведь это температура, она не может здесь быть выше 235 или ниже -273oC.

TMP03/TMP04 имеют рабочий температурный диапазон от -40°C до +100°C

Используйте любой свободный регистр или ячейку памяти.

Нужно же индицировать знак температуры, а он у вас теряется в подпрограмме преобразования.

Это мне нужно делать после вычитания из 235? А как я узнаю, что получилось отрицательное число? В регистре переполнения будет 1 после вычитания, или как? :)

Еще обратил внимание, что в регистры r4-r7 и r2-r3 заносятся константы, а не данные из регистров таймеров/счетчиков.

...
;заносим в сумму Х .
; берем из таймера0
mov r7,#00
mov r6,#00
mov r5,#10h
mov r4,#20h
...

; Деление	 сумма/Т2
; (r7:r6:r5:r4)/(r3:r2) = r5:r4
;
; делитель берем из таймера1
mov	 r3,#05h ; старший байт
mov	 r2,#10h ; младший байт

Это я ставил для проверки работоспособности программы. Так потом данные будут браться со счетчиков.

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

Вычитание есть сумма двух операндов. Операнды представляются либо в обратном коде, либо в дополнительном коде.

В примере ниже частное Т1/Т2 представлено числом 240. Т.е. результирующая температура равна минус 5 градусов (235-240=-5).

Введем знаковый разряд в числа (старший бит).

235 0000 0000 1110 1011

240 0000 0000 1111 0000

-240 1000 0000 1111 0000

-240обр 1111 1111 0000 1111

+1 0000 0000 0000 0001

-240доп 1111 1111 0001 0000

сумма

235 0000 0000 1110 1011

-240доп 1111 1111 0001 0000

Тдоп 1111 1111 1111 1011

Sдоп.инв 1000 0000 0000 0100

+1 0000 0000 0000 0001

Т 1000 0000 0000 0101

Итого единица в старшем разряде - температура отрицательная. Остальной код соответствует числу 5. Итого минус пять.

Не забывать, что ответ получен в двоичном виде. Для выводана экран необходимо преобразование в двоично-десятичный со всеми вытекающими.

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

Вычитание есть сумма двух операндов. Операнды представляются либо в обратном коде, либо в дополнительном коде.

В примере ниже частное Т1/Т2 представлено числом 240. Т.е. результирующая температура равна минус 5 градусов (235-240=-5).

Введем знаковый разряд в числа (старший бит).

235 0000 0000 1110 1011

240 0000 0000 1111 0000

-240 1000 0000 1111 0000

-240обр 1111 1111 0000 1111

+1 0000 0000 0000 0001

-240доп 1111 1111 0001 0000

сумма

235 0000 0000 1110 1011

-240доп 1111 1111 0001 0000

Тдоп 1111 1111 1111 1011

Sдоп.инв 1000 0000 0000 0100

+1 0000 0000 0000 0001

Т 1000 0000 0000 0101

Итого единица в старшем разряде - температура отрицательная. Остальной код соответствует числу 5. Итого минус пять.

Не забывать, что ответ получен в двоичном виде. Для выводана экран необходимо преобразование в двоично-десятичный со всеми вытекающими.

как мне сделать так, чтобы узнать, будет ли полученное в итоге деления T1/T2 число больше либо меньше 235? Ввести что-то типа сравнения нужно? И еще - как мне учитывать минус? Перенести после вычитания старший бит в какой либо регистр?

Или просто проверять его типа jnb acc.7, loop ?

;в r7:r6 заносим 235, в r5:r4 - 240
mov r7,#00
mov r6,#235
mov r5,#00
mov r4,#240
;сравниваем
clr C
mov A, r7
subb A, r5
mov A r6
subb A, r4
jnc PLUS
MINUS:

типа такого?

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

На кой черт его проверять? После вычитания все само собой получится. Например, при расчете в дополнительном коде 235-198 Вы получите результат (в дополнительном коде) 1 0000 0000 0010 0100.

Т.к. возникла единица переноса из старшего (знакового) разряда, то при суммировании в дополнительном коде она добавляется к младшему разряду результата. Т.е. получится число 0000 0000 0010 0101. При этом в старшем (знаковом разряде) остался ноль, значит результат положительный, значит дополнительный код совпадает с прямым, значит ответ: плюс 37.

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

На кой черт его проверять? После вычитания все само собой получится. Например, при расчете в дополнительном коде 235-198 Вы получите результат (в дополнительном коде) 1 0000 0000 0010 0100.

Т.к. возникла единица переноса из старшего (знакового) разряда, то при суммировании в дополнительном коде она добавляется к младшему разряду результата. Т.е. получится число 0000 0000 0010 0101. При этом в старшем (знаковом разряде) остался ноль, значит результат положительный, значит дополнительный код совпадает с прямым, значит ответ: плюс 37.

Короче мне нужно просто вычитаемое переводить в дополнительный код и после вычитания проверять старший бит, так я понял? :)

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

Короче мне нужно

Ничего вам не нужно, у вас всё есть. :)

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

jnc loop

устанавливаете флаг в единицу.

Никогда не спорьте с дураком - люди могут не заметить между вами разницы

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

Т.к. возникла единица переноса из старшего (знакового) разряда, то при суммировании в дополнительном коде она добавляется к младшему разряду результата.

Вы даже меня запутали :)

Никогда не спорьте с дураком - люди могут не заметить между вами разницы

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

Короче мне нужно

Ничего вам не нужно, у вас всё есть. :)

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

jnc loop

устанавливаете флаг в единицу.

пока так сделал, все по порядку. Домой приду, сделаю, как вы сказали, с метками :) Но думаю и эта работать будет. Если я конечно тут не напутал :)

;в r7:r6 заносим 235, в r5:r4 - 240
mov r7,#00
mov r6,#235
mov r5,#00
mov r4,#240
;переводим вычитаемое в дополнительный код
mov A,R5	    ;заносим младший байт в акк
cpl A    ;инверсия акк
add A,#00000001b  ;прибавляем 1
mov R5, A	   ;младший байт из акка в регистр
mov A, R4	   ;старший байт в акк
cpl A    ;инверсия
addc A,#0	   ;складываем с учетом бита переполнения
mov R4, A	   ;старший байт из акка в регистр
;складываем с числом в дополнительном коде
mov A,R6	    ;заносим младший байт в акк   
add A,r4    ;сложение
cpl A   ;инверсия
add A,#00000001b   ;прибавляем 1 к младшему байту
mov r6, A   ;заносим полученное число в регистр
mov A, r7    ;старший байт в акк
addc A,r5  ;складываем с учетом бита переполнения
cpl A	   ;инверсия
mov R5, A ;число в регистр
end

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

;складываем с числом в дополнительном коде

mov A,R6 ;заносим младший байт в акк

add A,r4 ;сложение

cpl A ;инверсия

add A,#00000001b ;прибавляем 1 к младшему байту

mov r6, A ;заносим полученное число в регистр

mov A, r7 ;старший байт в акк

addc A,r5 ;складываем с учетом бита переполнения

cpl A ;инверсия

mov R5, A ;число в регистр

end

[/code]

А инверсия здесь зачем?

Никогда не спорьте с дураком - люди могут не заметить между вами разницы

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

Короче мне нужно

Ничего вам не нужно, у вас всё есть. :)

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

jnc loop

устанавливаете флаг в единицу.

Как это обнуляю флаг а потом сам его устанавливаю? А если у меня уменьшаемое больше вычитаемого, и я установлю флаг на положительное число, то что это будет?

;складываем с числом в дополнительном коде

mov A,R6 ;заносим младший байт в акк

add A,r4 ;сложение

cpl A ;инверсия

add A,#00000001b ;прибавляем 1 к младшему байту

mov r6, A ;заносим полученное число в регистр

mov A, r7 ;старший байт в акк

addc A,r5 ;складываем с учетом бита переполнения

cpl A ;инверсия

mov R5, A ;число в регистр

end

[/code]

А инверсия здесь зачем?

а как мы обратно из дополнительного в прямой код преобразуем? Нужно делать обратную инверсию, или я не прав? В книжке, которую мне сбросили даже написано: Поскольку сумма есть отрицательное число, то для перевода его в прямой код меняем цифры числа на противоположные. :unknw:

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

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

clr XFLAG ; ************************************************************************* Очищаем флаг, на случай если число положительное
mov R0,#10 ;заносим число
mov R1,#10
mov A,R1 ;заносим старший бит в акк
rlc A ;сдвиг аак на 1 разряд влево
jnc loop ;проверка бита переполнения, если не установлен, переход на метку
inc XFLAG ; *********************************************************************** тут уже известно, что число отрицательное.
mov A,R0 ;заносим младший байт в акк
cpl A ;инверсия акк
add A,#00000001b ;прибавляем 1
mov R0, A ;младший байт из акка в регистр
mov A, R1 ;старший байт в акк
cpl A ;инверсия
addc A,#0 ;складываем с учетом бита переполнения
mov R1, A ;старший байт из акка в регистр
loop:
end

а как мы обратно из дополнительного в прямой код преобразуем?

Здесь ничего не нужно преобразовывать! Здесь вы получаете результат вычислений - положительный или отрицательный.

Изменено пользователем Григорий Т.

Никогда не спорьте с дураком - люди могут не заметить между вами разницы

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

А почему бы в этом коде (ради оптимизации кода)

clr XFLAG ; ************************************************************************* Очищаем флаг, на случай если число положительное
mov R0,#10 ;заносим число
mov R1,#10
mov A,R1 ;заносим старший бит в акк
rlc A ;сдвиг аак на 1 разряд влево
jnc loop ; проверка бита переполнения, если не установлен, переход на метку
inc XFLAG ; *********************************************************************** тут уже известно, что число отрицательное.
mov A,R0 ;заносим младший байт в акк
cpl A ;инверсия акк
add A,#00000001b ;прибавляем 1
mov R0, A ;младший байт из акка в регистр
mov A, R1 ;старший байт в акк
cpl A ;инверсия
addc A,#0 ;складываем с учетом бита переполнения
mov R1, A ;старший байт из акка в регистр
loop:
end

не заменить

rlc A ;сдвиг аак на 1 разряд влево

jnc loop ; проверка бита переполнения, если не установлен, переход на метку

на

jnb A:7, loop; Проверка знакового разряда результата. Если 0 (результат положительный) - переход на метку

Pragmatik91, а нельзя ли в листингах кода выводить номера строк? Мне кажется, тогда гораздо проще будет ориентироваться.

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

mvkarp, де жа вю? :lol2:

Вроде, правильно. Только

rlc A ;сдвиг аак на 1 разряд влево
jnc loop ;проверка бита переполнения, если не установлен, переход на метку

легко меняется на

jnb acc.7,loop

Только что проверил специально на Keil.

Изменено пользователем Григорий Т.

Никогда не спорьте с дураком - люди могут не заметить между вами разницы

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

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

clr XFLAG ; ************************************************************************* Очищаем флаг, на случай если число положительное
mov R0,#10 ;заносим число
mov R1,#10
mov A,R1 ;заносим старший бит в акк
rlc A ;сдвиг аак на 1 разряд влево
jnc loop ;проверка бита переполнения, если не установлен, переход на метку
inc XFLAG ; *********************************************************************** тут уже известно, что число отрицательное.
mov A,R0 ;заносим младший байт в акк
cpl A ;инверсия акк
add A,#00000001b ;прибавляем 1
mov R0, A ;младший байт из акка в регистр
mov A, R1 ;старший байт в акк
cpl A ;инверсия
addc A,#0 ;складываем с учетом бита переполнения
mov R1, A ;старший байт из акка в регистр
loop:
end

а как мы обратно из дополнительного в прямой код преобразуем?

Здесь ничего не нужно преобразовывать! Здесь вы получаете результат вычислений - положительный или отрицательный.

;в r7:r6 заносим 235, в r5:r4 - 240
mov r7,#00
mov r6,#235
mov r5,#00
mov r4,#240
;вычитаем
clr c
mov A, r6
subb A,r4
mov r4, A
mov A, r7
subb A, r5
mov r5, A
clr c ; ************************************************************************* Очищаем флаг, на случай если число положительное
mov R5,#00 ;заносим число
mov R4,#240
mov A,R5 ;заносим старший бит в акк
jnb acc.7,loop ;проверка бита переполнения, если не установлен, переход на метку
inc c ; *********************************************************************** тут уже известно, что число отрицательное.
mov A,R4 ;заносим младший байт в акк
cpl A ;инверсия акк
add A,#00000001b ;прибавляем 1
mov R4, A ;младший байт из акка в регистр
mov A, R5 ;старший байт в акк
cpl A ;инверсия
addc A,#0 ;складываем с учетом бита переполнения
mov R5, A ;старший байт из акка в регистр
loop: 
end

Так? :)

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

Флаг С нельзя использовать. Это флаг операций, он изменится в строке

add A,#00000001b ;прибавляем 1

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

Никогда не спорьте с дураком - люди могут не заметить между вами разницы

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

Флаг С нельзя использовать. Это флаг операций, он изменится в строке

add A,#00000001b ;прибавляем 1

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

Знать бы еще, как это сделать :) Я просто не понимаю, что нам надо в этот свободный регистр занести? И после какой операции его использовать? Допустим, что я буду использовать регистр R3.

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

Занести 0 или 1, в зависимости от знака полученной температуры, а при выводе на индикацию, включить или выключить знак минуса на экране.

Никогда не спорьте с дураком - люди могут не заметить между вами разницы

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

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

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

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

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

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

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

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

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

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

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

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