Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Кто разъяснит прикол IAR C
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
SasaVitebsk
Объявлено следующее:

#define FCLK 14745600 // ×àñòîòà êîíòðîëëåðà
#define TCLK 68 // ×àñòîòà êîíòðîëëåðà â íñ
....
#define FREGENER 75 // ×àñòîòà ðåãåíåðàöèè ïàííî
#define FSHOWACT 40 // ×àñòîòà èñïîëíåíèÿ êîìàíä
....
OCR1A = FCLK/(1024*FSHOWACT); // FCLK/1024/16.7 Ãö = 862
....

Компилятор генерит следующее

168 // Инициализация таймера 1 (Исполнение активных комманд)
169 // TCCR1A = 0; // Запустить таймер 1 в режиме сравнения
170 OCR1A = FCLK/(1024*FSHOWACT); // FCLK/1024/16.7 Гц = 862
\ 00000100 EA08 LDI R16, 168
\ 00000102 EF1D LDI R17, 253
\ 00000104 93100089 STS 137, R17
\ 00000108 93000088 STS 136, R16


Если вместо 40 для константы FSHOWACT поставить 31 и меньше, то всё класс. Точно также всё правильно если поставить 40.0!
Что я не учёл?
sz36
Цитата
#define FSHOWACT 40 // ×àñòîòà èñïîëíåíèÿ êîìàíä
OCR1A = FCLK/(1024*FSHOWACT); // FCLK/1024/16.7 Ãö = 862


Не учел, что 40*1024 превышает максимальное значение для int (32767), и, соответственно, результат умножения получается отрицательным
Romario
Цитата(sz36 @ Jul 12 2006, 21:41) *
Цитата
#define FSHOWACT 40 // ×àñòîòà èñïîëíåíèÿ êîìàíä
OCR1A = FCLK/(1024*FSHOWACT); // FCLK/1024/16.7 Ãö = 862


Не учел, что 40*1024 превышает максимальное значение для int (32767), и, соответственно, результат умножения получается отрицательным


угу, везде после констант желательно ставить два символа "ul"

типа #define FSHOWACT 40ul ну и 1024 нужно написать как 1024ul
wink.gif
Сергей Борщ
Цитата(sz36 @ Jul 12 2006, 20:41) *
Не учел, что 40*1024 превышает максимальное значение для int (32767), и, соответственно, результат умножения получается отрицательным
Имеено так. Препроцессор по умолчанию считает все данные как int. Во избежание подобных недоразумений следует писать #define FCLK 14745600ULL, т.е объявлять константу типа unsigned long long или 14745600UL, т.е. unsigned long
GetSmart
Вроде бы профи, но не знаю чем отличается long от long long ?
Сергей Борщ
Цитата(GetSmart @ Jul 12 2006, 22:46) *
Вроде бы профи, но не знаю чем отличается long от long long ?
Тем что в некоторых компиляторах long long состоит из вдвое большего количества бит чем long?
GetSmart
Целое на 8 байт?
IgorKossak
Цитата(GetSmart @ Jul 13 2006, 00:07) *
Целое на 8 байт?

Именно.
Если используете С++ (вдруг захочется), то константы удобнее делать типизированными:
const unsigned long LONG_CONST = 4000000;
и т. д.
В этом случае компилятор будет предупреждать о потере значимости.
_Bill
Цитата(Сергей Борщ @ Jul 12 2006, 20:53) *
Цитата(sz36 @ Jul 12 2006, 20:41) *

Не учел, что 40*1024 превышает максимальное значение для int (32767), и, соответственно, результат умножения получается отрицательным
Имеено так. Препроцессор по умолчанию считает все данные как int. Во избежание подобных недоразумений следует писать #define FCLK 14745600ULL, т.е объявлять константу типа unsigned long long или 14745600UL, т.е. unsigned long

Все правильно, только препроцессор здесь ни при чем. Препроцессор тупо заменяет один текст другим, а все остальное делает компилятор.
IgorKossak
Цитата(_Bill @ Jul 13 2006, 10:03) *
Цитата(Сергей Борщ @ Jul 12 2006, 20:53) *

Цитата(sz36 @ Jul 12 2006, 20:41) *

Не учел, что 40*1024 превышает максимальное значение для int (32767), и, соответственно, результат умножения получается отрицательным
Имеено так. Препроцессор по умолчанию считает все данные как int. Во избежание подобных недоразумений следует писать #define FCLK 14745600ULL, т.е объявлять константу типа unsigned long long или 14745600UL, т.е. unsigned long

Все правильно, только препроцессор здесь ни при чем. Препроцессор тупо заменяет один текст другим, а все остальное делает компилятор.

Кто бы это ни делал, любые литералы, влезающие в диапазон целых , воспринимаются компилятором как целые если они не снабжены специальными суффиксами и не содержат десятичной точки.
Надо сказать, что на разных платформах целые имеют разную длину.
Поэтому для большей предсказуемости поведения компилятора надёжнее использовать типизированные константы. Ошибки могут быть выявлены ещё на этапе компиляции.
Сергей Борщ
Цитата(_Bill @ Jul 13 2006, 10:03) *
Цитата(Сергей Борщ @ Jul 12 2006, 20:53) *

Препроцессор по умолчанию считает все данные как int.

Все правильно, только препроцессор здесь ни при чем. Препроцессор тупо заменяет один текст другим, а все остальное делает компилятор.
Да, правильно. А меня чего-то заклинило что это делает препроцессор. И очень меня это смущало. Спасибо, теперь "отпустило" :-) Действительно, при таком раскладе все становится гармоничным. Возможно я где-то более подробно читал какая из частей компилятора занимается вычислением констант и в голове ошибочно отложился препроцессор.
SasaVitebsk
Спасибо теперь понял.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.