Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей... |
01.12.2009, 02:14
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
struct & union в многофайловом проекте.
Привет всем.
Имеем многофайловый проект IARAVR, в котором подключены файлы:
mai.c
modul1.c
modul2.c
файл main.c
Код:
|
#include ‹main.h›
void main(void){
modul1_char=41;
modul2_char=61;
flaginp1=1; //identifier "flaginp1" is undefined, имя флана не определено, флаг не видим в этой части программы
flaginp2=1; //identifier "flaginp2" is undefined, имя флана не определено, флаг не видим в этой части программы
modul1_rutin ();
modul2_rutin ();
flaginp1=0; //identifier "flaginp1 is undefined, имя флана не определено, флаг не видим в этой части программы
flaginp2=0; //identifier "flaginp2" is undefined, имя флана не определено, флаг не видим в этой части программы
modul1_char=00;
modul2_char=00;
while(1){
}} |
файл modul1.c
Код:
|
#include ‹main.h›
//определение глобальных переменных
unsigned char modul1_char; //структура битов (флагов)
struct { unsigned char
flagkey1:1,
flaginp1:1;}flag1;
#define flagkey1 flag1.flagkey1 //определим для удобства бращения к флагу по имени
#define flaginp1 flag1.flaginp1 //определим для удобства обращения к флагу по имени
//функция:
void modul1_rutin (void){
//определение локальных переменных
unsigned char temp1_modul1;
unsigned char temp2_modul1;
temp1_modul1=45;
flagkey1=1;
flagkey2=2; //identifier "flaginp1" is undefined
flagkey3=3; //identifier "flaginp1" is undefined
temp2_modul1=55;
temp1_modul1=modul2_char;
temp2_modul1=modul3_char;
modul1_char=temp1_modul1+temp2_modul1;
modul2_rutin ();
flaginp1=1;
} |
файл modul2.c
Код:
|
#include ‹main.h›
//определение глобальных переменных
unsigned char modul2_char;
struct { unsigned char //структура битов (флагов)
flagkey2:1,
flaginp2:1;}flag2;
#define flagkey2 flag2.flagkey2 //определим для удобства бращения к флагу по имени
#define flaginp2 flag2.flaginp2 //определим для удобства бращения к флагу по имени
//функция
void modul2_rutin (void){
//определение локальных переменных
unsigned char temp1_modul2;
unsigned char temp2_modul2;
temp1_modul2=45;
temp2_modul2=55;
flagkey1=1; //identifier "flaginp1" is undefined
flagkey2=1; //identifier "flaginp1" is undefined
temp1_modul2=modul1_char;
modul2_char=temp1_modul2+temp2_modul2;
flaginp2=1;
} |
файл main.h
Код:
|
#define fclc 8000000 //Hz
#include "iotiny2313.h"
#include ‹inavr.h›
#include ‹modul1.h› //подключим заголовоки всех с файлов .С в проекте
#include ‹modul2.h› |
файл modul1.h
Код:
|
//прототип функции
void modul1_rutin (void);
//обьявление глобальных переменных внешними, для доступа из других файлов .С
extern unsigned char modul1_char; |
файл modul2.h
Код:
|
//прототип функции
void modul2_rutin (void);
//обьявление глобальных переменных внешними, для доступа из других файлов .С
extern unsigned char modul2_char; |
Имеем доступ из всех файлов *.с к переменным из других файлов, обьявленых в *.h как extern unsigned char переменная;
это переменные объявленые внешними в хидерах (extern unsigned char modul1_char и extern unsigned char modul2_char)
вопрос:
как обьявить структуру или союз (в самих файлах *.С или в их хидерах), что бы так же были видимыми во всех файлах *.с ?
(или объявить так что бы были видимыми только в некоторых файлах или функциях?)
объявление типа: в файлах *.С или в хидерах, вызывает ошибки.
extern struct имя;
или
extern имяструктуры.имя бита;
Или потребуется объявлять структуры (и союзы) в main.с?
хотелось бы флаги модуля обьявлять в самом модуле а не в main.c.
а обращатся к ним из других файлов.
В однофайловом проекте, когда файлы *.c подключаются в main.c таких проблем нет.
проект для IARAVR прикреплён в архиве.
|
|
|
|
01.12.2009, 03:30
|
|
Временная регистрация
Регистрация: 25.11.2009
Сообщений: 61
Сказал спасибо: 1
Сказали Спасибо 17 раз(а) в 17 сообщении(ях)
|
Re: struct & union в многофайловом проекте.
modul1.h
struct flag2_t {
unsigned char //структура битов (флагов)
flagkey2:1,
flaginp2:1;
};
extern struct flag2_t flag2;
#define flagkey2 flag2.flagkey2
#define flaginp2 flag2.flaginp2
modul1.c
struct flag2_t flag2;
|
|
|
|
01.12.2009, 10:51
|
|
Почётный гражданин KAZUS.RU
Регистрация: 06.02.2007
Сообщений: 1,340
Сказал спасибо: 3
Сказали Спасибо 106 раз(а) в 66 сообщении(ях)
|
Re: struct & union в многофайловом проекте.
Покарежил, что успел, перед работой, посмотри.
Последний раз редактировалось urry; 01.12.2009 в 11:08.
|
|
|
|
01.12.2009, 14:35
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
|
Re: struct & union в многофайловом проекте.
main.h
typedef struct{
unsigned flagkey:1;
unsigned flaginp:1;
}tpFlagsStruct;
#define flagkey FlagsStruct.flagkey //определим для удобства бращения к флагу по имени
#define flaginp FlagsStruct.flaginp //определим для удобства обращения к флагу по имени
main.c
tpFlagsStruct FlagsStruct;
В те файлы где нужен доступ к флагам из FlagsStruct достаточно добавить две строчки
#include "main.h"
extern tpFlagsStruct FlagStruct;
Вторую можно вообще в main.h перенести, но тогда доступ к флагам получат любые модули подключающие main.h.
|
|
|
|
01.12.2009, 15:36
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
Re: struct & union в многофайловом проекте.
всем спасибо, попробую отпишусь
|
|
|
|
07.12.2009, 05:00
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
Re: struct & union в многофайловом проекте.
Из всего вышеизложеного товарищами, получилось 4 варианта синтаксиса обьявления и определения внешних структур(struct) для многофайловых проектов, приемлемых моим нуждам. В общем то записи похожи, но есть некоторые отличия.
Компилируется и работает в IAR AVR.
Кому интересно, выкладываю 4 проекта для IAR AVR5.3
|
|
|
|
07.12.2009, 05:36
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
|
Re: struct & union в многофайловом проекте.
4 варианта и все кривые ![Улыбка](images/smilies/icon_smile.gif)
Если структуры одинаковые зачем объявлять 4 типа? А если понадобится работать с ними через указатель? Придется приводить тип к одному из 4-х при взятии адреса. Или к void*. Некрасиво это. Объявление типа должно быть одно.
|
|
|
|
07.12.2009, 18:19
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
Re: struct & union в многофайловом проекте.
Сообщение от kison
|
4 варианта и все кривые ![Улыбка](images/smilies/icon_smile.gif)
Если структуры одинаковые зачем объявлять 4 типа? А если понадобится работать с ними через указатель? Придется приводить тип к одному из 4-х при взятии адреса. Или к void*. Некрасиво это. Объявление типа должно быть одно.
|
Кривые с точки зрения синтаксиса языка СИ?.. думаю тогда бы они не компилировались..
или почему кривые?
Ваш вариант обьявления в МАЙН не понравился. Потому, что мне удобно обьявлять флаги, в файле к которому они относятся, а не все флаги учавствующие в проекте обьявлять в майн.
Что бы при присоединении файла *.c и *.h к новому проект, флаги УЖЕ были обьявлены, и не обьявлять их в каждом новом проекте каждый раз ручками... Что бы свесит к минимуму, телодвижения при формировании нового проекта из уже существующих модулей-файлов.
Можно конечно в каждом новом проекте обьявлять все флаги которые будут в нём использоватся. Но мне кажется это не очень удобным.
Может я и не прав с точки зрения Си. Но мне такой подход удобнее. Обьявил один раз при написании модуля и забыл. Я так понимаю и указатели так же можно обьявить в кажом модуле и более к ним не возращатся. Такой подход возможен?
Поясните про указатели.. я с ними ещё не знакомился... почему нельзя работать с флагами как с битовыми перемеными и в чём прелесть указателей. Если конечно у вас есть охота.
С уважением.
Последний раз редактировалось picavr; 07.12.2009 в 18:30.
|
|
|
|
07.12.2009, 20:44
|
|
Почётный гражданин KAZUS.RU
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
|
Re: struct & union в многофайловом проекте.
Сообщение от picavr
|
Кривые с точки зрения синтаксиса языка СИ?.. думаю тогда бы они не компилировались..
или почему кривые?
|
Нет, не синтаксиса С, а обычного здравого смысла. Ну и негласных правил программирования, ведь программы пишутся не только для себя, но и другие люди должны суметь разобраться в исходнике.
Сообщение от picavr
|
Ваш вариант обьявления в МАЙН не понравился. Потому, что мне удобно обьявлять флаги, в файле к которому они относятся, а не все флаги учавствующие в проекте обьявлять в майн.
|
Объявлять переменную можно где угодно, а вот тип описывать в одном месте.
И для ОДИНАКОВЫХ структуп тип тоже должен быть один. Это дает возможность использовать функции передавая им указатель на структуру как параметр.
Ну для примера:
Код:
|
typedef struct
{
uint8_t PriVar;
uint8_t SecVar;
} tpMyStruct;
tpMyStruct MyStruct1, MyStruct2;
uint8_t average(tpMyStruct* pMyStruct)
{
return (pMyStruct-›PriVar + pMyStruct-›SecVar) / 2;
}
int main(void)
{
uint8_t a,b;
a = average(&MyStruct1);
b = average(&MyStruct2);
} |
Функции все равно, с какой структурой ей приходится работать.
Сейчас же есть аж четыре типа для одинаковых структур.
Надо выносить typedef в одно место.
Но если все же хочется иметь в каждом модуле свое описание типа, то его придется обрамлять директивами препроцессора:
Код:
|
// modul1.h
#ifndef TP_MY_STRUCT
#define TP_MY_STRUCT
typedef struct
{
uint8_t PriVar;
uint8_t SecVar;
} tpMyStruct;
#endif
extern tpMyStruct MyStruct1;
// modul1.c
tpMyStruct MyStruct1; |
Кстати в хидерах принято обрамлять весь текст в такие же директивы используя имя хидера как сигнализатор подключенности:
Код:
|
#ifndef MODUL1_H
#define MODUL1_H
// тело хидера
#endif |
Это позволяет произвольно подключать заголовки в другие заголовки и не бояться двойного подключения.
Но в случае четырехкратного размножения одного типа существует опасность изменить тип в одном модуле и не изменить в других. Это может привести к веселым глюкам ![Улыбка](images/smilies/icon_smile.gif) Если же определение типа есть только в одном месте, то такая ситуация исключена.
Кстати можно пойти дальше и собрать всю работу с флагами в одном модуле - используя функции вместо дефайнов. И весь доступ осуществлять только через них. Тем более что обычно работать с флагами приходится в критических секциях, ведь флаги чаще всего используются для сигнализации основному потоку о событиях в прерывании. Так что критические секции можно сразу включить в функцию модификации флагов. Этакая инкапсуляция. А вообще С не рассчитан на удобную работу с однотипными объектами, если они конечно не собраны в один массив. Эту задачу решил С++.
|
|
|
|
08.12.2009, 01:24
|
|
Почётный гражданин KAZUS.RU
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
|
Re: struct & union в многофайловом проекте.
Мне было необходимо только обьявление структуры битов, для видимости из внешних файлов. Потому что флаги в IAR нельзя определить как битовую переменную как например можно в HITECH PIC, можно только через битовую структуру.
И размеры структур в моих файлах не всегда одинаковые скорее наоборот, количество флагов всегда разное, в примерах для простоты сделал их одинаковыми.
Я не могу говорить/спорить по поводу определения типа структуры (typedef struct) потому что пока не понял, для чего его нужно определять. Если структуру можно объявить не определяя предварительно её тип.
Я так понимаю, что определение типа структуры(размер и количество элементов) в данном случае происходит в самом обьявлении структуры.. или нет?
Код:
|
struct flags_keys{ unsigned char//имя структуры и размер структуры
flagkey0:1, //имя элемента : размер элемента
flagkey1:1, //имя элемента : размер элемента
flagkey2:1, //имя элемента : размер элемента
flagkey3:1; //имя элемента : размер элемента
}; |
Зачем предварительно определять тип структуры? что бы объявить несколько однотипных структур? ведь можно их объявить и без определения типа.
в двух проектах которые я выложил, так и происходит, обьявление структур без определения их типа - TYPEDEF.
Почитал у класиков Шилд и Прата, описывается КАК зопределить тип структуры и потом как объявить структуру этого типа, но не говорится ДЛЯ ЧЕГО необходимо? Это связано с указателями?
Последний раз редактировалось picavr; 08.12.2009 в 01:34.
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 15:24.
|
|