Консультация № 159335
01.02.2009, 14:38
50.00 руб.
0 13 1
Добрый день, вопрос по операциям с двухбайтными числами. Есть ADuC848 (асемблер MSC-51) в нем используется главный 16 битный АЦП и который последовательно преобразует 3 напряжения в 3 двухбайтных значения U1, U2, U3 записывая их в память поочередно. Так же в памяти хранится значение R0 и alpha.
Нужно сделать два вычисления:
1. RT=(U1-U2)*R0/(U0-U1)
2. T=(RT-R0)/R0*alpha

Обсуждение

давно
Посетитель
7438
7205
01.02.2009, 23:50
общий
А величины (U1-U2), R0, (U0-U1), RT, alpha - однобайтные или двубайтные?
От этого зависит алгорим расчета
Например, если (U1-U2) и R0 - двубайтные, то их произведение будет 4-х байтное,
а если однобайтные, то произведение - двубайтное...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
03.02.2009, 12:11
общий
U1, U2, U3 - из АЦП - двухбайтные целые числа, их перевести в числа с плавающей точкой; числа RT, alpha точе в виде с плавающей точкой, а уже потом делать операции.
давно
Посетитель
7438
7205
03.02.2009, 12:29
общий
Хм...о плавающей точке в задании ничего не было сказано.
Это уже явно не "вопрос по операциям с двухбайтными числами"
Это значительно усложняет задачу.
Вы представляете, что значит реализовать эмуляцию вещественных чисел на 8-битном процессоре? И какой разрядности должны быть эти вещественые числа?
И, вообще, Вы уверены, нужны ли вещественные числа? Какого порядка там числа?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
03.02.2009, 12:59
общий
квант ацп - 20мкВ, значит U1 = число квантов(двух байтное)*(квант АЦП) так же и для других чисел, самое большое значение - U0 оно порядка 2.5В; U1 - порядка1.5В; U2 - 0.8В

Слушайте, нашел библиотеку для работы с плавающими точками на 8 битовом процессоре, http://iit1.mpei.ac.ru/pub.htm называется Библиотека FP51S и ее описание. мне ее только что посоветовали использовать, правда я в ней пока не разобрался.
давно
Посетитель
7438
7205
03.02.2009, 13:28
общий
Чего-то не стыкуется:
1В = 50000 * 20 мкВ, 2.5В = 2.5 * 50000 = 125000 - в два байта (мах 65536) ну никак не помещается!
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
03.02.2009, 13:42
общий
Сори за ложную информацию там когда измеряется 2.5 вольта переключается режим, и в итоге получается что квант 40мкВ
давно
Посетитель
7438
7205
03.02.2009, 14:01
общий
И все равно не понимаю, зачем использовать вещественные числа - лишний геморрой (отладка, время работы).
Вполне достаточно работать с показаниями АЦП, параметры тоже привести к ним.
Если нужно получить вольты, преобразовать к вольтам...
Для 1.5В (75000) тоже не поместится в два байта
Значит квант должен быть везде 40мкВ
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
04.02.2009, 09:01
общий
При измерении U2 - квант 20мкВ(иначе погрешность определения больше 10%, что не удовлетворяет ТЗ), при измерении U1 и U0 квант 40 мкВ. Т.к. кванты разные, то вычисление в относительных единицах не целесообразно. Мне нужно посчитать и получить результат.
давно
Посетитель
7438
7205
04.02.2009, 11:33
общий
Хорошо, пусть будет так.
Можно сделать по-другому: все преобразовываем, допустим, к сотым (тысячным,десятитысячным) вольта.
Т.е. будем иметь величины 250(2500,25000) для 2.5В, 80(800,8000) для 0.8В и т.д.
Опять же все константы тоже умножаем на 100(1000,10000).
Вычисляем, потом делим полученный результат на 100(1000,10000) и получаем целую и дробную часть
Так устроит?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
04.02.2009, 19:05
общий
Давайте так, просто горю, уже сдавать скоро!
давно
Посетитель
7438
7205
05.02.2009, 04:01
общий
Я пока пишу подпрограммки, уточните:
1) сколько знаков после запятой будем использовать: 2, 3 или 4? Чем больше, тем точнее, но и сложнее расчет.
2) чему равны R0 и alpha?
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Неизвестный
05.02.2009, 10:05
общий
кароче, у вроде написал, с использованием того класса, что я дал не могли бы вы проверить?

?DT?Mesure SEGMENT DATA
RSEG ?DT?Mesure
BUF: DS 3
BUF1: DS 3
BUF2: DS 3

PUBLIC Mesure
EXTRN CODE(MOVFP_Y_C,MOVFP_Y_X,MOVFP_R_X,MOVFP_Y_R,W_TO_FP,ADD_FP,SUB_FP,MUL_FP,DIV_FP)

?PR?Mesure SEGMENT CODE
RSEG ?PR?Mesure
;--------------------------------------------------------------------------------
; Подпрограмма Mesure
; Вычисление температуры по трем измерениям напряжений
; Входные параметры:
; А - номер измеряемого канала
; Выходные параметры:
; T - соответствующая R температура (oC) в формате FP -
; возвращается в регистрах R2(знак и характеристика числа),R3-R4(мантисса)
;--------------------------------------------------------------------------------
Mesure:

MOV ADC0CON1, #01100100 ; 1,2,3 биты - диапазон 1,28В , 6 бит - униполярный режим, 7,8 биты - буферный режим

SWAP A
ORL A,#00000001
MOV ADC0CON2, A ; 1-4 биты - вход c номер контролируемой точки, 7,8 биты - источник опорного напряжения

JBC RDY0, M1 ; Ждем результата измерения U2
M1: CLR RDY0 ; Результат получен

MOV R3,ADC1H ; Сохранение результата U2 для преобразования
MOV R4,ADC1M

LCALL W_TO_FP ; Преобразование U2 в FP, результат в регистрах R2-R4

MOV DPTR,#koef+3
LCALL MOVFP_Y_C ; пересылка q2 из ПЗУ в регистры R5-R7

LCALL MUL_FP ; Результат U2,В в R2-R4
MOV R1,#BUF
LCALL MOVFP_R_X ; Сохранение U2 в внутреннем ОЗУ

MOV ADC0CON1, #01100100 ; 1,2,3 биты - диапазон 1,28В , 6 бит - униполярный режим, 7,8 биты - буферный режим

AND A,#11111110
SWAP A
MOV P3,A ;Выбор линии U1 контролируемой точки
MOV ADC0CON2, #11100001 ; 1-4 биты - вход AIN8, 7,8 биты - источник опорного напряжения

JBC RDY0, M2 ; Ждем результата измерения U1
M2: CLR RDY0 ; Результат получен

MOV R3,ADC1H ; Сохранение результатов U1 для преобразования
MOV R4,ADC1M

LCALL W_TO_FP ; Преобразование U1 в FP, результат в регистрах R2-R4

MOV DPTR,#koef
LCALL MOVFP_Y_C ; пересылка q1 из ПЗУ в регистры R5-R7
LCALL MUL_FP ; Результат U1 в R2-R4

MOV R1,#BUF1
LCALL MOVFP_R_X ; Сохранение U1 в внутреннем ОЗУ для дальнейших вычислений

MOV R1,#BUF
LCALL MOVFP_Y_R ; Загрузка в Y в 2*U2

LCALL SUB_FP ; Результат U1-2*U2 в R2-R4

MOV DPTR,#koef+6
LCALL MOVFP_Y_C ; пересылка R0 из ПЗУ в регистры R5-R7

LCALL MUL_FP ; Результат (U1-2*U2)*R0 в R2-R4

MOV R1,#BUF2
LCALL MOVFP_R_X ; Сохранение (U1-2*U2)*R0 во внутреннем ОЗУ для дальнейших вычислений

MOV ADC0CON1, #11100100 ; 1,2,3 биты - диапазон 2,56В , 6 бит - униполярный режим, 7,8 биты - буферный режим
MOV ADC0CON2, #00010001 ; 1-4 биыт - вход AIN9, 7,8 биты - источник опорного напряжения

JBC RDY0, M1 ; Ждем результата измерения U0
M1: CLR RDY0 ; Результат получен

MOV R3,ADC1H ; Сохранение результатов U0
MOV R4,ADC1M

LCALL W_TO_FP ; Преобразование U0 в FP, результат в регистрах R2-R4

MOV DPTR,#koef+3
LCALL MOVFP_Y_C ; пересылка q2 из ПЗУ в регистры R5-R7
LCALL MUL_FP ; Результат U0 в R2-R4

MOV R1,#BUF1
LCALL MOVFP_Y_R ; Загрузка U1 в R5-R7

LCALL SUB_FP ; U0-U1 результат в R2-R4
LCALL MOVFP_Y_X ; U0-U1 результат в R5-R7

MOV R1,#BUF2
LCALL MOVFP_Y_R ; Загрузка (U1-2*U2)*R0 в R2-R4

LCALL DIV_FP ; Результат R(T)=(U1-2*U2)*R0/(U0-U1) в R2-R4

MOV DPTR,#koef+6
LCALL MOVFP_Y_C ; пересылка R0 из ПЗУ в регистры R5-R7

LCALL SUB_FP ; R(T)-R0 результат в R2-R4

MOV R1,#BUF1
LCALL MOVFP_R_X ; Сохранение R(T)-R0 во внутреннем ОЗУ для дальнейших вычислений

MOV DPTR,#koef+6
LCALL MOVFP_Y_C ; пересылка R0 из ПЗУ в регистры R5-R7

MOV DPTR,#koef+9
LCALL MOVFP_X_C ; пересылка alpha из ПЗУ в регистры R2-R4

LCALL MUL_FP ; R0*alpha результат в R2-R4
LCALL MOVFP_Y_X ; R0*alpha результат в R5-R7

MOV R1,#BUF1
LCALL MOVFP_X_R ; Загрузка в X в R(T)-R0, результат в R2-R4

LCALL DIV_FP ; T=(R(T)-R0)/R0*alpha результат в R2-R4

RET


koef: DB 37H, 0A7H, 0C5H ; q1 = 20 мкВ
DB 38H, 27H, 0C5H ; q2 = 40 мкВ
DB 43H, 0B4H, 00H ; R0=360 Ом
DB 3BH, 8CH, 3FH ; alpha=4.28*10^-3 C^-1

END


давно
Посетитель
7438
7205
06.02.2009, 00:38
общий
это ответ
Здравствуйте, d1mka1986!
Просмотрел Ваше решение. В целом все правильно.
Исправил пару ошибок:
1) Было неправильно организовано преобразование показаний АЦП в вольты.
Надо делить показание или на 50000 для 20мкВ, или на 25000 для 40мкВ.
2) В одном месте была использована не та подпрограмма: в комментарии правильно, а имя п/п неправильное
3) Ну и константы подправил


Приложение:
;1. RT=(U1-U2)*R0/(U0-U1)
;2. T=(RT-R0)/R0*alpha

?DT?Mesure SEGMENT DATA
RSEG ?DT?Mesure
BUF: DS 3
BUF1: DS 3
BUF2: DS 3

PUBLIC Mesure
EXTRN CODE(MOVFP_Y_C,MOVFP_Y_X,MOVFP_R_X,MOVFP_Y_R,W_TO_FP,ADD_FP,SUB_FP,MUL_FP,DIV_FP)

?PR?Mesure SEGMENT CODE
RSEG ?PR?Mesure
;--------------------------------------------------------------------------------
; Подпрограмма Mesure
; Вычисление температуры по трем измерениям напряжений
; Входные параметры:
; А - номер измеряемого канала
; Выходные параметры:
; T - соответствующая R температура (oC) в формате FP -
; возвращается в регистрах R2(знак и характеристика числа),R3-R4(мантисса)
;--------------------------------------------------------------------------------
Mesure:

MOV ADC0CON1, #01100100 ; 1,2,3 биты - диапазон 1,28В , 6 бит - униполярный режим, 7,8 биты - буферный режим

SWAP A
ORL A,#00000001
MOV ADC0CON2, A ; 1-4 биты - вход c номер контролируемой точки, 7,8 биты - источник опорного напряжения

JBC RDY0, M1 ; Ждем результата измерения U2
M1: CLR RDY0 ; Результат получен

MOV R3,ADC1H ; Сохранение результата U2 для преобразования
MOV R4,ADC1M

LCALL W_TO_FP ; Преобразование U2 в FP, результат в регистрах R2-R4

MOV DPTR,#koef+3
LCALL MOVFP_Y_C ; пересылка q2 из ПЗУ в регистры R5-R7

LCALL DIV_FP ; Результат U2,В в R2-R4

MOV R1,#BUF
LCALL MOVFP_R_X ; Сохранение U2 в внутреннем ОЗУ

MOV ADC0CON1, #01100100 ; 1,2,3 биты - диапазон 1,28В , 6 бит - униполярный режим, 7,8 биты - буферный режим

AND A,#11111110
SWAP A
MOV P3,A ;Выбор линии U1 контролируемой точки
MOV ADC0CON2, #11100001 ; 1-4 биты - вход AIN8, 7,8 биты - источник опорного напряжения

JBC RDY0, M2 ; Ждем результата измерения U1
M2: CLR RDY0 ; Результат получен

MOV R3,ADC1H ; Сохранение результатов U1 для преобразования
MOV R4,ADC1M

LCALL W_TO_FP ; Преобразование U1 в FP, результат в регистрах R2-R4

MOV DPTR,#koef
LCALL MOVFP_Y_C ; пересылка q1 из ПЗУ в регистры R5-R7
LCALL DIV_FP ; Результат U1 в R2-R4

MOV R1,#BUF1
LCALL MOVFP_R_X ; Сохранение U1 в внутреннем ОЗУ для дальнейших вычислений

MOV R1,#BUF
LCALL MOVFP_Y_R ; Загрузка в Y в 2*U2

LCALL SUB_FP ; Результат U1-U2 в R2-R4

MOV DPTR,#koef+6
LCALL MOVFP_Y_C ; пересылка R0 из ПЗУ в регистры R5-R7

LCALL MUL_FP ; Результат (U1-U2)*R0 в R2-R4

MOV R1,#BUF2
LCALL MOVFP_R_X ; Сохранение (U1-U2)*R0 во внутреннем ОЗУ для дальнейших вычислений

MOV ADC0CON1, #11100100 ; 1,2,3 биты - диапазон 2,56В , 6 бит - униполярный режим, 7,8 биты - буферный режим
MOV ADC0CON2, #00010001 ; 1-4 биты - вход AIN9, 7,8 биты - источник опорного напряжения

JBC RDY0, M1 ; Ждем результата измерения U0
M1: CLR RDY0 ; Результат получен

MOV R3,ADC1H ; Сохранение результатов U0
MOV R4,ADC1M

LCALL W_TO_FP ; Преобразование U0 в FP, результат в регистрах R2-R4

MOV DPTR,#koef+3
LCALL MOVFP_Y_C ; пересылка q2 из ПЗУ в регистры R5-R7
LCALL DIV_FP ; Результат U0 в R2-R4

MOV R1,#BUF1
LCALL MOVFP_Y_R ; Загрузка U1 в R5-R7

LCALL SUB_FP ; U0-U1 результат в R2-R4
LCALL MOVFP_Y_X ; U0-U1 результат в R5-R7

MOV R1,#BUF2
LCALL MOVFP_X_R ; Загрузка (U1-U2)*R0 в R2-R4

LCALL DIV_FP ; Результат R(T)=(U1-2*U2)*R0/(U0-U1) в R2-R4

MOV DPTR,#koef+6
LCALL MOVFP_Y_C ; пересылка R0 из ПЗУ в регистры R5-R7

LCALL SUB_FP ; R(T)-R0 результат в R2-R4

MOV R1,#BUF1
LCALL MOVFP_R_X ; Сохранение R(T)-R0 во внутреннем ОЗУ для дальнейших вычислений

MOV DPTR,#koef+6
LCALL MOVFP_Y_C ; пересылка R0 из ПЗУ в регистры R5-R7

MOV DPTR,#koef+9
LCALL MOVFP_X_C ; пересылка alpha из ПЗУ в регистры R2-R4

LCALL MUL_FP ; R0*alpha результат в R2-R4
LCALL MOVFP_Y_X ; R0*alpha результат в R5-R7

MOV R1,#BUF1
LCALL MOVFP_X_R ; Загрузка в X в R(T)-R0, результат в R2-R4

LCALL DIV_FP ; T=(R(T)-R0)/R0*alpha результат в R2-R4

RET


koef:
DB 47H, 043H, 50H ; q1 = 50000 = 1 B / 20 мкВ
DB 46H, 0c3H, 50H ; q2 = 25000 = 1 B / 40 мкВ
DB 43H, 0B4H, 00H ; R0=360 Ом
DB 3BH, 08CH, 3FH ; alpha=4.28*10^-3 C^-1

END
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
Форма ответа