Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту

Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей...

 
Опции темы
Непрочитано 01.12.2009, 02:14  
picavr
Почётный гражданин KAZUS.RU
 
Аватар для picavr
 
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
picavr на пути к лучшему
По умолчанию 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 прикреплён в архиве.
Вложения:
Тип файла: rar test C.rar (24.0 Кб, 45 просмотров)
Реклама:
picavr вне форума  
Непрочитано 01.12.2009, 03:30  
roxfan
Временная регистрация
 
Регистрация: 25.11.2009
Сообщений: 61
Сказал спасибо: 1
Сказали Спасибо 17 раз(а) в 17 сообщении(ях)
roxfan на пути к лучшему
По умолчанию 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;
roxfan вне форума  
Сказали "Спасибо" roxfan
picavr (01.12.2009)
Непрочитано 01.12.2009, 10:51  
urry
Почётный гражданин KAZUS.RU
 
Аватар для urry
 
Регистрация: 06.02.2007
Сообщений: 1,340
Сказал спасибо: 3
Сказали Спасибо 106 раз(а) в 66 сообщении(ях)
urry на пути к лучшему
По умолчанию Re: struct & union в многофайловом проекте.

Покарежил, что успел, перед работой, посмотри.
Вложения:
Тип файла: rar test.rar (18.2 Кб, 63 просмотров)
__________________
warez

Последний раз редактировалось urry; 01.12.2009 в 11:08.
urry вне форума  
Сказали "Спасибо" urry
picavr (01.12.2009)
Непрочитано 01.12.2009, 14:35  
kison
Почётный гражданин KAZUS.RU
 
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
kison на пути к лучшему
По умолчанию 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.
kison вне форума  
Сказали "Спасибо" kison
picavr (01.12.2009)
Непрочитано 01.12.2009, 15:36  
picavr
Почётный гражданин KAZUS.RU
 
Аватар для picavr
 
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
picavr на пути к лучшему
Радость Re: struct & union в многофайловом проекте.

всем спасибо, попробую отпишусь
picavr вне форума  
Непрочитано 07.12.2009, 05:00  
picavr
Почётный гражданин KAZUS.RU
 
Аватар для picavr
 
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
picavr на пути к лучшему
По умолчанию Re: struct & union в многофайловом проекте.

Из всего вышеизложеного товарищами, получилось 4 варианта синтаксиса обьявления и определения внешних структур(struct) для многофайловых проектов, приемлемых моим нуждам. В общем то записи похожи, но есть некоторые отличия.

Компилируется и работает в IAR AVR.
Кому интересно, выкладываю 4 проекта для IAR AVR5.3
Вложения:
Тип файла: rar C struct external.rar (66.1 Кб, 70 просмотров)
picavr вне форума  
Непрочитано 07.12.2009, 05:36  
kison
Почётный гражданин KAZUS.RU
 
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
kison на пути к лучшему
По умолчанию Re: struct & union в многофайловом проекте.

4 варианта и все кривые
Если структуры одинаковые зачем объявлять 4 типа? А если понадобится работать с ними через указатель? Придется приводить тип к одному из 4-х при взятии адреса. Или к void*. Некрасиво это. Объявление типа должно быть одно.
kison вне форума  
Непрочитано 07.12.2009, 18:19  
picavr
Почётный гражданин KAZUS.RU
 
Аватар для picavr
 
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
picavr на пути к лучшему
По умолчанию Re: struct & union в многофайловом проекте.

Сообщение от kison Посмотреть сообщение
4 варианта и все кривые
Если структуры одинаковые зачем объявлять 4 типа? А если понадобится работать с ними через указатель? Придется приводить тип к одному из 4-х при взятии адреса. Или к void*. Некрасиво это. Объявление типа должно быть одно.
Кривые с точки зрения синтаксиса языка СИ?.. думаю тогда бы они не компилировались..
или почему кривые?

Ваш вариант обьявления в МАЙН не понравился. Потому, что мне удобно обьявлять флаги, в файле к которому они относятся, а не все флаги учавствующие в проекте обьявлять в майн.

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

Можно конечно в каждом новом проекте обьявлять все флаги которые будут в нём использоватся. Но мне кажется это не очень удобным.
Может я и не прав с точки зрения Си. Но мне такой подход удобнее. Обьявил один раз при написании модуля и забыл. Я так понимаю и указатели так же можно обьявить в кажом модуле и более к ним не возращатся. Такой подход возможен?

Поясните про указатели.. я с ними ещё не знакомился... почему нельзя работать с флагами как с битовыми перемеными и в чём прелесть указателей. Если конечно у вас есть охота.

С уважением.

Последний раз редактировалось picavr; 07.12.2009 в 18:30.
picavr вне форума  
Непрочитано 07.12.2009, 20:44  
kison
Почётный гражданин KAZUS.RU
 
Регистрация: 13.12.2004
Сообщений: 3,172
Сказал спасибо: 11
Сказали Спасибо 692 раз(а) в 504 сообщении(ях)
kison на пути к лучшему
По умолчанию 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
Это позволяет произвольно подключать заголовки в другие заголовки и не бояться двойного подключения.
Но в случае четырехкратного размножения одного типа существует опасность изменить тип в одном модуле и не изменить в других. Это может привести к веселым глюкам Если же определение типа есть только в одном месте, то такая ситуация исключена.
Кстати можно пойти дальше и собрать всю работу с флагами в одном модуле - используя функции вместо дефайнов. И весь доступ осуществлять только через них. Тем более что обычно работать с флагами приходится в критических секциях, ведь флаги чаще всего используются для сигнализации основному потоку о событиях в прерывании. Так что критические секции можно сразу включить в функцию модификации флагов. Этакая инкапсуляция. А вообще С не рассчитан на удобную работу с однотипными объектами, если они конечно не собраны в один массив. Эту задачу решил С++.
kison вне форума  
Сказали "Спасибо" kison
bbill_ (08.12.2009)
Непрочитано 08.12.2009, 01:24  
picavr
Почётный гражданин KAZUS.RU
 
Аватар для picavr
 
Регистрация: 07.10.2007
Адрес: Луганск
Сообщений: 1,816
Сказал спасибо: 13
Сказали Спасибо 399 раз(а) в 214 сообщении(ях)
picavr на пути к лучшему
По умолчанию 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.
picavr вне форума  
 

Закладки
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Часовой пояс GMT +4, время: 15:24.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot