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

Лидеры

  1. one_eight_seven

    one_eight_seven

    Участник*


    • Баллы

      2

    • Постов

      1 610


  2. komah

    komah

    Участник


    • Баллы

      2

    • Постов

      45


  3. patron

    patron

    Участник


    • Баллы

      1

    • Постов

      305


  4. AHTOXA

    AHTOXA

    Свой


    • Баллы

      1

    • Постов

      4 033


Популярный контент

Показан контент с высокой репутацией 12.03.2024 во всех областях

  1. Здесь вместо согласованного фильтра интегратор со сбросом (счетчик). Можно обойтись одним сумматором и вычитать отсчет, задержанный на длительность символа, если знак совпадает. Тогда переполнения не будет. Решение принимается по переходу через 0, для 4FSK работать не будет. И даже сам переход по моему не очень правильно ищется. Лучше не по одному отсчету смотреть, а по выходу интегратора. Ну и подстройки тактовой здесь нет.
    1 балл
  2. 1. Согласованный фильтр. Импульсная характеристика должна соответствовать ИХ фильтра на передаче. Есть вероятность, что он уже присутствует до вычисления фазы. Можно проверить - на передачу выбрать режим FSK, а на приеме сначала FSK, потом GFSK. Если результаты разные, фильтр уже есть. 2. Ресемплер (интерполятор) - на каждый символ должно приходиться целое число отсчетов, например 2. 3. Выбрать метод оценивания ошибки синхронизации. Выбор зависит от числа отсчетов на символ и формы символа (ИХ фильтра). Если предполагается передача настроечной последовательности в каждом пакете, то выбор богаче, но я с такими вариантами дела не имел. Из NDA самые популярные алгоритмы - Early-Late и Гарднер. Если использовать решения о принятых символах (обратную связь) - Zero-Crossing. 4. В синхронизаторе присутствует интерполятор (например, на основе pfb), который должен выдавать значение в зависимости от полученной оценки ошибки синхронизации (в пределах интервала времени между отсчетами). 5. Если ИХ фильтра и число отсчетов на символ на входе синхронизатора всегда одни и те же (для любой скорости), п. 1, 2 и 4 можно объединить. 6. Оценка ошибки фильтруется простейшим БИХ - фильтром. Коэффициенты определяют скорость подстройки синхронизатора. 7. Если накопленная ошибка превышает интервал времени между отсчетами, следующий отсчет пропускается. 8. В схеме с pfb можно реализовать оценку ошибки синхронизации на основе максимального правдоподобия. Для этого делается два банка фильтров - с ИХ==ИХ согласованного фильтра (mf) и с ИХ== производной ИХ согласованного фильтра (dmf). Оценка ошибки рассчитывается как произведение выходов mf и dmf. 9. В итоге, при исходных 8,3 отсчета на символ, синхронизатор будет выдавать 10 выходных отсчетов на 83 входных. То есть, на каждый входной отсчет, будет получаться от 0 до N выходных. N зависит от реализации. Выше некоторых звезд ) Наверное, стоит говорить о потенциале реализации демодулятора, который обеспечит вероятность ошибки на бит не хуже, чем встроенный. В большинстве случаев мягкое решение - это просто квантованное значение амплитуды на выходе демодулятора. Дальше можно уже всякие правдоподобия считать и их отношения. Просто для выхода демодулятора в виде PAM с несколькими уровнями, нужно для каждого бита значения как-то нормировать.
    1 балл
  3. плюсую. int temp = FROST; нет ни какой разницы FROST - это дефайн или енум. нет ни какой разницы, с точки зрения конечного пользователя этой функции - она макрос, инлайн или обычная функция. Автор my_macro_func() принимает решение, как максимально эффективно её определить и решает сделать её макросом или функцией. Пользователя это не должно волновать. (более того, она вообще может быть и на асме определена, а может быть и из библиотеки взята, исходного кода которой у вас нет.) Тем более автор этой функции, может в любой момент переоформить её из макроса, в обычную функцию. Тогда Вам придется my_macro_func() переименовывать в my_func() - а это смена API. У пользователей посыпется сборка. мне казалось, что общепринятые правила, это имена функций и методов - с маленькойБуквы. см printf(), strlen(), open(), .... мне мешают нотации/префиксы/постфиксный. Я делаю все имена переменных/функцый - с маленькой, все имена типов/классов с большой. Наверно из Qt и FreeRTOS подчерпнул. Разделение слов - кэмл, без '_'.
    1 балл
  4. А они редакторе подсвечиваются по-разному. (Я использую Eclipse для embedded-проектов, QtCreator для ПК-проектов). Префиксы мне не нравятся. Нет гарантий, что префикс соответствует реальному типу. Сменил тип - забыл про префикс. Гораздо надёжнее не полагаться на префиксы, а использовать возможности современных IDE. Навёл мышку на название типа - получил всплывающую подсказку с кусочком объявления. Если там doxigen- комментарий перед типом, то и он отобразится. Единственное место, где я оставил префиксы - это переменные-члены класса. Они у меня называются m_var; Если интересно, вот рекомендации по кодированию одного из моих старых проектов. Вот, кстати, идеальное место для применения RAII. Создаётся тип CriticalSection, в конструкторе вызываются cpu_alloc_critical_section_context(csc) и cpu_entry_critical_section(csc), а в деструкторе - cpu_leave_critical_section(csc). Тогда функция будет выглядеть так: inline void init() { CriticalSection cs(csc); SPI3->CR1 = SPI_CR1_PRESET_VAL; SPI3->CR2 = SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN; SPI3->SR = 0x0; SPI3->CRCPR = 0x0; SPI3->I2SCFGR = 0x0; SPI3->I2SPR = 0x0; __DSB(); } Это немного короче, но главное - нет шанса забыть освободить критическую секцию. Даже если где-то посреди функции сделать return;
    1 балл
  5. Хаха, поздравляю 🙂 Я это разочарование и негодование уже прошел, теперь и вам предстоит пройти через него. И есть еще одно разочарование-негодование - без включения оптимизации -O3 компилятор не способен выдать короткий код, а все эти портянки наследований классов и тп так и будет пихать как есть целыми простынями в выходной код. По поводу префиксов-постфиксов. Ну это конечно же кто как привык, или какие общие правила оформления установлены в команде разработчиков, когда работаешь на фрилансе в группе. Лично я стараюсь не удлинять имена различными префиксами. Хотя во FreeRTOS это принято. Наверно, именно оттудава у меня появилось отторжение префиксов. Вместо этого в редакторе я использую подсветку синтаксиса. Ну и некоторые общепринятые правила именования - например, имена функций и методов - с ЗаглавнойБуквы, а дефайны и перечисления в энумераторе - целиком ЗАГЛАВЫМИ_БУКВАМИ. В С++ так же и имена классов стал писать с ЗаглавнойБуквы. В редакторе есть уже шаблоны оформления, использую его с небольшими изменениями и применяю автоформат текста. В остальном же - осмысленные имена. Ну и хороший редактор текста с преддиктивным вводом и всплывающими подсказками. Натыкал несколько начальных букв, Ctrl+пробел - и всё слово появилось или предлагаются варианты, если их несколько. PS. Между struct и class в С++ нет никакой разницы, кроме области видимости членов по умолчанию. Поэтому, различия будут разве что филологические, зависящие от того, с какой стороны и с каким подходом смотреть. PS2. Очень просто - по имени энумератора, оно обязательно следует перед именем перечислителя - EnumName::MEMBER_NAME А это никак. В короткое имя не впихнешь всё описание структуры, все её нюансы. Тем более, когда дойдете до наследований, начнется ваще трэш - вы при любом раскладе не будете визуально знать, базовый ли это класс или наследуемый от пары десятков классов. Да оно и не нужно, в принципе то. Тут главное - само имя, как именно оно названо на человеческом языке. Поэтому, перед тем, как чето именовать, не мешало бы вообще на бумажке составить блок-схему и определиться, что как будет называться и что каждый элемент будет делать. Если требуются пояснения к написанному коду, использую комменты в стиле doxygen перед началом блока: /** * @brief Эта штука называется так-то. * @details Нужна для того-то, делает так-то и сяк-то, а еще бибикаетю * @param vara - (для функций с параметрами - описание параметра vara) * @note - Пишем какие-то заметки, типа "Решение, в принципе, хорошее, можно оставить" * @bug - Блин, замечены такие-то баги * @todo - И вот эти баги надо исправить! */ Class A (или Foo(int vara) и т.п.) И потом можно даже сгенерировать документацию по всему написанному, куда будут включены описания и даже (по желанию) исходные коды. Кому-то покажется, что много лишнего текста. Но зато как раз создается описание для дальнейшего использования и решается вышепоставленный вопрос с тем, как впихнуть в имя всё описание. Лично я, как говорил, использую подсветку синтаксиса в редакторе. Там всё настраивается, можно задать разный цвет и разный стиль (курсив, полужирный, подчеркивание) для всех этих элементов. Попробуйте, поэкспериментируйте. Тут главное, запомнить, что на что назначили, ну и найти минимально необходимый объем выделения, чтобы текст не казался "новогодней елкой". Когда-то раньше я тоже ставил префиксы для глобальных переменных. Потом, с освоением инструментов самого редактора, отказался от этих буковок.
    1 балл
  6. А зачем их отличать? Что то - константа, что другое. Вам - нет. Человеку, который будет этот код открывать - да. А не надо сразу понимать насколько она тривиальная и из чего она состоит. Важно - что она делает, и как ей пользоваться. Если инженер занимается поддержкой кода, то ему важно - как легко её найти, и да - ему будет важно знать, что внутри. Так он пойдёт в реализацию. Если ему надо использовать - то он посмотрит в API. А тут для человека в теме - rx_lane_injector - что-то инжектирует в RX Lane. Смотрит какой тип - понятно, что инжектирует пакеты. Английским по белому же написано. Уже понятно для чего это нужно. Ну и раз оно что-то делает, то это явно класс - есть же поведение. Но если надо узнать API, или поддерживать - то в определение - а там видно, что это класс, и видно, что это UVM компонент. Те, кто занимается верификацией из этого уже много чего вынесут - это основная библиотека. Это как вам std::string - уже всё понятно, и что нужно, и какие методы есть, и как этим пользоваться.
    1 балл
  7. класс и структура - это одно и то же. enum - ALL_CAPS. по хорошему, нет никакой разницы, что перед глазами - класс, юнион, енум, если им даны правильные названия, из которых понятно за что они отвечают и что они делают. А если нужны подробности - то всё-равно пойдёшь в объявление, а там, например: ethernet_channel_packet_injector rx_lane_injector; вроде уже понятнее. Если нужно ещё конкретику, тогда идёшь в определение, а там и вовсе нет сомнений class ethernet_packet_injector: public uvm::uvm_component { ... }
    1 балл
  8. Не - не совсем так, или точнее - совсем не так 🙂 Это очень специфическая тема. Искажений - несметное количество, а тех, что нужные - очень мало. И вообще - гитарные у-ли из техники давно превратились в искусство - своего рода Страдивари и Гварнери : там манипулировали деревом и лаками, а тут - подбором деталей. Нынешние технологии обработки гитарного сигнала дошли до предельно возможных теоретически - на основе анализа дельта импульса, теория свёртки и т.д. , вот только все эти алгоритмы моделируют звучание известных ламповых аппаратов. Современные исказители, фейзеры, фленджеры, дигитальные ревербераторы и дилеи прекрасно себя зарекомендовали в области обработки гитарного сигнала, но до сих пор непреложным осталось правило : выходной усилитель - только лампа. Уйти от этого пока не удаётся никому. А в джазе до сих пор предпочитают чисто ламповые аппараты. Пружинный ревер по нынешним временам - чистый анахронизм, современные дигитальные несравненно лучше. Пружинные - это для гурманов, кому хочется поиграть звуком 50-х - 60-х - типа как Shadows 🙂
    1 балл
  9. Тут ещё важно, где вы живёте и нужна ли вам поверка, калибровка, ремонт и сервис. Если в России - то АКИП. Если не в РФ, то предложение по ссылке вполне то, что надо.
    1 балл
×
×
  • Создать...