реклама на сайте
подробности

 
 
> Ошибка в AVR Studio4
Wild007
сообщение Oct 30 2006, 07:58
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 226
Регистрация: 25-03-05
Из: Беларусь
Пользователь №: 3 672



Подскажите пожалуйста!!! Уже час не могу создать MACRO.
Привожу отрывок:
. . . .
.EQU TTT=4100/1000000
LDI r17,0x100-(TTT*20000000/1024)
. . . . .
выдает "error: Operand(s) out of range in 'ldi r17,0x100'"
Считаю на калькуляторе -- значение в скобках =0x50.
В чем проблема? (цифры приведены так как они передаются в MACROS по параметрам и просьба их не обсуждать)


--------------------
Ничто так не ограничивает полет мысли программиста, как компилятор
Go to the top of the page
 
+Quote Post
2 страниц V  < 1 2  
Start new topic
Ответов (15 - 26)
xemul
сообщение Oct 31 2006, 15:11
Сообщение #16



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Выражение
Цитата
(A/B*C/D)

вычисляется препроцессором слева направо как целочисленное, и с указанными значениями
A/B = 0 без вариантов.
К сожалению, Вам придется самому следить за переполнением и потерей точности в таких выражениях.
Выражение (A*С/B/D) не приведет ни к потере точности, ни к переполнению.

Занятно:
Код
.EQU A=4100.0
.EQU B=1000000
.EQU C=20000000
.EQU D=1024

    LDI R18,low($100-INT(4100.0/B*C/D))
    LDI R19,high($100-INT(A/B*C/D))

в R18 получим 0xb0 - правильно, а в R19 0x01 - неправильно.
Таки косячок имеется.
Go to the top of the page
 
+Quote Post
Gennadiy_
сообщение Oct 31 2006, 16:58
Сообщение #17


Частый гость
**

Группа: Свой
Сообщений: 79
Регистрация: 13-01-06
Из: Москва
Пользователь №: 13 133



Я писал так:

Код
.equ    quant=(CK/64)/256
.equ    Hquant=(CK/256)*60*60
.equ    Mquant=(CK/256)*60
.equ    Squant=(CK/256)
;Время   =((((((часы*60)+минуты)*60)+секунды)*CK)/64)/256
;максимальное время 19ч 5мин 19 сек <<=  считает с ошибкой


.set    hour    =3
.set    min    =0
.set    sec    =0
.equ    1_Time    =((hour*Hquant)+(min*Mquant)+(sec*Squant))/64

.set    hour    =0
.set    min    =20
.set    sec    =0
.equ    2_Time    =((hour*Hquant)+(min*Mquant)+(sec*Squant))/64


И параметры вычислялись с ошибкой, но поскольку это только время нахождения в разных режимах, некритичное, я забил на это.
Go to the top of the page
 
+Quote Post
Wild007
сообщение Nov 1 2006, 06:56
Сообщение #18


Местный
***

Группа: Свой
Сообщений: 226
Регистрация: 25-03-05
Из: Беларусь
Пользователь №: 3 672



Даа, проверять, проверять и еще раз проврять... (сказал отладчик smile.gif ).
Может письмо Atmely наскрябать, чтобы препроцесор апгрейдил? Ведь при вычислении формулы РС безразлично в коком виде представлены числа, а при подстановке в реал можно ограничиваться и целочисленными значениями. Или добваить директиву препроцесора.


--------------------
Ничто так не ограничивает полет мысли программиста, как компилятор
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Nov 1 2006, 08:20
Сообщение #19


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(xemul @ Oct 31 2006, 17:11) *
Выражение
Цитата
(A/B*C/D)

вычисляется препроцессором слева направо как целочисленное, и с указанными значениями
A/B = 0 без вариантов.
К сожалению, Вам придется самому следить за переполнением и потерей точности в таких выражениях.
Выражение (A*С/B/D) не приведет ни к потере точности, ни к переполнению.

Занятно:
Код
.EQU A=4100.0
.EQU B=1000000
.EQU C=20000000
.EQU D=1024

    LDI R18,low($100-INT(4100.0/B*C/D))
    LDI R19,high($100-INT(A/B*C/D))

в R18 получим 0xb0 - правильно, а в R19 0x01 - неправильно.
Таки косячок имеется.

А если так сделать?
Код
.EQU A=4100.0
.EQU B=1000000.0
.EQU C=20000000.0
.EQU D=1024.0

    LDI R18,low($100-INT(4100.0/B*C/D))
    LDI R19,high($100-INT(A/B*C/D))
Go to the top of the page
 
+Quote Post
Wild007
сообщение Nov 1 2006, 08:42
Сообщение #20


Местный
***

Группа: Свой
Сообщений: 226
Регистрация: 25-03-05
Из: Беларусь
Пользователь №: 3 672



Проверил в Студии:

.EQU A=4100.0
.EQU B=1000000.0
.EQU C=20000000.0
.EQU D=1024.0
LDI R18,low($100-int(A/B*C/D));
LDI R19,high($100-int(A/B*C/D))
;R18=0x00 R19=0x01 -- это не правильно

LDI R18,low($100-(C/D*A/B));
LDI R19,high($100-(C/D*A/B))
;R18=0xB0 R19=0x00 -- это правильно


--------------------
Ничто так не ограничивает полет мысли программиста, как компилятор
Go to the top of the page
 
+Quote Post
Andreas1
сообщение Nov 1 2006, 09:06
Сообщение #21


Местный
***

Группа: Свой
Сообщений: 446
Регистрация: 12-03-06
Из: Москва
Пользователь №: 15 142



А чем не нравится так
#define A 4100.0
#define B 1000000.0
#define C 20000000.0
#define D 1024.0
LDI R18,low($100-int(A/B*C/D));
LDI R19,high($100-int(A/B*C/D))

В отладчике получается
;R18=0xB0 R19=0x00
Go to the top of the page
 
+Quote Post
Wild007
сообщение Nov 1 2006, 09:15
Сообщение #22


Местный
***

Группа: Свой
Сообщений: 226
Регистрация: 25-03-05
Из: Беларусь
Пользователь №: 3 672



Цитата(Andreas1 @ Nov 1 2006, 12:06) *
А чем не нравится так
#define A 4100.0
#define B 1000000.0
#define C 20000000.0
#define D 1024.0
LDI R18,low($100-int(A/B*C/D));
LDI R19,high($100-int(A/B*C/D))

В отладчике получается
;R18=0xB0 R19=0x00


Это все хорошо, но А,C и D это параметры которые передаются в MACROS, а EQU здесь применено для упрощения.


--------------------
Ничто так не ограничивает полет мысли программиста, как компилятор
Go to the top of the page
 
+Quote Post
Andreas1
сообщение Nov 1 2006, 09:42
Сообщение #23


Местный
***

Группа: Свой
Сообщений: 446
Регистрация: 12-03-06
Из: Москва
Пользователь №: 15 142



Цитата
Это все хорошо, но А,C и D это параметры которые передаются в MACROS, а EQU здесь применено для упрощения.

Не понял.
.EQU задает только целые
#define можно задать целые и дробные
умножение и деление дает тип результата по операндам.
Или проблема в том, что в макрос не передается вещественное??
Go to the top of the page
 
+Quote Post
Wild007
сообщение Nov 1 2006, 09:50
Сообщение #24


Местный
***

Группа: Свой
Сообщений: 226
Регистрация: 25-03-05
Из: Беларусь
Пользователь №: 3 672



.MACRO DELAYMKS ;
.....
LDI R18,$100-(@0/1000000*@1/@2)
.......
.ENDM

в теле основной программы:

.EQU F_cry=20000000
.....
DELAYMKS 4100,F_cry,1024
......

примерно так.


--------------------
Ничто так не ограничивает полет мысли программиста, как компилятор
Go to the top of the page
 
+Quote Post
Andreas1
сообщение Nov 1 2006, 10:06
Сообщение #25


Местный
***

Группа: Свой
Сообщений: 446
Регистрация: 12-03-06
Из: Москва
Пользователь №: 15 142



Ну тогда так

.MACRO DELAYMKS ;
.....
LDI R18,$100-INT(@0/1000000*@1/@2)
.......
.ENDM

в теле основной программы:

#define F_cry 20000000.0
.....
DELAYMKS 4100.0,F_cry,1024.0

Если работает, поробовать убрать .0 в вызове

Сообщение отредактировал Andreas1 - Nov 1 2006, 10:08
Go to the top of the page
 
+Quote Post
xemul
сообщение Nov 1 2006, 10:54
Сообщение #26



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(IgorKossak @ Nov 1 2006, 11:20) *
Цитата(xemul @ Oct 31 2006, 17:11) *

Выражение
Цитата
(A/B*C/D)

вычисляется препроцессором слева направо как целочисленное, и с указанными значениями
A/B = 0 без вариантов.
К сожалению, Вам придется самому следить за переполнением и потерей точности в таких выражениях.
Выражение (A*С/B/D) не приведет ни к потере точности, ни к переполнению.

Занятно:
Код
.EQU A=4100.0
.EQU B=1000000
.EQU C=20000000
.EQU D=1024

    LDI R18,low($100-INT(4100.0/B*C/D))
    LDI R19,high($100-INT(A/B*C/D))

в R18 получим 0xb0 - правильно, а в R19 0x01 - неправильно.
Таки косячок имеется.

А если так сделать?
Код
.EQU A=4100.0
.EQU B=1000000.0
.EQU C=20000000.0
.EQU D=1024.0

    LDI R18,low($100-INT(4100.0/B*C/D))
    LDI R19,high($100-INT(A/B*C/D))


Не, это я протормозилsmile.gif. Как уже указал Andreas1, вещественные константы можно определить только через #define.
Более занятно, что при
Код
#define A 4100
#define B 1000000.0
#define C 20000000
#define D 1024

INT(A/B*C/D) = 0x50
а при
Код
#define A 4100
#define B 1000000
#define C 20000000.0
#define D 1024

INT(A/B*C/D) = 0x00
Т.е. похоже, что тип результата препроцессор полагает целым, и только когда уткнется в вещественное число, конвертит текущий результат в вещественный формат. Неаккуратненькоsad.gif.
Go to the top of the page
 
+Quote Post
Wild007
сообщение Nov 1 2006, 12:11
Сообщение #27


Местный
***

Группа: Свой
Сообщений: 226
Регистрация: 25-03-05
Из: Беларусь
Пользователь №: 3 672



.MACRO DELAYMKS ;
.....
LDI R18,$100-INT(@0/1000000*@1/@2)
.......
.ENDM

в теле основной программы:

#define F_cry 20000000.0
.....
DELAYMKS 4100.0,F_cry,1024.0

Выдает ошибку

.MACRO DELAYMKS ;
.....
LDI R18,$100-INT(@0/MIL*@1/@2)
.......
.ENDM

в теле основной программы:

#define MIL 1000000.0
.....
DELAYMKS 4100.0,F_cry,1024.0
работает правильно, даже если
.EQU F_CRY=20000000

Получается для коректной работы и уменьшения времени на отладку надо все заранее объявлять ВСЕ константы через #define


--------------------
Ничто так не ограничивает полет мысли программиста, как компилятор
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 10:27
Рейтинг@Mail.ru


Страница сгенерированна за 0.01492 секунд с 7
ELECTRONIX ©2004-2016