Перейти к содержанию
    

Простой вопрос по инициализации переменной sfr

Сильно не пинайте, на С перешел неделю назад, пишу в 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Обычно объявлять sfr есть необходимость только если компилятор из коробки не поддерживает выбранный чип.

Судя по тому что у Вас PIC и среда MPLab - оба от одного производителя, то смею предположить что Вы что-то делаете не так.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

.... смею предположить что Вы что-то делаете не так.
Это тоже вполне допустимо :)

Регистры sfr конечно же переопределять задача не стоит.

Тут суть в чем: в файле lib.c лежит универсальный код, нпример реализован LCD, ему нужно работать с sfr (DB0...DB7, EN, RS...), каждый раз, когда этот файл используется (в другом приложении), править хеадер как-то не корректно (наверное). Посему в lib.c есть только объявление sfr переменной (что бы код компилился), а ее инициализация происходит уже в другом файле (e.g. main.c).

Как-то так...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

править хеадер как-то не корректно (наверное).

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

 

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

 

#define LCD_PORT PORTB

 

и далее везде в модуле LCD работайте не напрямую, а через макрос LCD_PORT

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

#define LCD_PORT PORTB и далее везде в модуле LCD работайте не напрямую, а через макрос LCD_PORT
Ото ж, я так и делал, только если файлы лежат в разных проектах, то компилятор ее не видит (в данном случае lib.c прикручен к рабочему проекту как библиотека).

Похоже это приколы этого компилятора или, что скорее всего, я еще не до конца разобрался...

Вот только не понятно, все таки как extern переменную инициализировать не значением, а адресом, в данном случае sfr регистра.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ото ж, я так и делал, только если файлы лежат в разных проектах, то компилятор ее не видит (в данном случае lib.c прикручен к рабочему проекту как библиотека).

Похоже это приколы этого компилятора или, что скорее всего, я еще не до конца разобрался...

Вот только не понятно, все таки как extern переменную инициализировать не значением, а адресом, в данном случае sfr регистра.

Переменные extern инициализируются в месте их объявления (там где они без ключевого слова extern), а присваивать значения можно везде, где их видно.

Чтоб инициализировать переменную адресом Вам нужно смотреть в сторону указателей

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чтоб инициализировать переменную адресом Вам нужно смотреть в сторону указателей
С указателями понятно, но неужели нет стандартного решения...

Т.е. если в одном файле она объявленя как extern volatile unsigned int DATAPORT __attribute__ ((__sfr__));,

то в другом должно быть что-то типа volatile unsigned int DATAPORT __attribute__ ((__sfr__, __address__(0x200)));

Так вот этот атрибут __address__(0x200)__ компилятор не понимает...

Изменено пользователем vassabi

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С указателями понятно, но неужели нет стандартного решения...

Т.е. если в одном файле она объявленя как extern volatile unsigned int DATAPORT __attribute__ ((__sfr__));,

то в другом должно быть что-то типа volatile unsigned int DATAPORT __attribute__ ((__sfr__, __addr[0x200]__));

Так вот этот атрибут __addr[0x200]__ компилятор не понимает...

С некоторыми упрощениями (насчет того что делает компилятор, а что линкер) можно сказать следующее:

Еxtern говорит компилятору что эта переменная определена в другом модуле, таким образом он не выделяет под нее еще одну область памяти.

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

Даже если компилятор скомпилирует все модули то потом ругнется линкер что типы переменных не совпадают.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...должны в точности переписать ее объявление в том виде, в котором она объявлена (там где без extern)...

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

 

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

 

Изменено пользователем vassabi

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

Что за библиотека? Ваша или Third party?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

 

 

P.S. Как-то мало библиотеками приходилось пользоваться, потому не знаю будет ли работать такой вариант. В либе всю работу с портами делать через вызов функций. Сами функции определять в отдельном файле в соответсвии c реальным железом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

В любом случае, спасибо! Думаю, что я просто еще не достаточно с IDE разобрался...

 

==============

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

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

Изменено пользователем vassabi

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Сомневаюсь что это оптимально. Если у процессора куча режимов косвенной адресации то еще прокатит, во всех остальных случаях лучше когда адреса переменных известны на этапе компиляции

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

....во всех остальных случаях лучше когда адреса переменных известны на этапе компиляции
На этапе компиляции чего?

Если речь о библиотеке и она откомпилена, то там адреса этой переменной не будет, она же extern.

Если речь о компиляции основной задачи к которой зацеплена уже откомпиленая библиотека, то тут она (переменная) и пропишеться по адресу.

Изменено пользователем vassabi

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если речь о библиотеке и она откомпилена, то там адреса этой переменной не будет, она же extern.

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

Хотя это не всем критично, я обращаю внимание на такие моменты только потому, что у моих приборов батарейное питание и желаемый срок работы от батареи - не менее 6 лет.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...