2016-06-14 3 views
0

Я пытаюсь настроить модуль USART в микроконтроллере XMEGA и споткнуться об ошибке, которую я не могу найти. Для ясности я даю вам полный код. Поэтому ничего в этом заголовочном файле отсутствует. (F_CPU определен в главном файле)Препроцессор: отсутствующий двоичный оператор перед токеном

#ifndef USART_H_ 
#define USART_H_ 

#include <avr/io.h> 



#define USART_BAUDRATE   4800 
#define USART_BSCALE   -3 

#if USART_BSCALE < 0 
    #define USART_BSEL   F_CPU/(pow(2,USART_BSCALE) * 16 * USART_BAUDRATE) - 1 
    #define USART_BAUD_REAL  F_CPU/(pow(2,USART_BSCALE) * 16 * (USART_BSEL + 1)) 
#else 
    #define USART_BSEL   (1/(pow(2,USART_BSCALE))) * (F_CPU/(16 * USART_BAUDRATE) - 1) 
    #define USART_BAUD_REAL  F_CPU/(16 * ((pow(2,USART_BSCALE) * USART_BSEL) + 1)) 
#endif 

#define USART_BAUD_ERROR  USART_BAUD_REAL * 1000/USART_BAUDRATE 

#if USART_BAUD_ERROR<990 || USART_BAUD_ERROR>1010 /* <-- ERROR IS IN THIS LINE! */ 
    #error Baud rate error too high! 
#endif 


#endif /* USART_H_ */ 

Компилятор завершается с ошибкой

missing binary operator before token "("

в отмеченной линии. Раньше были скобки, но я их удалил, попробовал разные комбинации скобок, но компилятор все еще видит их там. Что здесь не так?

+4

Вы не можете использовать функции C (pow ...) внутри аргумента директивы #if препроцессора, потому что, ну, он оценивается препроцессором во время компиляции ... –

+0

О, это плохо. Есть ли другой способ вычислить полномочия тогда? – Peder

+2

Силы двух? Сдвиг битов (и они поддерживаются: https://gcc.gnu.org/onlinedocs/gcc-3.0.2/cpp_4.html#SEC38) –

ответ

2

Предпроцессорная директива #if оценивается на этапах предварительной обработки. Функция pow оценивается во время выполнения. Поэтому вы не можете использовать его внутри токенов препроцессора (макросов), которые передаются в #if. Вы захотите вычислить все эти значения во время компиляции.

Подсказка: «2 раза n» - это то же самое, что и 1 << n (побитовая левая смена).

Кроме того, есть и другие серьезные проблемы:

  • Вы пометили этот AVR, так что вы, вероятно, не следует использовать числа с плавающей точкой. Они не только сделают вашу программу невероятно медленной и откроются для всех видов ошибок, из их использования ничего не получится.

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

    Возможно, было бы разумно проверить, имеет ли ваша целевая система даже FPU перед рассмотрением использования с плавающей запятой.

  • Вам нужно написать собственные макросы, с круглыми скобками, окружающими макросъемку. Также как ваш второй USART_BSEL, который правильно написан. В противном случае, если ваш макрос используется в выражении, вы можете получить очень тонкие и очень строгие ошибки, связанные с приоритетом оператора. Каждая полуподобная книга C решает эту проблему в предпроцессорной главе.