реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Простой вопрос по инициализации переменной sfr, Объявление внешней sfr переменной в С
vassabi
сообщение Mar 22 2013, 15:00
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 156
Регистрация: 18-02-13
Из: Киев
Пользователь №: 75 678



Сильно не пинайте, на С перешел неделю назад, пишу в MPLAB X IDE 1.7

Как объявить sfr переменную в одном файле, а инициализировать в другом (например, первый файл библиотечный - lib.c, второй рабочий - main.c)
Например, мне нужно чтобы lib.c работал с регистром PORTB.
В lib.c я делаю объявление
extern volatile unsigned int DATAPORT __attribute__ ((__sfr__));

Как мне теперь инициализировать ее в main.c?
И еще вопрос, как делать объявление и инициализацию, в случае если нужно работать с переменной, которая ссылается на бит в sfr регистре?

з.ы. Хелп в MPLAB X очень тяжелый для восприятия, по большей чати отправляет к ANSI стандарту С (литературу по С я курю параллельно)

Сообщение отредактировал vassabi - Mar 22 2013, 15:01
Go to the top of the page
 
+Quote Post
jack_avenger
сообщение Mar 24 2013, 18:47
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 170
Регистрация: 30-06-05
Из: Киев
Пользователь №: 6 426



Обычно объявлять sfr есть необходимость только если компилятор из коробки не поддерживает выбранный чип.
Судя по тому что у Вас PIC и среда MPLab - оба от одного производителя, то смею предположить что Вы что-то делаете не так.
Go to the top of the page
 
+Quote Post
vassabi
сообщение Mar 24 2013, 19:00
Сообщение #3


Частый гость
**

Группа: Свой
Сообщений: 156
Регистрация: 18-02-13
Из: Киев
Пользователь №: 75 678



Цитата(jack_avenger @ Mar 24 2013, 20:47) *
.... смею предположить что Вы что-то делаете не так.
Это тоже вполне допустимо sm.gif
Регистры sfr конечно же переопределять задача не стоит.
Тут суть в чем: в файле lib.c лежит универсальный код, нпример реализован LCD, ему нужно работать с sfr (DB0...DB7, EN, RS...), каждый раз, когда этот файл используется (в другом приложении), править хеадер как-то не корректно (наверное). Посему в lib.c есть только объявление sfr переменной (что бы код компилился), а ее инициализация происходит уже в другом файле (e.g. main.c).
Как-то так...
Go to the top of the page
 
+Quote Post
jack_avenger
сообщение Mar 24 2013, 19:11
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 170
Регистрация: 30-06-05
Из: Киев
Пользователь №: 6 426



Цитата(vassabi @ Mar 24 2013, 23:00) *
править хеадер как-то не корректно (наверное).

Править хедер не стоит

Сделайте что-то вроде следующего

#define LCD_PORT PORTB

и далее везде в модуле LCD работайте не напрямую, а через макрос LCD_PORT
Go to the top of the page
 
+Quote Post
vassabi
сообщение Mar 24 2013, 19:16
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 156
Регистрация: 18-02-13
Из: Киев
Пользователь №: 75 678



Цитата(jack_avenger @ Mar 24 2013, 21:11) *
#define LCD_PORT PORTB и далее везде в модуле LCD работайте не напрямую, а через макрос LCD_PORT
Ото ж, я так и делал, только если файлы лежат в разных проектах, то компилятор ее не видит (в данном случае lib.c прикручен к рабочему проекту как библиотека).
Похоже это приколы этого компилятора или, что скорее всего, я еще не до конца разобрался...
Вот только не понятно, все таки как extern переменную инициализировать не значением, а адресом, в данном случае sfr регистра.
Go to the top of the page
 
+Quote Post
jack_avenger
сообщение Mar 24 2013, 19:21
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 170
Регистрация: 30-06-05
Из: Киев
Пользователь №: 6 426



Цитата(vassabi @ Mar 24 2013, 23:16) *
Ото ж, я так и делал, только если файлы лежат в разных проектах, то компилятор ее не видит (в данном случае lib.c прикручен к рабочему проекту как библиотека).
Похоже это приколы этого компилятора или, что скорее всего, я еще не до конца разобрался...
Вот только не понятно, все таки как extern переменную инициализировать не значением, а адресом, в данном случае sfr регистра.

Переменные extern инициализируются в месте их объявления (там где они без ключевого слова extern), а присваивать значения можно везде, где их видно.
Чтоб инициализировать переменную адресом Вам нужно смотреть в сторону указателей
Go to the top of the page
 
+Quote Post
vassabi
сообщение Mar 24 2013, 19:26
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 156
Регистрация: 18-02-13
Из: Киев
Пользователь №: 75 678



Цитата(jack_avenger @ Mar 24 2013, 21:21) *
Чтоб инициализировать переменную адресом Вам нужно смотреть в сторону указателей
С указателями понятно, но неужели нет стандартного решения...
Т.е. если в одном файле она объявленя как extern volatile unsigned int DATAPORT __attribute__ ((__sfr__));,
то в другом должно быть что-то типа volatile unsigned int DATAPORT __attribute__ ((__sfr__, __address__(0x200)));
Так вот этот атрибут __address__(0x200)__ компилятор не понимает...

Сообщение отредактировал vassabi - Mar 24 2013, 19:51
Go to the top of the page
 
+Quote Post
jack_avenger
сообщение Mar 24 2013, 19:43
Сообщение #8


Частый гость
**

Группа: Свой
Сообщений: 170
Регистрация: 30-06-05
Из: Киев
Пользователь №: 6 426



Цитата(vassabi @ Mar 24 2013, 23:26) *
С указателями понятно, но неужели нет стандартного решения...
Т.е. если в одном файле она объявленя как extern volatile unsigned int DATAPORT __attribute__ ((__sfr__));,
то в другом должно быть что-то типа volatile unsigned int DATAPORT __attribute__ ((__sfr__, __addr[0x200]__));
Так вот этот атрибут __addr[0x200]__ компилятор не понимает...

С некоторыми упрощениями (насчет того что делает компилятор, а что линкер) можно сказать следующее:
Еxtern говорит компилятору что эта переменная определена в другом модуле, таким образом он не выделяет под нее еще одну область памяти.
И дописывая перед переменной extern Вы должны в точности переписать ее объявление в том виде, в котором она объявлена (там где без extern) за исключением пожалуй начального значения и включая ее адрес. Т.е. сделать таким образом код работающий с разными адресами не получится.
Даже если компилятор скомпилирует все модули то потом ругнется линкер что типы переменных не совпадают.

Go to the top of the page
 
+Quote Post
vassabi
сообщение Mar 24 2013, 19:52
Сообщение #9


Частый гость
**

Группа: Свой
Сообщений: 156
Регистрация: 18-02-13
Из: Киев
Пользователь №: 75 678



Цитата(jack_avenger @ Mar 24 2013, 21:43) *
...должны в точности переписать ее объявление в том виде, в котором она объявлена (там где без extern)...

Да, это я в курсе...

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


Сообщение отредактировал vassabi - Mar 24 2013, 19:54
Go to the top of the page
 
+Quote Post
jack_avenger
сообщение Mar 24 2013, 20:14
Сообщение #10


Частый гость
**

Группа: Свой
Сообщений: 170
Регистрация: 30-06-05
Из: Киев
Пользователь №: 6 426



Цитата(vassabi @ Mar 24 2013, 23:52) *
Да, это я в курсе...

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

Что за библиотека? Ваша или Third party?
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Mar 24 2013, 20:15
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(vassabi @ Mar 24 2013, 21:52) *
Походу, самый правильный вариант только через препроцессор... но тогда билиотечный файл не хочет ее видеть и не компилится...

Вам обязательно чтоб библиотека была? Какой от этого профит? Может лучше исходники компилировать в каждом проекте?


P.S. Как-то мало библиотеками приходилось пользоваться, потому не знаю будет ли работать такой вариант. В либе всю работу с портами делать через вызов функций. Сами функции определять в отдельном файле в соответсвии c реальным железом.
Go to the top of the page
 
+Quote Post
vassabi
сообщение Mar 24 2013, 20:26
Сообщение #12


Частый гость
**

Группа: Свой
Сообщений: 156
Регистрация: 18-02-13
Из: Киев
Пользователь №: 75 678



Цитата(_Артём_ @ Mar 24 2013, 22:15) *
Вам обязательно чтоб библиотека была? Какой от этого профит? Может лучше исходники компилировать в каждом проекте?...
Ну сейчас так и делаю, не без дела же сидеть sm.gif
В любом случае, спасибо! Думаю, что я просто еще не достаточно с IDE разобрался...

==============
Хочу просто библиотеку отдельной сборкой держать, тут все таки есть свои плюсы, если код оптимизирован или откомпилен жирным дорогим компилятором в триал периоде wink.gif
Потм трассировщик туда уже не лезет, от основного не отвлекает. Кста, а кто нибудь знает, существуют ли атрибуты функций, которые позволяют трассировщику туда не залазить в процессе отладки?

Сообщение отредактировал vassabi - Mar 24 2013, 20:32
Go to the top of the page
 
+Quote Post
jack_avenger
сообщение Mar 24 2013, 20:48
Сообщение #13


Частый гость
**

Группа: Свой
Сообщений: 170
Регистрация: 30-06-05
Из: Киев
Пользователь №: 6 426



Цитата(vassabi @ Mar 25 2013, 00:26) *
Хочу просто библиотеку отдельной сборкой держать, тут все таки есть свои плюсы, если код оптимизирован или откомпилен жирным дорогим компилятором в триал периоде wink.gif

Сомневаюсь что это оптимально. Если у процессора куча режимов косвенной адресации то еще прокатит, во всех остальных случаях лучше когда адреса переменных известны на этапе компиляции
Go to the top of the page
 
+Quote Post
vassabi
сообщение Mar 24 2013, 20:54
Сообщение #14


Частый гость
**

Группа: Свой
Сообщений: 156
Регистрация: 18-02-13
Из: Киев
Пользователь №: 75 678



Цитата(jack_avenger @ Mar 24 2013, 22:48) *
....во всех остальных случаях лучше когда адреса переменных известны на этапе компиляции
На этапе компиляции чего?
Если речь о библиотеке и она откомпилена, то там адреса этой переменной не будет, она же extern.
Если речь о компиляции основной задачи к которой зацеплена уже откомпиленая библиотека, то тут она (переменная) и пропишеться по адресу.

Сообщение отредактировал vassabi - Mar 24 2013, 20:54
Go to the top of the page
 
+Quote Post
jack_avenger
сообщение Mar 24 2013, 21:02
Сообщение #15


Частый гость
**

Группа: Свой
Сообщений: 170
Регистрация: 30-06-05
Из: Киев
Пользователь №: 6 426



Цитата(vassabi @ Mar 25 2013, 00:54) *
Если речь о библиотеке и она откомпилена, то там адреса этой переменной не будет, она же extern.

Будет код для доступа к ресурсу. Если адрес известен заранее, то команды получаются быстрее и короче в сравнении с вариантом когда сначала этот адрес надо вычислить.
Хотя это не всем критично, я обращаю внимание на такие моменты только потому, что у моих приборов батарейное питание и желаемый срок работы от батареи - не менее 6 лет.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 16:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01483 секунд с 7
ELECTRONIX ©2004-2016