Правильное подключение #include

Обсуждаем контроллеры компании Atmel.
Ответить
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

Собственно столкнулся я с тем, что не могу разобраться в подключении #include. Собственно вопрос: а как их подключать, чтобы было правильно, если в проекте несколько файлов .c и соответствующих им .h ? Например у меня есть два файла .с, функции в которых используют _delay_ms(). Надо ли в каждом из них указать #include "delay.h" и определить F_CPU ? Или это делать в заголовочных файлах .h через #ifndef ? Или достаточно в файле main.c их просто всех перечислить, а компилятор сам разберется, куда и что подсунуть? avr-gss имеется в виду.
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

Например у меня есть два файла .с, функции в которых используют _delay_ms(). Надо ли в каждом из них указать #include "delay.h"
Да.
и определить F_CPU
Нет. Это делается в настройках проекта или makefile ключом -DF_CPU
Реклама
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

Таким образом получается, что если у меня есть файл lcd.h в котором определена функция lcd_str_out(), и этот файл подключен #include lcd.h в файле main.c и я захочу использовать эту функцию в файле ADC.c, то мне надо будет и в нем прописать #include lcd.h и все include, которые может потребовать эта lcd.h. Правильно? Ну либо перенести использование этой функции из ADC.c в main.c

Добавлено after 1 minute 15 seconds:
[uquote="COKPOWEHEU",url="/forum/viewtopic.php?p=4202518#p4202518"]Нет. Это делается в настройках проекта или makefile ключом -DF_CPU[/uquote]
Atmel Studio не просит в свойствах проекта частоту CPU :(
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32

Сообщение Martian »

Вам придётся прописать его везде, где используется функция. В этом случае может возникнуть другая ошибка: два и более определений функций. В этом случае как раз используют директивы #ifndef в начале файла .h - тогда при сборке, если уже один раз было собрано, последующие попытки проигнорируются.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

[uquote="Martian",url="/forum/viewtopic.php?p=4202551#p4202551"]. В этом случае как раз используют директивы #ifndef в начале файла .h - тогда при сборке, если уже один раз было собрано, последующие попытки проигнорируются.[/uquote]
А с переменными тоже так же надо? А то у меня одна переменная должна в двух разных файлах использоваться (результаты из функции в одном файле используются в функции в другом файле. И вот как-то не получается у меня одну переменную к двум файлам привязать. И объявляю вроде как глобальную, т.е. вне функции и volatile использую. Но компилятор не соглашается с моим предложением :))
Нет, так тоже не получается :cry:
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA

Сообщение GoldenAndy »

Land, по F_CPU
Сделайте отдельный заголовочный файл, например, defines.h
В нем определите этот F_CPU и подключайте этот файл во всех ваших файлах, где вы подключаете delay.h
Подключать defines.h нужно перед delay.h

По переменной.
Объявляете эту переменную в одном модуле.
пусть это
unsigned int i;

тогда в нужном вам другом модуле пишете
extern unsigned int i;
и компилятор понимает, что i у нас уже где то есть и не делает еще одну переменную.
Можно все глобальные переменные объявить в main.c, а extern-нотификации описать в том же defines.h и подключать его везде, где надо.
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Контактная информация:
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

Таким образом получается, что если у меня есть файл lcd.h в котором определена функция lcd_str_out(), и этот файл подключен #include lcd.h в файле main.c и я захочу использовать эту функцию в файле ADC.c, то мне надо будет и в нем прописать #include lcd.h и все include, которые может потребовать эта lcd.h. Правильно?
Да. Но если у вас и сам код функции тоже в *.h файле - будут проблемы. Тогда либо не использовать эти функции откуда попало, а только из одного *.c файла, либо разделять библиотеку по-человечески на *.c + *.h.
Atmel Studio не просит в свойствах проекта частоту CPU
Ну так пропишите -DF_CPU=... во флаги компилятора руками, возможность вписывать свои флаги там есть
В этом случае как раз используют директивы #ifndef в начале файла .h - тогда при сборке, если уже один раз было собрано, последующие попытки проигнорируются.
Это от многократного включения в ОДИН *.c файл. Если же включаются в разные *.c файлы, это не поможет.
А с переменными тоже так же надо? А то у меня одна переменная должна в двух разных файлах использоваться (результаты из функции в одном файле используются в функции в другом файле.
В *.c файле переменную определяете, а в *.h - объявляете с модификатором extern. Он говорит, что переменная где-то есть, но не тут.
Сделайте отдельный заголовочный файл, например, defines.h
В нем определите этот F_CPU и подключайте этот файл во всех ваших файлах, где вы подключаете delay.h
Подключать defines.h нужно перед delay.h
Можно и так, хотя мне привязка к порядку инклюдов не нравится.
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

Большое вам спасибо. Наконец-то пазл сложился, а то кусок оттуда, кусок отсюда, а цельной картины не было. Еще раз большое спасибо за разъяснения )
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA

Сообщение GoldenAndy »

COKPOWEHEU писал(а):Можно и так, хотя мне привязка к порядку инклюдов не нравится.
Да мне тоже. Но в случае delay.h - или прописывать в свойствах проекта, или прописывать в ключах, или следить за порядком инклюдов.
Хотя я этот делей использую редко, в основном у меня суперцикл, привязанный к системному таймеру, и все задержки считаются от системного таймера.

А, и я считаю, что проще прописать или в свойствах проекта, или в инклюднике, нежели бегать по строкам конфига флагов компилятора.
Да, я понимаю, что то, что я пропишу в свойствах проекта - тоже попадет в те же флаги компилятора.
Хотя в свойствах проекта - более наглядно.
Но есть любители собирать проекты руками, писать make в блокнотике, в соседнем блокнотике исходник, компилить из командной строки, прошивать дудкой, делая ей свой батник....
Мне проще всё прописать в свойствах проекта, написать текст в студии, нажать F11 и получить прошивку уже в МК.
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18676
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

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

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA

Сообщение GoldenAndy »

ARV, правильно. но иногда получается, что для какого то стороннего h-файла нужен некий дефайн. (см. delay.h и F_CPU)
И тут или этот дефайн лепить в каждом с-файле, дабы его увидел delay.h, или делать отдельный заголовочник для общих определений, или писать в свойства проекта / ключи компилятора.
Мне лично удобнее выносить в отдельный общий инклюдник.
Там у меня вагон всего общего живет.
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18676
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

GoldenAndy писал(а):но иногда получается, что для какого то стороннего h-файла нужен некий дефайн. (см. delay.h и F_CPU)
И тут или этот дефайн лепить в каждом с-файле, дабы его увидел delay.h, или делать отдельный заголовочник для общих определений, или писать в свойства проекта / ключи компилятора
из вашего перечисления только последний вариант правильный - общие для всего проекта константы, дефайны и т.п. следует выносить в опции проекта/компилятора, и никак ниначе.

то есть это не абсолютное требование, но универсально-правильное.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 1925
Зарегистрирован: Чт июл 28, 2016 07:58:37
Откуда: Kyiv, UA

Сообщение GoldenAndy »

ARV, я не любитель руками править всякие ключи компилятора, редактировать make и прочее...
Меня, в принципе, устраивает вынести общий для всех-всех модулей дефайн в конфиг в студии.
Но мне удобнее и проще определить этот дефайн в общем инклюднике.
Там же и другие общие константы/дефайны, typedef-ы и т.д.
Кроме того, когда всё в инклюднике - проще выкладывать исходники. *.c и *.h выложил - и всё. А дальше каждый может попробовать затянуть в свою любимую ide.
Но тут на вкус и цвет - фломастеры разные.

И да, я ж не программист, я только учусь. 33 года уже учусь.
ИзображениеИзображение
Изображение
 
Telegram               Лучшая благодарность ->
[+]
Контактная информация:
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18676
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

только ваш подход чреват тем, что собирая новый проект из "отработанных и гарантированно работающих" старых файлов, вы рискуете в одном из них забыть про какой-то дефайн, и получить чудеса... а так - снова, как я не раз говорил: все полезно, что в рот полезло.

Добавлено after 1 minute 12 seconds:
GoldenAndy писал(а):я ж не программист, я только учусь. 33 года уже учусь
я и сам такой... учусь только дольше - тупой, наверное...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

А почему #define NAME из одного .с файла не определено для другого? И как с этим бороться? Делать глобальный .с файл, в который вносить подобные дефайны?
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

Потому что #define это просто вставка всего текста из одного файла в другой.
Делать глобальный .с файл, в который вносить подобные дефайны?
Чего вы хотите добиться этим я вообще не знаю.
Мучитель микросхем
Аватара пользователя
Сообщения: 445
Зарегистрирован: Ср сен 16, 2020 20:38:41
Откуда: Краснодарский край, г.Абинск

Сообщение JMC.Hard »

[uquote="Land",url="/forum/viewtopic.php?p=4203121#p4203121"]А почему #define NAME из одного .с файла не определено для другого? И как с этим бороться?[/uquote]
А для этого, Land, в языках программирования существует такое понятие, как область видимости. Покопайте в эту сторону :wink:
Лучше сделать и жалеть, чем жалеть, что не сделал ...
Прорезались зубы
Сообщения: 217
Зарегистрирован: Ср янв 11, 2012 11:55:51

Сообщение Land »

[uquote="COKPOWEHEU",url="/forum/viewtopic.php?p=4203123#p4203123"]Чего вы хотите добиться этим я вообще не знаю.[/uquote]
не прописывать одни и те же дефайны по пять раз в разных файлах. Вроде как очевидно

Добавлено after 30 seconds:
[uquote="JMC.Hard",url="/forum/viewtopic.php?p=4203190#p4203190"][uquote="Land",url="/forum/viewtopic.php?p=4203121#p4203121"]А почему #define NAME из одного .с файла не определено для другого? И как с этим бороться?[/uquote]
А для этого, Land, в языках программирования существует такое понятие, как область видимости. Покопайте в эту сторону :wink:[/uquote]
спасибо.
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

не прописывать одни и те же дефайны по пять раз в разных файлах. Вроде как очевидно
Что плохого в том, что в каждом файле прописывается именно то, что в нем нужно, а не абы что?
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32

Сообщение Martian »

Ну, если значение одного и того же дефайна должно быть одним и тем же для всех файлов, где он используется, то как-то странно его прописывать сколько-то раз. В конце концов, если его потом надо изменить, где-то забудется и приведёт к ошибке.
Контактная информация:
Ответить

Вернуться в «AVR»