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

Waso

Свой
  • Постов

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

  • Посещение

Сообщения, опубликованные Waso


  1. День добрый!

     

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

    На западе эту технологию недавно освоили. А как дела обстоят у наших восточных друзей (китайцев)?

    Ну или может быть даже на родине такое делают?

     

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

    Хотя именно пленку использовать для нас необязательно.

  2. Ладно, чтобы не смотрели на меня косо, открою карты. =) Мне надо написать прогу для работы пульта оператора, к которому подключается до 20 панелей клиентов. Для каждого клиента на пульте есть кнопка и двухцветный светик. Поведение всех клиентов описывается одной машиной состояний (StateMachine).

    Я задумал описать класс клиента, который содержит статус, процедуру обработки состояний, и ссылки на свои кнопку и светик, которые инициализируются в конструкторе. Кнопки и светики описаны в отдельных классах с интерфейсом "Нажата?", "Включить красный", "Выключить" и тп.. В main будет цикл, который будет перебирать массив указателей на классы клиентов и запускать процедуру обработки очередного клиента. Одна виртуальная функция добавляет 50байт кода для каждой кнопки или светика. Умножаем на кол-во кнопок и светиков, и еще на колво виртуальных методов и получаем много килобайт, невлезаем. Вот я и думаю как бы поизящнее решить эту проблему, чтобы поменьше писанины и пооптимальнее код.

     

    От виртуальных функций можно избавиться, избавившись от шаблонов и заплатив парой байт ОЗУ на каждую кнопку и светик - помнить номер строки и столбца не как параметр шаблона, а как константу.

     

    Интересно как решали такую проблему другие. =)

  3. Можно спросить - нафига наследовать MtxButton от MtxKeyboard , которая по жизни должна быть одна на всех, да еще и с виртуальными функциями, что вообще нонсенс.
    Ну я сделал все члены класса MtxKeyboard статическими, так что этот класс не должен размножаться при появлении дочерних классов. Но ваша запись со вложенным статическим классом более грамотна, спасибо. Виртуализовать функции кнопок я хочу чтобы была возможность загонять указатели на них в массивы и потом динамически перебирать в цикле. Хотя это и не всегда надо и всегда можно обойти, но если есть возможность без огромных неоправданных затрат использовать красивости плюсов - я хочу их использовать. Просто я только начинаю осваивать плюсы и могу легко сваять слона из мухи по неопытности. Такчто не раздражайтесь пожалуйста сильно по этому поводу.
  4. Продолжу задавать вопросы по плюсам в этой теме. Предыстория та-же.

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

    template<int row, int col>
    class MtxButton : public MtxKeyboard
    {
    public:
        /*virtual /*inline*/  uint8_t Get()        { return State[(col-1)]&(1<<(row-1));}
        /*virtual /*inline */ uint8_t Pressed()    { return (Get()&&(Ticks>=KEYPRES_TRESHOLD))? 1 : 0;}
        /*virtual /*inline */ uint8_t Locked()    { return (Get()&&(Ticks>=KEYLOCK_TRESHOLD))? 1 : 0;}
    };

    Простенькая тестовая прога:

    MtxButton<1,1> Key_Num1;
    MtxButton<1,2> Key_Num2;
    MtxButton<1,3> Key_Num3;
    MtxButton<1,4> Key_Num4;
    //========== еще 16 кнопок
    
    class Client_c
    {public:
        Client_c(MtxKeyboard *  pB):pButton(pB){};
        MtxKeyboard * pButton;};
    
    Client_c Client_1(&Key_Num1);
    Client_c Client_2(&Key_Num2);
    Client_c * pClient[]={&Client_1,&Client_2};
    
    int main(void){
      for(;;)  {
          Keys.Scan();
          if (Key_Num1.Pressed())pin1.Toggle();
                  if (Client_1.pButton->Pressed())pin2.Toggle();  }
    return 0;}

    на максимальной оптимизации в WinAVR130309 компилится в 500+ байт кода и около 10байт ОЗУ. Но вот как только я делаю функции наследников виртуальными - таже прога компилится в 3000+ байт кода и 230байт ОЗУ. Я в курсе про таблицу вызова виртуальных процедур, но 2 тыщи слов она не сожрет. В чем проблема? По сгенеренному асму не могу понять.. Какбудто оптимизация отключается. На всякий случай приложил исходники.

    virtual.zip

  5. Хорошо, но тогда эти ссылки будут храниться в ОЗУ, а ето непозволительный оверхед! Если даже в классе кнопки ссылку обьявить как константу и задавать в конструкторе, компилятор всеравно ее пихает в ОЗУ.. :(

  6. Добрый день! или не день =) ... Влеплю сюда вопрос по Си++.

     

    Не пойму как реализовать следующую идею:

    Заводим класс клавиатуры, в котором описан метод(процедура) опроса клавиатуры, которая обновляет находящуюся в этом-же классе переменную - битовую маску нажатых клавиш. (сколько клавиш-столько бит)

     class MtxKeypad
    {
    private:
      volatile KeyMapType NewKeyMap;   //  считываемая в данный момент карта клавиш
    public:
      volatile KeyMapType KeyMap;       // последняя считанная карта клавиш
    
      // typedef Mtx_Button<1,1> Key_1;        // !! эти строки относятся к вопросу сабжа
    // typedef Mtx_Button<1,2> Key_2;        // тут объявляются все кнопки и их расположение (строка,столбец) 
    // typedef Mtx_Button<2,1> Key_Enter;    
    // typedef Mtx_Button<4,1> Key_Cancel; 
    
      void Scan() {  // метод опроса клавиатуры
    // ....
          KeyMap=NewKeyMap;
    // ....
      }
    };

    далее заводим шаблон класса отдельной кнопки, который умеет сообщать, нажата эта кнопка или нет:

    template <int Col, int Row>
    class Mtx_Button : public MtxKeypad
    {
        //friend class MtxKeypad;    // это вот ХЗ надо тут или нет
    private:
    static const KeyMapType mask=(1UL<<(Row*5+Col));
    public:
      inline uint8_t Pressed() {return (MtxKeypad::KeyMap & mask)!=0;}
    };

    И нужно использовать потом так:

    int main()
    {
        MtxKeypad Keys;
        Mtx_Button<4,1> Key_A;
        for(;;)
        {
            Keys.Scan();
            if(MtxKeypad::Key_1::Pressed()) pin2.Toggle();  // ошибка
            if(Key_A.Pressed()) pin2.Toggle();  // работает если добавить Key_A.Scan(); но тут отдельный объект с отдельными переменными - неправильно
        }
    }

    Так вот ВНИМАНИЕ ВОПРОС: как правильно описать классы, если мне надо чтоб дочерние объекты не копировали родительский метод и переменные, а пользовались ими, влияли на них.

  7. Ну и нормально Только #if defined (PORTA) - лишнее, ибо не будет вызываться, пока вы не определите Pin<'A'...>. В этом прелесть шаблонов
    Да? А я ведь сначала без этих излишеств написал. У меня WinAVR тогда ругается
    'PORTE' was not declared in this scope

    ну и действительно такого порта нет в восьмой меге например. А компилятор всетаки анализирует весь текст видимо. Может я чтото не так сделал?

    С другой стороны для порта A дейсвительно это лишняя проверка, потомучто этот порт есть у всех авр-ок :lol:

     

    По поводу режима ноги - для сложных случаев я оставил режим BIDIR. Можно еще режимов напридумывать. Я ж ведь ради чего это делаю - чтобы не париться с инициализацией ножек. Хочется чтоб это все делал конструктор. Вот кстати непонятка: если обьявление Pin<'A'...> сделано НЕ внутри какойто функции, то куда вставит компилятор код конструкторов?

     

    А вы, похоже, смотрели вариант для stm32?
    Да. Но я просмотрел всю тему. Полезного почерпнул не только из последнего поста. :)
  8. AHTOXA, посмотрел я на ваши труды и попробовал написать подобное для АВР. Сначала было так:

    template<GPIO_mode_t mode, char port, int bit, char activestate>
    class Pin{
        inline volatile uint8_t & PORTx()
                {
            #if defined (PORTA)
                                     if (port == 'A') return PORTA;
             #endif
            #if defined (PORTB)
                                     if (port == 'B') return PORTB;
            #endif
          //..................такая конструкция для буков С..F и все вместе для DDRх и PINх}
        inline void On()
        {
            if ( mode==BIDIR || mode==OUTPUT ) {activestate == 'L' ? PORTx()&=~mask : PORTx()|=mask;}
            if ( mode==OUTPUT_OK ) {activestate == 'L' ? DDRx()|=mask : DDRx()&=~mask;}
        }
    // и тп
    }

    Потом пытался уменьшить количество писанины в части ссылок на регистры:

    template<char port> class Base_Pin;
    
    template<>  // такой шаблон для всех буков - можно сделать макрос
        class Base_Pin<'A'>
        {
        public:
            inline volatile uint8_t & PORTx(){return PORTA;}
                            inline volatile uint8_t & DDRx(){return DDRA;}
                            inline volatile uint8_t & PINx(){return PINA;}
        }; 
    
    template<GPIO_mode_t mode, char port, int bit, char activestate>
    class Pin2 : public Base_Pin<port>
    {    inline void On(){Base_Pin<port>::PORTx()|=(1<<bit);} };

    И если дальше "упрощать" создав макрос для объявления базовых классов всех портов, то приходим к необходимости отказаться от символьных констант и воспользоваться enum-ом. В итоге получаем код Alex312. Но я оставил себе первый вариант. Он хоть и громоздкий, но зато легко читаемый\понимаемый.

     

    И да кстати. Я так и не понял в чем вкусность переопределения операторов в примере Антона.

  9. Genadi, даже если уйти от смещений и явно указывать регистры, то проблема остается. Ведь компилятор ругается не на это. Он не хочет принимать указатель как константу.

     

    В теме с исходниками нашел такой файлик "avrio.hpp" от Аlex312. Там эта задача реализована через enum-ы:

    enum __bits {__bit_0=0, __bit_1=1, __bit_2=2, __bit_3=3, __bit_4=4, __bit_5=5, __bit_6=6, __bit_7=7};
    enum __ports{__port_A,__port_B,__port_C,__port_D,__port_E,__port_F,__port_G};
    enum __ports_reg {__reg_PORT, __reg_DDR, __reg_PIN};
    
    // Шаблон функции, определяющей требуемые адреса в пространстве В/В
    template <__ports port, __ports_reg reg> volatile uint8_t& __ports_ref();
    
    #define AVRLIB_SPECIALIZE_PORT_REF(_port_) \
    template <> inline volatile uint8_t& __ports_ref<__port_##_port_, __reg_PORT>() { return PORT##_port_; } \
    template <> inline volatile uint8_t& __ports_ref<__port_##_port_, __reg_DDR >() { return DDR##_port_; } \
    template <> inline volatile uint8_t& __ports_ref<__port_##_port_, __reg_PIN >() { return PIN##_port_; }
    
    #if defined (PORTA)
    AVRLIB_SPECIALIZE_PORT_REF(A)
    #endif
    #if defined (PORTB)
    AVRLIB_SPECIALIZE_PORT_REF(B)
    #endif
    .....
    template <__ports port, __bits bit>
    class __pin
    {
    public:
        static inline void set(void)
        {
            __ports_ref<port, __reg_PORT>()|=bit_mask(bit);
        }
    };
    __pin<__port_C,__bit_4> out4;
    out4.set();

    Довольно муторно, но работает. Правда на этот раз несварение возникает у Иара. Даже на максимальной оптимизации он упорно отказывается сводить "out4.set();" к ассемблерному "sbi".

  10. template <uint8_t volatile & port, const char bit>
    class mypin
    {
    public:
            __inline mypin(){*(&port-1)|=(1<<bit);}
        static __inline void set()    {port|=(1<<bit);}
    };
    
    mypin<PORTA,4> mypinname;
    mypinname.set();

    такой вариант работает в иаре, но ухудшается оптимизация. ВинАВР же опять не доволен строчкой "mypin<PORTA,4> mypinname;":

        - template argument 1 is invalid
        - `*' cannot appear in a constant-expression
        - a cast to a type other than an integral or enumeration type cannot appear in a constant-expression

    звезда там берется из разложения макроса PORTA => (*(volatile uint8_t *)((0x1B) + 0x20))

  11. Всем доброго времени суток!

     

    Понадобилось перенести проект с IAR (EWAVR 530) на WinAVR (20090313) для юридической чистоты...

    Вылезла такая бяка: Иар успешно работает с такой конструкцией:

    template <unsigned char volatile * port, const char bit>
    class mypin
    {
    public:
            inline mypin() {*(port-1)|=(1<<bit);} // смещение -1 - регистр DDR - настраиваем на выход.
            static inline void set()    {*port|=(1<<bit);}
    };
    int main()
    {
        mypin<&PORTA,4> mypinname; // тут мы обьявляем место подключения и инициализируем одновременно
    //...
         mypinname.set();
    //...
    }

    А WinAVR глючит на конструкции &PORTA в объявлении класса и заявляет что не хватает параметров:

        - wrong number of template arguments (1, should be 2) provided for 'template<volatile uint8_t* port, char bit> class mypin'

    хотя в другом месте адрес порта успешно изымается:

    volatile uint8_t* portC = &PORTC;
    *portC &= ~(1<<7);

    Это глюк компилятора? Как это можно обойти? Подскажите пожалуйста!

  12. День добрый, уважаемые форумчане!

     

    Понадобилось сделать платку, 6 слоев, в которой диэлектриком между первым и вторым слоями топологии служит СВЧ материал (как вариант Rogers RO4350), а для остальных слоёв используется стандартный FR4. Резонит за такую платку размером 150х200 мм запросил аж порядка 20 тыс. рублей, чем меня премного удивил. Надеюсь это какаято ошибка. (Если даже там 2-3 платы на заготовке, всеравно страшно)

     

    Интересует - делал ли ктонибудь из присутствующих подобные платы. Где, почем и какие советы можете дать.

     

    Поиском пользовался, короткие слова типа СВЧ он не ищет.. Короче если такая тема обсуждалась - прошу извинить и наставить на путь истинный. :)

  13. Занимаюсь получением спектра по модифицированному ковариационному алгоритму, описанному в книге Марпла мл., на которую тут ссылались.

    Написал прогу. Вернее списал с книжки, перевел с тамошнего фортрана на экселевский бейсик (ну надо оно мне там!!).

    Но она считает неправильно. В конце той книги должна быть тест-последовательность, по которой можно отладить все процедурки,

    приведенные в книге. Но в моем дэжавюшнике книга обрывается на стр 547, где еще идет окончание 16-й главы... Откуда я только не качал

    эту книженцию - везде лежит одно и тоже. Иногда по половинкам иногда целая, но косяки все теже.

    У кого есть ПРИЛОЖЕНИЕ II с 64-точечной комплексной тест-последовательностью марпла - помогите пожалуйста! Можно прямо тут положить. :)

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

    А все. Сам нашел. )))) Там-же есть постраничная выкладка этой книги. Там все от начала и до конца и в хорошем качестве. Только чтоб показывало - надо скачать 0584.djbz обязательно. и можно по страничкам смотреть.

  14. Перемычку переставил.

    ОШИБОК НЕТ!

    Есть небольшие отклонения от схемы - сопротивление R12 - 200к

    С4 из двух 22+10

    как мне кажется повлиять на работоспособность недолжно.

    У данного программатора критичны номиналы сопротивлений в цепи контроля сброса (Reset_ADC и т.п.). У меня с резистором 200к не работало, поставил 220к - заработало. Пробуйте. ;) Ну а по портам - следите чтоб ваш виртуальный USB-COM порт не был занят другой программой, когда прошиваете. Как это проверить.... а проще всего перезагрузить комп. :D

     

    А Петру советую убрать эту проверку ресета - много крови она мне попортила. ))) 220к - редкий номинал. И даже опытному человеку при взгляде на схему без знания особенностей прошивки не очевидно, что этот резистор не терпит отклонений даже на 10%. ;)

  15. Возникла идея, хотя возможно она не нова. Идея в том чтобы выводить отладочную информацию через тотже SPI, через который зашиваем прогу. Контроллер в программаторе переправляет полученные по SPI данные прямо в UART и обратно (когда не в режиме программирования). Таким образом со стороны компа ничего не меняется - отладка через тотже виртуальный компорт. А на плате избавляемся от дополнительных отладочных линий. И от дополнительного отладочного шнурка. Если присутствуют другие устройства на шине SPI - ну тут уже поле для фантазии: либо просматривать все что вообще летает по SPI либо всеже задействовать для отладочной информации отдельную линию ENable.

  16. Здравствуйте! Использую библиотеку элементов на основе базы данных - экселевского файла. Для разделения на группы (транзисторы/микрухи/коммутация/индикация) использую вкладки в одном и томже файле. Сначала всем был доволен, но когда библиотека набрала жирка - стали заметны тормоза. И это еще мягко сказано. Схема в сотню элементов переносится на плату около получаса! Также заметны паузы при добавлении компонентов, а если вдруг понадобилось обновить параметры из базы - пиши пропало - комп задумывается надолго. Комп не слабый. Core2Duo 2.6ГГц, 1Гб ОЗУ.

     

    Теперь вопрос. Как уменьшить тормоза, не уходя от принципа базы данных. Ну тоесть я могу сделать отдельный xls и DbLib на каждую группу компонентов или перейти от экселя к аксесу, но поможет ли это. Работы слишком много чтобы вот так вот взять и проэкспериментировать. Посоветуйте пожалуйста.

  17. xlive AP0101 Polygon Pours & Copper Regions.pdf

    Но надо дружить с английским.

     

    Подсветка: DXP\Preferences\PCB editor - Board Insight Display - Live Highlight

     

    Владимир Ну это совсем дубовый способ - тогда и рамку надо масштабировать заранее, либо печатать сначала только рамку в масштабе 1:1, а потом совать ее обратно в принтер и печатать увеличенную плату. Это есть не совсем удобно, хотя всеравно спасибо - сам не догадался. В OutputJob-ах можно както сделать, чтоб какието слои он печатал 1:1 а другие 5:1 например ?

     

    +Еще вопрос. Как задать несколько предустановок генератора Bill of Materials? Например мне для создания перечня элементов по ГОСТу удобно сортировать элементы по Designator-у, а для спецификации или списка для закупки - по Comment-у. Приходится перетаскивать то один то другой из этих столбиков в окошко группировки, да и другие менять. Геморрой однако!

  18. Скажите пожалуйста, есть ли возможность масштабировать плату при выводе на печать. Например я развел плату, нужно выпустить КД. Оформил тут-же в Альтиуме чертеж - рамку нарисовал, размеров понаставил, табличку отверстий он сам втыкает - нет счастью предела. Но на плате много мелких деталей. Наколдовать бы простым движеньем рук масштаб 2:1 или больше и вапче былабы жизнь-малина тогда....

  19. Перед разводкой платы забыл указать пары механических слоев (вернее не знал что это надо сделать...). Изза этого корпуса всех компонентов (и тех что сверху и тех что снизу) остались у меня в первом мех.слое. А этот слой я использую для подготовки документации - монтажных схем. Получается абра-кадабра. Развел уже много. Какнибудь можно парой простых движений рук переместить все примитивы, находящиеся в слое мех1 у нижних компонентов в слой мех2 :?:

  20. Vokchap, Zeroom - спасибо за ответы!

     

    Еще вопрос. Можно ли настроить Fanout таким образом, чтобы он автоматически отвел от QFP-шного корпуса (с шагом 0.5мм) дорожки с Via на концах, чтобы продолжить на другом слое. У меня задан внешний диаметр виа 1мм и всеравно фанаут отводит не все ноги. Самому это реально сделать, а вот альтиуму фантазии не хватает. Думаю проблема в неправильных настройках. Вопрос - как это делают другие.

  21. У меня сейчас последние месяцы до защиты, работаю параллельно на пол-ставки электронщиком. Тема дисера связана с радиофизикой (всмысле радиоактивных веществ и излучений), а не с электроникой. Сделано мало. Стараюсь об этом не думать и двигаться всеже потихоньку, потомучто иначе это вызывает жуткий стресс... Мотивами поступления была отсрочка, перспектива ускоренного карьерного роста ну и немного научного интереса.

     

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

     

    А еще есть люди, неплохо живущие на науке - за счет всяких разных грантов и т.п. Но это не столько научная, сколько бумажная деятельность. Оно вам надо?

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