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

Darth Vader

Участник
  • Публикаций

    73
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о Darth Vader

  • Звание
    Участник

Посетители профиля

140 просмотров профиля
  1. 2018 Вопросы начинающих

    А как можно посмотреть классы, сгенерированные при компиляции PCB-проекта? Их генерацию или отсутствие можно задавать галочками в опциях проекта на вкладке Class Generation. Но вот какие именно классы в итоге сгенерировались, как они называются и что в них входит посмотреть не удаётся. Да, если перейти к PCB, то там можно посмотреть классы в меню Design -> Classes... Но не всегда это дает полную картину. Например: 1. PCB в проекте ещё нет. Не добавлена, не сделана. Пока что есть только схема. Хотелось бы знать, какие классы с какими членами сгенерировались при её компиляции. 2. PCB в проекте уже есть, но при переносе изменений из схемы в PCB или наоборот между классами цепей схемы и PCB есть различия. Для полноты картины хотелось бы видеть, что за классы сгенерировались при компиляции схемы и какие классы есть в PCB. Если с просмотром классов в PCB проблем нет, то вот как поглядеть классы, сгенерированные в результате компиляции схемы?
  2. Нет. Я об этом не говорил. Автор темы - да, возможно. Моя же задача - разместить константную структуру в области флеш-памяти, одновременно инициализировав её при этом нужными мне значениями. Чтобы была возможность изменять некоторые параметры не затрагивая основную прошивку и не перекомпилируя и перезаливая программу. Пример со знакогенератором для матричного индикатора тоже очень подходящий. Там стоит та же задача, только размещать надо массив с начертанием символов.
  3. Изначальная задача (у меня) - инициализировать объект, разместив его по точному, заданному мной, адресу. Объект - структура с кучей полей - настроечных параметров. Указатель на объект сделать можно. Присвоить ему нужный адрес тоже. Разместить объект в памяти по этому указателю также можно. Но инициализировать такой объект одновременно с его объявлением через указатель нельзя. Далее, уже в самой программе, в функции main() или любой другой функции, можно присвоить значения его полям. По-отдельности каждому. Но мне надо не присвоить по-отдельности, а именно инициализировать все разом через список инициализации. В конечном итоге я должен получить, чтобы вместе с кодом программы в прошивке присутствовало значение этого объекта, которое будет зашито в область флеш-памяти по заданному адресу. Ещё один распространенный пример из этой серии - размещение таблицы символов знакогенератора для матричного индикатора в области флеш-памяти.
  4. Пришлось-таки использовать директивы. Чтобы скрыть компиляторозависимую часть кода - обернул её макросом. Пока что определил только часть для Кейла. Когда понадобится использовать код в других IDE с другими компиляторами - надо будет взамен #error определить соответствующие директивы размещения. #include <stdint.h> // Простая структура для примера struct MyConfig_st { uint8_t Field1; uint8_t Field2; uint8_t Field3; }; #define CONFIG_ADR 0x1E800 // Адрес структуры конфигурации в памяти EEPROM // Макрос атрибута размещения объекта по адресу ADR_VAL #if defined ( __CC_ARM ) // for ARM Compiler #define __AT_ADDR(ADR_VAL) __attribute__((at(ADR_VAL))) #elif defined ( __ICCARM__ ) // for IAR Compiler #error __AT_ADDR(ADR_VAL) не определён для компилятора IAR! #elif defined ( __GNUC__ ) // for GNU Compiler #error __AT_ADDR(ADR_VAL) не определён для компилятора GNU! #elif defined ( __TASKING__ ) // for TASKING Compiler #error __AT_ADDR(ADR_VAL) не определён для компилятора TASKING! #elif defined ( __CMCARM__ ) // for Phyton CMC-ARM Compiler #error __AT_ADDR(ADR_VAL) не определён для компилятора Phyton CMC-ARM! #else #error __AT_ADDR(ADR_VAL) не определён для используемого компилятора! #endif // Объявляем и инициализируем константную структуру конфигурации по адресу CONFIG_ADR const MyConfig_st MyConfig __AT_ADDR(CONFIG_ADR) ={0x66,0x41,0x7};
  5. 2018 Вопросы начинающих

    Нет. Есть такой тип компонентов - перемычки (Jumper). Если конт. площадки на одной ПП внутри заготовки соединить с такими же на другой ПП и назначить им Type=Jumper и одинаковое ненулевое значение JumperID, то Альтиум будет знать, что они соединены внешним проводом - перемычкой. Тогда никакого конфликта или ошибок не будет.
  6. 2018 Вопросы начинающих

    Нет. Это будут 3 проекта: два PCB- проекта, и один проект мультиборд. Причем у каждого из PCB-проектов будет своя схема. А то, что я имею ввиду, это один PCB-проект с одной схемой со сквозной нумерацией компонентов (она может состоять из нескольких листов), элементы которой раскиданы по двум или более печатным платам. Причем эти платы в проекте присутствуют именно в виде PCB, а не в виде ссылок на другие PCB-проекты. И нумерация компонентов на них полностью соответствует схеме.
  7. 2018 Вопросы начинающих

    Возможно, это не то, о чём был вопрос. А может и оно. Это появился новый тип проектов - прибор (или устройство). Т.е. несколько электрически и механически связанных между собой PCB, ЭРИ, соединителей, жгутов/проводов. Полезная штука. В предыдущих версиях этого не хватало. Из-за этого приходилось схему всего прибора делать, как PCB-проект, содержащий только листы схем без PCB. А функциональные блоки ( в т.ч. печатные платы) изображать прямоугольниками с контактными площадками (соединителями), чисто графически. Естественно, возможностей для автоматической проверки и выявления ошибок такого проекта было мало. А вопрос, возможно, был в том, что концепция PCB-проекта Альтиума - это один проект - одна печатная плата. А не появилась ли в 18 версии возможность результатом одного PCB-проекта иметь более одной печатной платы? Типа, раскидать схему на две PCB, а затем сделать из них склейку, связав цепи на платах перемычками из проводов?
  8. Для описанной задачи этого не требуется. Всё, что надо для этого знать я сообщил компилятору двумя макросами: #define CONFIG_ADR 0x20000 // Адрес стр-ры конфигурации в памяти EEPROM #define MyConfig_ptr ((MyConfig_st*)CONFIG_ADR) // Указатель на стр-ру конфигурации в памяти EEPROM и описанием типа (структуры) MyConfig_st. От языка/компилятора требуется лишь поддержка инициализации объекта по указателю на него (тот самый (MyConfig_st*)CONFIG_ADR ). А с этим, как оказалось, засада. Указатель создать можно. Его можно использовать в коде для обращения к объектам: записи/чтения в/из них значений. На этом принципе построено обращение ко всем регистрам периферии. Но вот инициализировать объект по нему списком инициализации почему-то оказалось нельзя. По имени объекта можно, а по указателю на него нельзя. Было бы можно - задача решилась бы. Жаль.
  9. Что-то типа такого? #include <stdint.h> // Простая структура для примера struct MyConfig_st { uint8_t Field1; uint8_t Field2; uint8_t Field3; }; #define CONFIG_ADR 0x20000 // Адрес стр-ры конфигурации в памяти EEPROM #define MyConfig_ptr ((MyConfig_st*)CONFIG_ADR) // Указатель на стр-ру конфигурации в памяти EEPROM // Заполнение стр-ры значениями // S - указатель на стр-ру // F1, F2, F3 - значения полей void MyConfigInic (MyConfig_st* S,uint8_t F1,uint8_t F2,uint8_t F3) { S->Field1 = F1; S->Field2 = F2; S->Field3 = F3; } uint8_t tmp; // Сюда будем считывать данные из стр-ры int main () { // Присваиваем значение полям стр-ры MyConfigInic (MyConfig_ptr,0x66,0x41,0x7); // Считываем значения полей стр-ры tmp = MyConfig_ptr->Field1; // Прочитали значение 0x66 tmp = MyConfig_ptr->Field2; // Прочитали значение 0x41 tmp = MyConfig_ptr->Field3; // Прочитали значение 0x7 } Такое нормально сработает, если область размещения стр-ры будет в ОЗУ. При вызове функции MyConfigInic() с указателем на стр-ру и значениями для заполнения полей произойдёт присваивание полям стр-ры новых значений из аргументов ф-ции. Далее с полями стр-ры можно будет работать, обращаясь к ним через указатель. Но если стр-ра должна размещаться в области флеш-памяти, т.е. там же, где и код программы, то такой код не сможет инициализировать стр-ру данными. Простое присваивание данным во флеш-памяти новых значений не запишет там ничего.
  10. А есть ли стандартный, т.е. не выходящий за синтаксис С/С++ способ инициализации объекта по точно указанному адресу? Под объектом понимается объект данных любого типа - простого встроенного или составного пользовательского. Например целое число, перечисление, массив или структура. Вот пример кода, где объявляется и инициализируется константная структура с тремя полями данных. Из неё можно считывать данные - см. в main(). Но адрес её размещения в памяти выбирает линкер. #include <stdint.h> // Некая структура для примера struct MyConfig_st { uint8_t Field1; uint8_t Field2; uint8_t Field3; }; // Инициализация константной структуры const MyConfig_st MyConfig = {.Field1=0x66,.Field2=0x41,.Field3=0x7}; uint8_t tmp; // Сюда будем считывать данные структуры int main () { tmp=MyConfig.Field1; tmp=MyConfig.Field2; tmp=MyConfig.Field3; while(1); } Как штатными средствами C/C++ задать для этой структуры точный адрес? Я могу сделать указатель на неё и присвоить ему значение адреса при помощи приведения типа целого к указателю на структуру. Но инициализировать структуру по такому указателю я не могу. На строку с инициализацией компилятор (Keil Arm Compiler V5.06) ругается. #include <stdint.h> // Некая структура для примера struct MyConfig_st { uint8_t Field1; uint8_t Field2; uint8_t Field3; }; #define CONFIG_ADR 0x20000 // Адрес стр-ры конфигурации в памяти EEPROM #define MyConfig_ptr ((MyConfig_st*)CONFIG_ADR) // Указатель на стр-ру конфигурации в памяти EEPROM // Объявляем и инициализируем стр-ру в памяти EEPROM const MyConfig_st *MyConfig_ptr = {.Field1=0x66,.Field2=0x41,.Field3=0x7}; // Компилятор ругается !!! int main() { while(1); } Есть ли возможность сделать такое без использования директив размещения, которые в разных IDE и компиляторах/линкерах разные? Хотелось бы написать универсальный код, одинаково работающий везде, вне зависимости от среды разработки и компилятора.
  11. 2018 Вопросы начинающих

    Вход обратной связи (он же подстроечный, он же регулировочный) - это именно вход. Так что тип его in (или passive). Но уж точно не out (выход) и не power (цепи питания). А вход и выход линейного стабилизатора напряжения - они хотя для него являются in и out, но для всей прочей схемы это power. Так что скорее всего, лучше присвоить им тип power.
  12. 2018 Вопросы начинающих

    Их не так много: ЭСЛ, ТТЛ, ТТЛШ, N-MOS (N-МОП), CMOS (КМОП). Большинство современных российских и белорусских серий ИМС, таких, как 1554, 1564, 1594, 5584 изготавливаются по КМОП технологии. ИМС с повышенной стойкостью к воздействию спецфакторов - по КНИ (или КНС - это то же самое). Это те же структуры из КМОП-транзисторных ячеек, но на подложке из изолятора (сапфира). Из современных микросхем ТТЛ - серия 1533. Из названия следует, что MOS (МОП или МДП - это одно и то же). Это английская аббревиатура для полевого транзистора со структурой металл-окисел (диэлектрик)-полупроводник. Все современные ключевые/переключательные/импульсные полевые транзисторы - с индуцированным каналом - чтобы при напряжении затвор-исток близком к нулю транзистор был закрыт.
  13. 2018 Вопросы начинающих

    Правый нижний угол - клик на панель Design Compiller - в раскрывшемся списке ставьте галку на Navigator. Появится панель навигатора в которой будут видны все компоненты и цепи.
  14. отладка в Keil

    Спасибо. Так, вероятно, проще всего. И понятней. Сразу виден алгоритм: сначала зануляем всё битовое поле целиком ((reg) & ~(msk)), после чего выставляем в нем 1 в нужных разрядах ( | ((val) << (pos) & (msk)) ).
  15. отладка в Keil

    С макросом оказалось всё немного сложнее. При введении в него промежуточной переменной tmp появилась необходимость указывать её тип. Он должен совпадать с типом reg. А т.к. он в общем случае разный и заранее неизвестный, то придётся его вводить одним из параметров макроса. Как-то так // Макрос записи в регистр reg битовой последовательности val // в позицию pos (по младшему разряду), msk - маска битового поля #define TuneBitField(typename,reg,val,pos,msk) \ do { \ typename tmp=reg; \ tmp |= (((val) << (pos))&(msk)); \ tmp &= (((val) << (pos))|~(msk)); \ reg=tmp; \ } while (0) В С++ этот макрос можно (а скорее нужно) переоформить в виде шаблонной подставляемой (inline) функции, где параметром шаблона как раз и будет имя типа регистра reg, а аргументом функции будет ссылка на регистр, чтобы его содержимое можно было изменить. Второй вариант выхода из ситуации (для Си без плюсов) - переписать макрос без использования промежуточной переменной, приведя его к виду: do {reg=(reg&msk1)|msk2;} while (0) // Макрос записи в регистр reg битовой последовательности val // в позицию pos (по младшему разряду), msk - маска битового поля #define TuneBitField(reg,val,pos,msk) \ do { \ reg = ((reg)&(((val) << (pos)))|~(msk))|(((val) << (pos))&(msk)); \ } while (0)