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

Кто разъяснит прикол IAR C

Объявлено следующее:

 

#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!

Что я не учёл?

Поделиться сообщением


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

#define FSHOWACT 40 // ×àñòîòà èñïîëíåíèÿ êîìàíä

OCR1A = FCLK/(1024*FSHOWACT); // FCLK/1024/16.7 Ãö = 862

 

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

Поделиться сообщением


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

#define FSHOWACT 40 // ×àñòîòà èñïîëíåíèÿ êîìàíä

OCR1A = FCLK/(1024*FSHOWACT); // FCLK/1024/16.7 Ãö = 862

 

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

 

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

 

типа #define FSHOWACT 40ul ну и 1024 нужно написать как 1024ul

;)

Поделиться сообщением


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

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

Поделиться сообщением


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

Вроде бы профи, но не знаю чем отличается long от long long ?
Тем что в некоторых компиляторах long long состоит из вдвое большего количества бит чем long?

Поделиться сообщением


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

Целое на 8 байт?

Именно.

Если используете С++ (вдруг захочется), то константы удобнее делать типизированными:

const unsigned long LONG_CONST = 4000000;

и т. д.

В этом случае компилятор будет предупреждать о потере значимости.

Поделиться сообщением


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

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

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

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

Поделиться сообщением


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

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

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

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

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

Надо сказать, что на разных платформах целые имеют разную длину.

Поэтому для большей предсказуемости поведения компилятора надёжнее использовать типизированные константы. Ошибки могут быть выявлены ещё на этапе компиляции.

Поделиться сообщением


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

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

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

Да, правильно. А меня чего-то заклинило что это делает препроцессор. И очень меня это смущало. Спасибо, теперь "отпустило" :-) Действительно, при таком раскладе все становится гармоничным. Возможно я где-то более подробно читал какая из частей компилятора занимается вычислением констант и в голове ошибочно отложился препроцессор.

Поделиться сообщением


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

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

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

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

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

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

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

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