#c #macros #c-preprocessor #avr
#c #макросы #c-препроцессор #avr
Вопрос:
Я пишу простую библиотеку для своего AVR, и я хотел попробовать использовать макрофункцию для определения моей скорости передачи данных. Многие функции в библиотеке AVR используют макрос F_CPU, а также тот, который я хочу написать.
Вот что у меня есть для определения макроса и моей предполагаемой реализации:
#define BAUD_SELECT(baud) ((F_CPU)/(2*baud)-1)
myubrr = BAUD_SELECT(38400);
Я пытался использовать #define F_CPU 800000000UL, а также в файле make как -D»F_CPU 800000000UL», но я всегда получаю одну и ту же ошибку в строке реализации.
expected ')' before numeric constant
Я уверен, что это как-то связано с моим злоупотреблением #define, и что определение макроса находится в заголовочном файле, реализация — в соответствующем файле .c, а определение F_CPU либо в файле makefile, либо в другом основном файле .c.
РЕДАКТИРОВАТЬ Я изменил скобки, как было предложено, и запустил препроцессор и нашел выходной файл (по крайней мере, я думаю)
unsigned int myubrr = ((8000000UL 1)/(2*(baud))-1);
Он помещает дополнительный 1 там, где должен быть F_CPU, у меня нет опыта работы с препроцессором, поэтому я не уверен, как заставить его этого не делать, но, возможно, в этом проблема?
Комментарии:
1. попробуйте запустить на нем препроцессор и посмотреть, к чему он расширяется
2. Это кажется правильным. Вам наверняка не хватает круглой скобки где-то еще. Кстати, в выражении макроса всегда помещайте переменные, принятые в качестве аргумента, в круглые скобки. Представьте, что ваш макрос называется like
BAUD_SELECT(some_baud 100)
((F_CPU)/(2*some_baud 100)-1)
, который будет расширяться, а это не то, что вы хотите. Итак, вам нужно будет написать выражение следующим образом:((F_CPU)/(2*(baud))-1)
3. Присмотритесь повнимательнее к определению F_CPU … возможно, в конце строки за пределами окна вашего редактора есть какой-то мусор.
Ответ №1:
Попробуйте заключить ее в круглые скобки:
#define BAUD_SELECT(baud) ((F_CPU)/(2*(baud))-1)
Ответ №2:
Для меня это работает нормально:
#define BAUD_SELECT(baud) ((F_CPU)/(2*(baud))-1)
unsigned int myubrr = BAUD_SELECT(38400);
когда я компилирую с
$ cc -c -DF_CPU=8000000UL t.c
Дополнительные скобки в данном конкретном случае не имеют большого значения, хотя в целом они являются хорошей идеей. Итак, происходит что-то еще. Возможно F_CPU
, в каком-то другом заголовочном файле есть другое определение, которое переопределяет ваше определение F_CPU
Комментарии:
1. Как ни странно, переход от -D»F_CPU 800000000UL» к -D»F_CPU=800000000UL» позволил ему скомпилироваться, я никогда не замечал никакого различия между ними до сих пор, но все еще не уверен, что препроцессор делает по-другому.
2. Действительно, это как-то странно… 😉 — При первом запуске -D «F_CPU 800000000UL» определяет один макрос с пробелом в его идентификаторе, а именно макрос ‘F_CPU 800000000UL’, поскольку знак ‘=’ не используется, он получает значение 1. Итак, у нас есть ‘F_CPU 800000000UL 1’. Затем при разборе вашего кода препроцессор принимает эту фразу как есть и заменяет ‘F_CPU’ в вашем коде на ‘800000000UL 1’. Можно рассматривать это как ошибку cpp? ;->