Разработка ПО для DSP TMS320F28 motor control

    В своей первой статье я обмолвился о данном семействе контроллеров, мне в лс написал не один десяток людей с вопросами о нем, хотя это и не являлось темой статьи. В гугл народ категорически не хотел идти, говоря об отсутствии информации. Я немного удивился и решил проверить — действительно на русском языке по семейству C2000 нет практически ничего (на фоне AVR, STM), а главное нет понятных стартовых гайдов. Информацию можно найти на английском языке, но опять же ее мало. Для меня это несколько удивительно, учитывая, что данному семейству лет уже не мало. Поэтому решено было в меру своих возможностей повлиять на ситуацию.

    Кому эти контроллеры в принципе нужны… Вы хотите собрать себе сварочный инвертор? Источник бесперебойного питания? Выпрямитель для гальванической ванны? Частотник? Инвертор для альтернативной энергетики? Станок с ЧПУ? Если хотя бы один пункт про вас, то статья посвящается именно вам!

    Остальным читателям тоже будет интересно узнать о «новом-старом» контроллере, зачем он нужен и как с ним работать. Данное семейство очень простое (сильно проще STM, LPC и прочих Cortex-ов), камни легко купить (на Али тоже есть), позволяют реализовать сверхнадежные промышленные решения, на их основе можно построить практически любую промышленную систему управления.

    Вы уже решили, что данный контроллер ваша мечта и готовы ринуться в бой? Тогда покупаем за 17$ вот такую отладку F28027-LaunchPad:


    Купили? Вот теперь можно и в бой. Если возник вопрос где купить «получше» и «подешевле», то идем в официальный магазин. Переходим сюда и видим ценник 17$. За эту сумму вы получите оригинальную отладочную плату и доставку курьером до двери. Я заказывал один раз в Китае на сдачу, вышло 16$ и это со скидкой и купоном, так еще и как «бонус» поход на почту. Поэтому рекомендую именно официалов. Поехали!

    Обзор серии C2000


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

    Для начала пару слов о C2000 вообще. Отличительными чертами семейства, которые связаны с его основным назначением motor control, является наличие HRPWM (высокоточный ШИМ) и CLA (сопроцессор). Последний правда отсутствует в самых младших Piccolo TMS320F2802x, но оно там и не нужно, главное HRPWM на месте. Что это такое… Собственно HRPWM это обычный ШИМ, только очень точный и время записи и установки нового значения коэффициента заполнения происходит ощутимо быстрее. Это позволяет получить, например, отличный по форме синус в DC/AC инверторе или с очень высокой точностью управлять шаговыми двигателями в станке с ЧПУ.

    CLA — это по сути полноценное ядро, вот только доступа к периферии у него нет, только к основному ядру и памяти. Служит оно для разгрузки основного ядра от вычислений. Очень легко и непринужденно данный сопроцессор переваривает данные float, что важно при реализации различных алгоритмов, фильтров и прочего.



    Я буду рассказывать о двух основных семействах с которыми вам вероятно придется столкнуться:

    • Piccolo. Самые младшие контроллеры, но и самые дешевые. Мой TMS320F28027 как раз из этого семейства. Если вы надумаете разрабатывать силовую электронику в коммерческих целях, то это будут ваши основные камни — они достаточно дешевые, паябельные (LQFP, QFN, TSSOP) и позволяют реализовать почти все. Например, их производительности хватит для двухфазного PFC, инвертора для солнечных панелей, частотника до 10 кВт с векторным управлением и т.д. Как видите это сегмент продукции который покупают и обычные люди, и предприятия, а значит очень востребовано. Основные ограничения — частота 60 МГц, ограниченное число ШИМ-каналов.
    • Delfino. Идеологически это все те же Piccolo, только накаченные мельдонием. В чем это выражается — частота до 200 МГц, в старших камнях уже 2 полноценных ядра + 2 сопроцессора, большие корпуса и соответственно много ног, много каналов ШИМ, много АЦП и всего в общем-то много. То есть в старших камнях мы имеем 4 ядра с частотой 200 МГц, производительность в 800 MIPS, что согласитесь весьма внушительно. Такую мощу использовать можно по разному, но основное применение — алгоритмически сложные системы, например, выпрямитель «Виенна» или еще чего. Так же на одном таком контроллере можно реализовать всю систему управления для станка с ЧПУ, например, фрезерного или газопламенной резки металла.

    Доработка отладочной платы


    Когда вы получите коробку с отладочной платой, то обнаружите отсутствующий кварц и конденсаторы к нему. Их не обязательно, но желательно допаять. Кварцев в корпусе HC-49 у меня уже не водится, поэтому пришлось одолжить у знакомого. Он ковыряет AVR и STM, поэтому только 8 МГц у него нашлись. Запаял. Конденсаторы 22 пФ добавил по старой памяти, вроде так на мегах в школе делал.

    Данное решение не самое лучшее и связано это с настройкой PLL. Максимальный множитель для PLL составляет х12 (можно и больше, но не рекомендовано и криво работает). Максимальная частота 60 МГц. Максимальное значение делителя на выходе PLL составляет 3. Частота кварца 8 МГц. Я не могу умножить на 8 на целое число и получить 60. Ищем ближайшее общее значение, в данном случае это 240. То есть умножит 8 на 30, а потом разделив на 4 я получу заветные 60 МГц, но тут беда — х30 множитель PLL недопустим, делитель /4 тоже недоступен. Тут есть 2 выхода:

    • Плохой: частоту 8 МГц умножить на 7 и поделить на 1 и получим 56 МГц. Можно умножить и на 8 и получить 64 МГц, работать будет стабильно, но в обоих случаях частота не максимальная 60 МГц. Не хватает перфекционизма, увы. У меня именно такой вариант, запаял 8 МГц и сделал частоту 56 МГц.
    • Хороший: пойти и купить кварц на 10 или 20 МГц (лучше 10) и умножить на 6, ну и поделить на 1, получаем заветные 60 МГц. Живу я за городом и честно говоря лень было ехать в местный магазин, в котором не факт что есть кварцы на 10 МГц. Для обучения пойдет конечно и внутренняя RC-цепь, и кварц на 8 МГц, но в свои проекты будущие все таки ставьте кварцы на 10 МГц, только не мамонтов-мутантов в корпусе HC-49.

    Архитектура и особенности периферии


    Все, что будет происходить далее относится к контроллеру TMS320F28027. Для начала давайте просто посмотрим на структуру, которая взята из даташита:



    Первое на что стоит обратить внимание — ОЗУ разделена на 3 сектора: M0, M1 и SARAM. Объемы этих секторов памяти в нашем случае 1к, 1к и 4к. Стоит заметить, что в данном случае слово не 8 битное, а 16 битное, то есть в более привычной форме это 2 кБайт + 2 кБайт + 8 кБайт. Особенность данного модуля в том, что сектора M0 и M1 более шустрые, чем оставшиеся 8 кБайт ОЗУ. Формально можно воспринимать это как кэш. В секторах M0 и М1 обычно хранят наиболее часто используемые данные, а так же данные, которые наиболее критичны к производительности памяти. По умолчанию мы можем указать с помощью линкера что и где хранится, но эту тему в данной статье я поднимать не буду, тут отдельная статья нужна как минимум.

    Второй важной особенностью является то, что вся периферия тактируется от системной шины, то есть от 60 МГц (в моем случае 56 МГц). В качестве примера приведу микроконтроллеры STM32, там частота ядра составляет, например, 180 МГц для F4, но вот периферия тактируется через ряд делителей. Данный подход я для себя именую «фальшивые мегагерцы», хотя это весьма утрировано. Поэтому 60 МГц у TMS320F28 и 180 МГц у stm32 не так уж сильно отличаются, а если вспомнить о наличии CLA, то 60 + 60 МГц уже как минимум сопоставимы. Понятно, что такое сравнение не правильное, но явно дает понять, что не одними мегагерцами сыты.

    Так же интересный момент — обратите внимание на общую структуру: HRPWM, АЦП, компараторы с внутренним ЦАП, модуль обработки энкодера (eCAP)… Готовый преобразователь частоты с векторным управлением в чистом виде! В этом вся суть данного семейства — минимализм. С одной стороны периферия достаточно бедная на фоне Cortex-ов, но с другой стороны достаточная, чтобы реализовать и частотник, и dc/dc, и dc/ac, да и драйвер шагового двигателя. За счет этого работа с контроллерами TMS320F28 очень простая, понятная и не перегружена лишними действиями. Но если вам вдруг нужно 3 UART-а, а к ним пару i2c и еще 3 SPI, то эти контроллеры точно не для вас — у них задачи другие.

    Окружение и среда разработки



    Посмотрели на логотип-заставку? Запоминаем ее. Если вы решили начать применять в разработке героев статьи, то данная софтина ваше все, а называется софтина как видите — controlSUITE.

    Данное приложение является собранием и библиотекой всего, что понадобится для разработки ПО для контроллеров семейства C2000. Установка данного приложения — это первое, что нужно сделать и посмотреть его состав, в нем находятся:

    • Описание всех существующих контроллеров и отладочных плат на их основе. Исходники схем, печатных плат, BOM-ы в основном в Altium Designer
    • Примеры схемотехники и проектирования печатных плат
    • Основные библиотеки для разработки встроенного ПО
    • Библиотеки математики и DSP, в том числе для использования с CLA
    • Примере проектов ПО для каждого вида периферии
    • Большое количество апноутов по реализации большинства алгоритмов управления двигателями, dc/dc преобразователями, MPPT-контроллерами и прочими системами
    • Набор программ, которые позволяют создать систему управления двигателем без программирования вообще, просто используя графическую среду
    • Сама IDE в которой и будет вестись разработка

    Все, что я описал выше — очень кратко и скромно. На то, чтобы все просмотреть и пролистать хотя бы по диагонали, вам потребуется пару недель. Конечно большинство из этого объема данных на старте вам не понадобится, но нужно помнить куда идти, если что-то для вас непонятно и в диковинку.

    Теперь то, с чем мы сегодня поработаем — IDE, графическая часть, которой основана на базе всем известного Eclipse. Компилятор не GCC, а свой от Texas, который по моему субъективному мнению определенно лучше первого. Хотя есть подозрения, что это основательно допиленный все тот же gcc. Называется среда разработки — Code Composer Studio, актуальная на данный момент версия 7.4.

    Создание проекта


    Вначале я хотел реализовать задачу идентичную первой статье, то есть нарисовать синус. В принципе в рамках одной статьи это можно было бы сделать, оставив за кадром очень большой объем мелочей, но как известно суть как раз в мелочах. В интернете есть несколько статей по TMS, но все они весьма поверхностны и сводятся к виду «вот это копируем и опа все работает», то есть сам процесс и идеология не рассматриваются вообще. Поэтому в рамках данной статьи мы создадим проект, почистим его от лишних компонентов, настроим прошивку во flash память контроллера и научимся работать с GPIO, а они тут весьма интересные.

    Скачиваем CCS7 с сайта производителя, устанавливаем и приступаем к созданию проекта привычным способом: File → New → CCS Project...


    Видим данное окно и в нем нам необходимо выбрать интересующий нас контроллер, в моем случае это TMS320F28027, указать имя проекта и прописать путь, где он будет храниться. Предварительно нужно создать папку, где будет храниться проект. Имя проекта и имя папки могут не совпадать. Жмем кнопку Finish и наш проект создан.

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


    • inc — папка, которая содержит все заголовочные файлы
    • system_inc — в данном подразделе будут хранится заголовочные файлы стандартных библиотек, файлы же, которые мы сами будет создавать, например, main.c находятся в папке inc. Это позволит не поломать что-то бездумно или удалить лишнего
    • src — папка со всеми исходниками
    • system_src — папка с исходными файлами для стандартных библиотек

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

    Теперь создаем в папке inc файл main.h и подключаем его в main.c. Через него будет происходить подключения базовых библиотек. И перед тем как начать переносить библиотеки и прочие файлы, давайте в настройках проекта пропишем пути к папкам, где будут храниться наши будущие заголовочные файлы. Для этого в дереве проекта правой кнопкой жмем на проект (Test) и в само низу нажимаем Properties или просто нажимаем Alt+Enter. В открывшем окне идем Build → C2000 Compiler → Include Options и тут нам необходимо к двум уже имеющимся путям — прописать путь к папкам inc и system_inc. Нажимаем Add, далее Workspace и далее до нужной папке inc, затем проделываем тоже самое и цепляем вторую папку. Таким образом мы прописали относительные пути, при переносе проекта ничего перенастраивать не придется. В итоге у нас получается вот такая картина и жмем Ok:



    Теперь мы имеем пустой проект с прописанными путями и прочими настройками, остается его только заполнить библиотеками. Единственное, что нужно сделать — это проверить все ли подключено. По идее у вас должен получиться такой код и картина, компилируем проект. Для этого нажимаем CTRL+B или наверху идем в Project → Build All. Проект должен скомпилироваться без ошибок и выглядеть так (картинка кликабельна):



    Теперь давайте немного о линковщике поговорим. Изначально при создании проекта IDE генерирует файл 28027_RAM_lnk.cmd, он размещает нашу программу в ОЗУ в процессе отладки и прошивки. Это удобно, когда мы занимаемся отладкой, т.к. не тратятся ресурсы flash памяти да и вход в отладку в ОЗУ ощутимо быстрее происходит. Но что делать, если мы хотим шить во флеш? Для этого есть другой файл линковки, который разместит нашу программу именно во флеш. Этот вариант я и покажу.

    Первым делом удаляем файл 28027_RAM_lnk.cmd. Как я уже говорил — controlSUITE наше все. Открываем его. Теперь идем English → Device → Piccolo F2802x → Supporting Libraries → Header Files for F28027x. Справа мы видим папки — это и есть стандартные библиотеки и все, что нужно, включая линковщики. Теперь идем в папку f2802x_common → cmd и тут мы видим набор линковщиков для всех камней линейки. Как не сложно догадаться файлы _RAM для заливки кода в ОЗУ, а без данного тега для заливки по флеш. Берем файл F28027.cmd и копируем в наш проект вместо старого удаленного линковщика.

    Теперь пришло время перенести сами библиотеки. Идем в папку f2802x_common → source и видим кучу файлов. Тут два вида библиотек: стандартные регистры (аналог CMSIS) и некое подобие SPL. В данном случае нас интересует только первый вид, то есть файлы с префиксом f2802x_. Конечно можно все их перетащить в наш проект, но зачем засорять его если мы не все использовать будем? Если что-то понадобится, то в дальнейшем просто добавим. Пока ограничимся следующим наборов файлов:

    • f2802x_codestartbranch.asm
    • f2802x_defaultisr.c
    • f2802x_piectrl.c
    • f2802x_pievect.c
    • f2802x_sysctrl.c

    Копируем данные файл и вставляем в нашу папку system_src. Теперь идем в папку f2802x_headers → source и забираем оттуда файл F2802x_GlobalVariableDefs.c и опять же копируем в нашу папку system_src. Далее идем в папку f2802x_headers → cmd и копируем оттуда файл F2802x_Headers_nonBIOS.cmd в ту же самую папку. На этом наполнение папки system_src закончено и переходим к заголовкам.

    Идем в папку f2802x_headers → include и копируем оттуда все файлы в нашу папку system_inc. Теперь идем в папку f2802x_common → source и копируем оттуда файлы:

    • f2802x_examples.h
    • f2802x_globalprototypes.h
    • f2802x_i2c_defines.h
    • f2802x_epwm_defines
    • f2802x_swprioritizedisrlevels.h
    • f2802x_defaultisr.h

    У нас должна получиться такая картина в дереве проекта:


    Теперь необходимо подключить базовые библиотеки, файл main.h обретает следующий вид:

    #pragma once
    
    #include "F2802x_Device.h"
    #include "F2802x_examples.h"
    

    Пробуем компилировать. Если проект скомпилировался без ошибок и варнингов — значит все правильно подключено. Если этого не произошло, то все 10 раз перепроверьте, а уж если совсем не получается, то пишите в лс — помогу, как говорила Сова: «Бэз-воз-мЭз-дно, то есть даром».

    Стартовая инициализация контроллера и системы тактирования


    В данном разделе мы напишем функцию, которая проинициализирует сторожевой таймер и вектора прерываний, обнулит флаги прерываний. Так же настроим систему тактирования в результате чего источником тактирования станет внешний кварц, а не внутренняя RC-цепочка, настроим PLL и включим тактирование для все периферии.

    Для аккуратности кода предлагаю вынести все базовые инициализации в отдельный файл, фронтендом которого станет функция void InitStartSystem (void). Для этого создаем файлы systemInitStart.h и systemInitStart.c. Я сразу напишу функцию и дальше просто разберем ее содержимое:

    void InitStartSystem (void) {
    
        DisableDog();
    
        XtalOscSel();                                   
        InitPll(TMS320_PLLCR, TMS320_DIVSEL);           
        InitPeripheralClocks();                        
    
        InitPieCtrl();
        InitPieVectTable();
    
    }
    

    Все функции, которые вызываются в InitStartSystem(), являются стандартными. Советую вам посмотреть подробно как они реализованы, для этого можно зажать CTRL и кликнуть по интересующей функции. Посмотрели? Теперь кратко пробежимся…

    • DisableDog() — функция выключает «собаку». Это обязательное действие при настройке основной части критичной периферии, например, системы тактирования. В коде библиотек вы часто увидите это, оно будет дублироваться и дублироваться
    • XtalOscSel() — данная функция реализует переключение с внутреннего источника тактирования на внешний кварц. Важный момент! В стандартной библиотеке с данной функцией есть ошибка — она не объявлена. Идем в файл f2802x_globalprototypes.h и среди всех прочих объявление дописываем строку extern void XtalOscSel (void)



      Второй важный момент! Идем в функцию XtalOscSel и удаляем функцию задержки.



      Третий важный момент! Идем в файл f28027x_exmaples.h и закомментируем функцию реализации задержки.


    • InitPll(TMS320_PLLMUL, TMS320_DIVSEL) — функция производит настройку PLL. В нее передаются 2 значения: множитель и делитель. Их значение прописаны дефайнами в заголовочном файле. Важный момент! Открываем данную функцию в библиотеке и нужно закомментировать задержку в самом низу

    • InitPll(TMS320_PLLMUL, TMS320_DIVSEL) — функция производит настройку PLL. В нее передаются 2 значения: множитель и делитель. Их значение прописаны дефайнами в заголовочном файле. Важный момент! Открываем данную функцию в библиотеке и нужно закомментировать задержку в самом низу
    • InitPeripheralClocks() — данная функция просто включает тактирование для всей периферии. Да, именно для всей. C2000 — это не решение для железок с питанием от батарейки,
      это решение на единицы-десятки-сотни киловатт и жалкие 2-3 мА роли тут не сыграют. Ну а вам не надо каждый раз вспоминать включили вы тактирование на какой нибудь SPI или нет
    • InitPieCtrl() — функция выключает все прерывания и сбрасывает флаги прерываний
    • InitPieVectTable() — функция заполняет таблицу с векторами прерываний

    Собственно вот она вся инициализация. Думаю многие заметили «важные моменты», связанные с функцией Delay. Почему мы ее выпилили на корню? Да все просто — это костыль.

    Инженеры TI добавили в часть функций эти совершенно ненужные задержки, добавили в недавних обновлениях. Зачем — загадка не только для меня. Регистры и прочие критичные записи и так защищены, поэтому не будет заставлять наш контроллер тупить. Кстати при инициализации в силовой электронике «тупить» вообще нельзя, а то будут бабахи. Поэтому забудьте навсегда функции delay и прочую бесовщину, только таймеры! Задержки допустимы только в каких-то учебных целей, например, быстро светодиодом помигать.

    Для того, чтобы убедиться в работоспособности кода, мы вызываем функцию инициализации в main, компилируем, прошиваем и цепляемся осциллографом на GPIO18. Это вывод аналогичен MCO у STM32, то есть он выводит системную частоту. Осциллографом должны увидеть сигнал с частотой 56 МГц. Если осциллограф хороший, то вы увидите меандр, если китаец (даже хороший), то скорее всего это будет что-то ближе к синусу. Настройка GPIO18 на вывод системной частоты можно увидеть в функции InitPeripheralClocks(). Сначала нужно «подключить» gpio к выходу частоты, а затем установить делитель, равный 1:

       GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 3; // GPIO18 = XCLKOUT
       SysCtrlRegs.XCLK.bit.XCLKOUTDIV=2; // Set XCLKOUT = SYSCLKOUT/1
    

    Настройка GPIO


    Для работы с данным семейством нам потребуется только референс мануал, который разработчики из TI разбили на несколько файлов, каждый из которых описывает определенную периферию, что очень удобно. Скачиваем даташит тут и идем в раздел Documentation Support на страницу 126. Тут мы видим набор ссылок на документацию с ее кратким описанием: errata, пособие для старта управления двигателем и гайды по каждой периферии. Нас интересует документ с названием TMS320F2802x/TMS320F2802xx Piccolo System Control and Interrupts Reference Guide, именно в нем находится описание интересующих нас GPIO и прочих базовым системных настроек. Смотрим на структурную схему GPIO:



    Мы видим достаточно привычную картину устройства портов ввода-вывода. Тут и возможность включения внутренней подтяжки, и использование сигнала с GPIO для прерываний и прочие прелесть. Главная фича данной периферии у C2000 — это возможность аппаратного подавления помех, например, дребезга механических контактов кнопки. Давайте посмотрим на интересную диаграмму:



    На ней показан принцип считывания состояния входов. В большинстве контроллеров состояние входа считывается с частотой тактирования данной периферии, то есть по умолчанию с частотой 56 МГц в нашем случае, а у тех же stm в старших семействах эти частоты еще выше. Думаю всем понятно, что при такой частоте контроллер успевать «увидеть» любые помехи и шумы. Иногда такая частота нужна, а иногда нет, например, если нам нужно опрашивать кнопку. Зачем нам ее опрашивать каждые 18 нс? Поэтому реализовали возможность уменьшения частоты тактирования конкретного порта с помощью регистра CTRL и битов QUALPRDx, где X принимает значение от 0 до 3: QUALPRD0 отвечает за GPIO0...7, QUALPRD1 отвечает за GPIO8...15 итак далее. По сути это обычный делитель частоты с коэффициентом от 1 до 510.



    Кнопку опрашивать сильно часто смысла нет, поэтому настраивать делитель будем на значение 510, то есть на максимум. Смотрим опять на диаграмму и видим, что сигнал считается установившемся, только когда его уровень был неизменным 6 тактов. Количество тактов, которое требуется для фиксации может быть 1, 3 или 6. Чем больше делитель и чем больше тактов мы фиксируем, тем стабильнее работа защиты от дребезга. Когда будет дребезг контактов, то вначале это будут хаотичные переходы из 0 в 1 и обратно, когда дребезг пройдет и сигнал устаканится и не будет изменяться в течение 6 тактов, то это будет означать, что кнопка нажата. Все гениальное просто.

    Теперь давайте рассмотрим основные регистры, прерывания затрагивать не будем — только настройки самих портов. Для начала нужно сказать, что регистры делятся на 2 типа: регистры настройки и регистры данных. Первые отвечают за конфигурацию свойств, например, вход это или выход. Вторая группа отвечает за запись и считывания состояния порта.

    Регистры настройки:

    • GPxCTRL — регистр для записи делителя тактовой частоты. Вместо «x» подставляем букву «А» — если у нас GPIO0...31, «В» — если используем GPIO32...63 и так далее
    • GPAQSELx — регистр для установки количество тактов для фиксации значения на входе
    • GPAMUX1 — регистр для выбора подключенной периферии, например, он указывает что приходит на ногу GPIO или UART, а может и ШИМ.
    • GPADIR — регистр выбора направления работы GPIO: вход или выход. По умолчанию все порты настроены на вход
    • GPAPUD — регистр отвечающий за подключение внутренней подтяжки к VCC.
      Стоит заметить, что у части портов по умолчанию подтяжка выключена, а у части включена.
      Это важно помнить!

    Регистры данных:

    • GPADAT — регистр состояния вывода. Если вывод настроен на вход, то из него мы читаем состояние входа. Если настроен на выход, то мы можем записать значение, которое этот выход должен принять, то есть 0 или 1
    • GPASET — регистр установки выхода в «1». Чтобы выставить в «1», необходимо записать «1», при записи «0» команда игнорируется
    • GPACLEAR — регистр установки выхода в «0». Чтобы выставить в «0», необходимо записать «1», при записи «0» команда игнорируется
    • GPATOGGLE — регистр, который инвертирует текущее значение состояние выхода. Чтобы инвертировать значение, необходимо записать «1», при записи «0» команда игнорируется

    Вот такой простенький набор регистров. Даже из описания выше уже можно понять, что нужно сделать для настройки порта, но предусмотрительный инженеры или технические писатели из TI сделали еще пошаговую инструкцию:



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

    • Шаг 1 — определяемся с функционалом вывода: что это будет вход или выход,
      gpio или выход другой периферии и прочее
    • Шаг 2 — включаем или отключаем внутреннюю подтяжку к питанию
    • Шаг 3 — настраиваем тактирование и защиту от дребезга для конкретного порта
    • Шаг 4 — выбираем нужную функцию: gpio или периферия
    • Шаг 5 — настраиваем направление работы вывода: вход или выход

    Вот и вся настройка, как видите она элементарная и логически понятная. Сразу хочу отметить, что не обязательно именно в таком порядке производить настройку, например, настроить направление (вход или выход) можно самым первым шагом. Это не имеет значения.

    Супер важно!

    При работе с регистрами в семействе C2000 необходимо учесть момент, что они защищены. Все далее описанное касается в основном только регистров группы настройки. Если вы внимательно смотрели стандартные функции, то наверняка увидели там непонятные команды: EALLOW; и EDIS;. Команда EALLOW — снимает защиту и открывает доступ для работы с системными регистрами. Команда EDIS — включает обратно защиту и открывает доступ для работы с системными регистрами. То есть любая работа с системными регистрами должна ВСЕГДА выглядеть следующим образом:

    EALLOW;
    
    // Работаем с системными регистрами, меняем их значения, настраиваем
    
    EDIS;
    

    Такая операция не требуется, если мы работаем с регистрами данных, например, если мы выставляем с помощью регистра GPxSET наш выход в «1», то с него не надо снимать защиту и соответственно и включать ее обратно. В документации везде написано, что нужно защищать, а что нет, например, так:



    Исходя из всего выше описанного, давайте настроим GPIO0...3 со светодиодами на выход. Все настройки GPIO предлагаю поместить в функцию InitLEDgpio и напишем ее:

    void InitLEDgpio (void) {
    
        EALLOW;
    
        GpioCtrlRegs.GPADIR.bit.GPIO0 = 1;
        GpioCtrlRegs.GPADIR.bit.GPIO1 = 1;
        GpioCtrlRegs.GPADIR.bit.GPIO2 = 1;
        GpioCtrlRegs.GPADIR.bit.GPIO3 = 1;
    
        EDIS;
    
    }
    

    По умолчанию наши GPIO уже настроены как GPIO, т.к. все значения регистров очищаются, а значит в регистр GPAMUX1 уже записан «0». Для GPIO0...11 подтяжка по умолчанию отключена, поэтому нам и остается только взять и определить направление работы на выход с помощью GPADIR. Если вы помните, то светодиоды к контроллеру подключены катодами, а значит сразу после инициализации они будут светиться. Давайте прям в функции инициализации данные выводы настроим в «1»:

    void InitLEDgpio (void) {
    
        EALLOW;
    
        GpioCtrlRegs.GPADIR.bit.GPIO0 = 1;
        GpioCtrlRegs.GPADIR.bit.GPIO1 = 1;
        GpioCtrlRegs.GPADIR.bit.GPIO2 = 1;
        GpioCtrlRegs.GPADIR.bit.GPIO3 = 1;
    
        EDIS;
    
        GpioDataRegs.GPASET.bit.GPIO0 = 1;
        GpioDataRegs.GPASET.bit.GPIO1 = 1;
        GpioDataRegs.GPASET.bit.GPIO2 = 1;
        GpioDataRegs.GPASET.bit.GPIO3 = 1;
    
    }
    

    Как видите я не использую регистр GPADAT для записи, а применяю SET, CLEAR, TOGGLE. Так же обратите внимание, что данную запись я выполнил за пределами защищенной зоны, то есть после команды EDIS. Теперь в этой же функции настроим GPIO12 для работы с кнопкой и допишем нашу функцию:

    void InitLEDgpio (void) {
    
        EALLOW;
    
        GpioCtrlRegs.GPADIR.bit.GPIO0 = 1;
        GpioCtrlRegs.GPADIR.bit.GPIO1 = 1;
        GpioCtrlRegs.GPADIR.bit.GPIO2 = 1;
        GpioCtrlRegs.GPADIR.bit.GPIO3 = 1;
    
        GpioCtrlRegs.GPAPUD.bit.GPIO12 = 1;
        GpioCtrlRegs.GPACTRL.bit.QUALPRD1 = 0xFF;
        GpioCtrlRegs.GPAQSEL1.bit.GPIO12 = 2;
    
        EDIS;
    
        GpioDataRegs.GPASET.bit.GPIO0 = 1;
        GpioDataRegs.GPASET.bit.GPIO1 = 1;
        GpioDataRegs.GPASET.bit.GPIO2 = 1;
        GpioDataRegs.GPASET.bit.GPIO3 = 1;
    
    }
    

    Первым делом я отключаю внутреннюю подтяжку записью «1» в регистр GPAPUD, т.к. она для GPIO12 по умолчанию включена. Как я ранее писал — все порты после инициализации настроены на вход, т.к. в регистре GPADIR записаны нули, его мы тут не настраиваем.

    Остается настроить защиту от дребезга, для этого делители записываем 0xFF, что соответствует значению /510. В регистр GPAQSEL1 запишем значение «10» или 2, что установит значение на выборку в 6 тактов. Готово! Для того, чтобы считать значение конкретного входа, нужно просто считать значение из регистра GPADAT:

    if (GpioDataRegs.GPADAT.bit.GPIO12) {
        
    // Если кнопка нажата и подает +3.3В (лог. 1) на вход, то выполняем данные действия
    
    }
    

    Вот таким образом мы и опрашиваем нужные выводы. Теперь давайте вызовем функцию настройки gpio в нашей основной функции и получим ее финальный вид:

    void InitStartSystem (void) {
    
        DisableDog();
    
        XtalOscSel();
        InitPll(TMS320_PLLMUL, TMS320_DIVSEL);
        InitPeripheralClocks();
    
        InitPieCtrl();
        InitPieVectTable();
    
        /*********************************/
    
        InitLEDgpio();
    
    }
    

    Теперь вызываем в функцию InitStartSystem в основном теле программы в main и на этом настройка завершается. Получаем вот такой код:

    #include "main.h"
    
    int main (void) {
    
        InitStartSystem();
    
        while(1)
        {
    
        }
    }
    

    Настало время написать нашу первую тестовую программу и проверить все это дело. Алгоритм такой: моргает светодиодом, который сидит на GPIO3, а при нажатии кнопки на GPIO12 зажигаем просто светодиод GPIO0. Таким образом мы проверим работу портов и на вход и на выход. Пишем следующий код:

    #include "main.h"
    
    int main (void) {
    
        InitStartSystem();
    
        while(1)
        {
    
            if (GpioDataRegs.GPADAT.bit.GPIO12)
            {
                GpioDataRegs.GPACLEAR.bit.GPIO0 = 1;
            }
            else
            {
                GpioDataRegs.GPASET.bit.GPIO0 = 1;
            }
    
            GpioDataRegs.GPATOGGLE.bit.GPIO3 = 1;
            delay(100000);
    
        }
    }
    

    Компилируем, идем в отладчик, запускаем и видим как один светодиод постоянно моргает, а при нажатии кнопки загорается еще один. В конце раздела я прикреплю проект с данным кодом, если что-то не получится, то подсмотрите в него. Специально для тех, кто тяжело воспринимает тексты или не все моменты понял предлагаю посмотреть данное видео по работе с GPIO, там происходит все тоже, что в разделе «GPIO». Предупреждаю, что видео на час, муторно, долго, но максимально подробно и все видно:



    Файлы из статьи


    • Архив с проектом для CCS7 скачиваем тут
    • Посмотреть код можно на github

    Итог


    На данном этапе я заканчиваю сегодняшнюю статью. Думаю вы поняли, что если бы я сходу решил показать реализацию DC/AC инвертора, то объем статьи был бы в несколько раз больше или же много важных мелочей остались бы просто за кадром, что на мой взгляд недопустимо.

    Надеюсь моя статья поможет всем желающим начать освоение данного семейства контроллеров и начать разработку в области силовой электроники и станкостроения. В будущем я наверняка напишу еще что-то на данную тему, например, хотелось бы рассмотреть работу с ШИМ или реализовать какой-то алгоритм. Главное чтобы было время.

    Если у вас остались какие-либо вопросы или у вас что-то не получается, то вы можете написать мне в личные сообщения и я постараюсь ответить на ваши вопросы и оказать посильную помощь в изучение. Успехов вам в обучение!

    UPD. Спасибо за наводку от BelerafonL на книгу «Встраиваемые высокопроизводительные цифровые системы управления»
    Поделиться публикацией
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 77
    • +2
      Для начинающих стоит написать максимально доходчиво, что данные адресуются по 16-бит. Т.е. sizeof(char)=1 при этом в char 16 бит. С первого раза можно сильно затупить по поводу того, что происходит со структурами и указателями.
      Насчёт сравнения с Cortex — есть контроллеры Concerto, в которых вместе два ядра — Cortex M3 и С28.
      • 0
        Замечание верное, спасибо, чуть позже в статье про это более точно напишу.
        О concerto хотел написать сначала, но не стал, т.к. чаще наблюдаю решение, когда стоит delfino и параллельно с ним тот же stm. Один управляет силовой частью, а второй общается с миром, управляет дисплеем и прочие прелести.
        Да и с concerto я работал мало, поэтому мое мнение по ним будет не самое компетентное.
        • 0
          имеет смысл сравнить с МК infineon. У них есть как раз семейство МК которые они позиционируют для управления двигателями и освещением. Есть высокоточный ШИМ и математический сопроцессор.
          • 0
            XMC, например, 4200 — еще большая экзотика в СНГ и про них еще меньше людей знает и держали их в руках. Еще можно сравнивать с Тошибой. В статье старался сравнить с тем, что видели и щупали все люди.
        • +1

          Я пытаюсь всеми силами убрать эти микроконтроллеры из железок что я делаю и заменить на ARM или связку ARM+FPGA

          • 0
            А ARM у вас не микроконтроллер? Или вы используете ARM процессоры или SoC? Возможно вы имели ввиду убрать микроконтроллеры не на АРМ.
            • +4
              В определенных задачах можно и нужно уйти на ПЛИС, но это скорее штучное оборудование. Если нужно производить простые и надежные, например, частотники до 1-2 кВт — проще и дешевле будет сделать это на младших TMS320 или XMC4200/4400. Все очень зависит от задач. Связка ARM+fpga или SoC — это круто, но дорого и ремонтопригодность ниже.
              • +2

                Частотники можно делать на STM32, как например делает их SEW-Eurodrive, но это конечно вопрос вкуса. :)
                Мы пытаемся перейти на ARM потому что это более распространенная архитектура чем TMS, лучше тулчейны и отладка, можно найти чипы дешевле.

                • 0
                  Можно и на AVR или даже ардуине. Вопрос лишь в том, что на выходе. Да и интересно глянуть на 100+ кВт на STM-ке. Пока еще такой дикости не наблюдал лично.

                  Отладка на ARM лучше, чем в CCS? О каких ARM речь? STM-ы дебажить в реал-тайме вообще страшно если они что-то под трехфазкой крутят, а что-то более менее адекватное там — это IAR, который кхм… кхм… из 90-х. Все остальные поделки на эклипсе и GDB обычном вызывают определенные сомнения.
                  • 0

                    IAR немного разукрасили в новой версии, теперь он из 200x:)

                    • 0
                      Кряк то уже есть на рутрекере?
                      • 0

                        Подходит от семёрки вроде

                        • 0
                          tronix286 а что там кстати с Вогоплеером?:)
                          у меня ещё один не разрезанный остался:)
                      • +2

                        Почему вы считаете что это дикость? Какая разница с точки зрения алгоритмов управлять двигателем в 100 кВт или 2 кВт?


                        А лично в реалтайме не отлаживаю под напряжением. В лучшем случае — вывожу на DAC интересующие мне сигналы. Если что-то в пределах 1мс — то можно через внешний интерфейс вытащить, CAN например.
                        Но отладка систем реального времени это не только отладка под реальным напряжением, и trace macrocell в АРМе позволяет делать побольше чем в c2000.
                        По поводу тулчейнов — у АРМ есть неоспоримое преимущество: GCC. Кроме того Кейл также хорош, если хочется чего-то от разработчика ядра.


                        Короче я не хочу спорить что АРМ лучше, это вопрос вкуса. Просто я сказал что в компании где я работаю мы пытаемся соскочить с TI

                        • 0
                          2 и 100 кВт — между ними пропасть, как и пропасть между 100 кВт и 1+МВт. При мощности 2 кВт будет позволена куча допущений, да и сеть наверняка однофазная будет, а это уже разные железки в принципе.

                          Хм… Работаю с приводами и преобразователями напряжения и 90% моей работы — это отладка под напряжением/нагрузкой. Видимо везде своя специфика. Через CAN развязанный кстати тоже дебажить иногда приходится, когда, например, преобразователь от 6 кВ и рядом сидеть страшно))

                          Да, Keil хорош, но опять же редактор кода и 00-х. Все таки если говорим о коммерческой разработке, то удобство — это время, а время — это деньги. Преимущество — GCC? Я и многие знакомые разработчики считают это большим недостатком, ну разве что в плюсы можно записать бесплатность.

                          Холивар «кто круче» — это вечно)) Я думаю тут просто нельзя сказать кто лучше. Есть люди, кто IAR боготворят и прочие интересные личности. Кстати из ARMов есть мотор контролы приличные, те же ранее упомянутые XMC4200, 4400, 4500 щупал и очень понравились, но связка eclipse (DAVE на нем)+GCC у меня вызывает страдания если честно.

                          • +1
                            Преимущество — GCC? Я и многие знакомые разработчики считают это большим недостатком


                            А можно уточнить, в чем заключается «большой недостаток»?
                          • –1
                            А я поддержу, мне тоже TI не нравится. С самого начала, с MSP430 не нравится. Они таки все вот вам камень такой, а вот и другой, под лоу повер, например. Юзайте и будут вам наноамперы. При этом еще попробуй так расположи периферию, чтоб она легла на некоторые ноги к земле, некоторые ключи по верху, и проследи по всем этим цепям ток. Не всегда получается так красиво сделать. STM — просто, тупо, грубо, зримо. Без всяких глубоких подводных камней.
                            • 0
                              Если надо мигать светодиодами и слать байты в юарт, то везде можно забить на процесс конструирования ПП и схемотехнику. Но вот если у тех же STM захотеть получить от АЦП в инжекторных канал заявленную точность, то так же нужно будет с прикладыванием головы разводить цепи внешнего ИОНа на Vref и прочие прелести. Про это в RM-е так же есть. За хорошие ТТХ надо платить хорошими знаниями и временем)
                              • +1
                                Не спорю. Конечно, думать нужно. Но когда думаешь раз, и оно не получается, по твоей вине. Думаешь — какой же я дебил, это же очевидно. Думаешь два, и оно снова не получается по твоей вине. Думаешь, что можно и уже даташит прочитать не поперек, а вдоль. Делаешь три, и оно не получается. Да, есть проблема на стекексчейдж, можно вот так костылем решить, а в даташите просто не указывается, ибо подразумевается. Делаешь четыре, оно конечно не работает. В интернете ноль. Стрелка осциллографа с анализаторами в зубы. Может так, а может не так. А пять — берешь L серию STM и делаешь на счет раз.
                                • 0
                                  Спорить тут не буду. У меня лично MSP430 только хорошие впечатления оставили, ну а то, что у TI все со своими «фичами» это известно)) Для меня загадка зачем они к ШИМ контроллерам прикручивают i2c или spi, а иногда и то и то, при чем реально они нужны в 0,0001% случаев.

                                  Правда у всех производителей есть свои особенности. Например, у меня всегда наступает боль, когда заказчик хочет видеть stm в железке, которая будет работать при -30..-50. И начинается магия, когда те же MSP430 весьма неплохо себя ведут и главное предсказуемо.
                          • 0
                            Странно что АРМ ядро, почему то у многих ассоциируется с продукцией STM, есть например такое вот. Такой же специализированный продукт, на известном ядре)
                            • +1
                              Фанаты ARM просто обычно мне их в пример ставят, да и поделки до 10 кВт я еще видел на stm, на других камнях нет. А вот после 10 кВт доводилось наблюдать только тексас, инфинеон, nec и тошибу.

                              За кинетис спасибо! Не встречался с ними и даже не знал, что фрискейл/nxp такое делают.
                    • 0

                      Нормальные процессоры, если перетерпеть боль их освоения.
                      Байт размером в 16 бит немного напрягает. Типы uint8_t и int8_t в <stdint.h> вообще не определены. Приоритеты прерываний прибиты гвоздями, аппаратной вложенности нет.
                      Пришлось самому на это семейство портировал FreeRTOS, т.к. TI пропихивает свою собственную RTOS SYSBIOS и ничего про FreeRTOS знать не хочет.

                      • –1
                        А какой смысл-то uint8_t и int8_t определять?
                        • 0

                          Их стандарт определяет в stdint.h

                      • +1
                        Delay вы зря убрали. После включения тактирования и настройки PLL требуется время для стабилизации частоты. Без задержки у вас тайминги не будут точными, что особенно важно для этих контроллеров и там где вы их применяете. Если ±1% (1МГц) нормально для вашего проекта, то Delay не нужен.
                        • –1
                          +-13 Гц выход частоты ядра. Если посмотреть предыдущие видео на канале, то там есть про настройку PLL и измерение частоты. В самом худшем случае было +-130 Гц с китайским кварцем. Поэтому проблемы, которую вы описали, просто нет.

                          Кстати этих задержек до определенных обновлений не было в принципе в стандартных функциях.
                          • 0
                            Для зарядки конденсаторов (22pF) в цепи генератора и запуска процесса требуется время. Тут, надеюсь, авторитетно и доходчиво описано. Вы свою прошивку можете делать без Delay, но советовать это всем, по-моему, неуместно и необоснованно. В Cortex-M (HSERDY) и в 8051 есть флаги, которые надо ждать. Ваша рекомендация ошибочна.
                            • +2
                              Этих «авторитетных» источников море. Например, на форуме тех же ti уже не раз данная тема мелькала и никто не страдал. Я склонен верить опять же результатам, которые у меня на осциллографе, а не у кого-то в книжке. Уж простите, если всем верить, то и до религии можно докатиться))

                              И если прочитать внимательно, то в статье я указываю, что все утверждения сугубо мое личное мнение и опыт. Если бы у меня были проблемы с плавающей на +-1 МГц частотой, то об этом бы рассказал. Я не призываю никого принимать так же на веру данную статью, галочку «туториал» тоже не ставил. Хотите верьте, а хотите нет. Поэтому говорить о каком-либо вредительстве думаю тут не стоит.
                              • 0
                                Нашёл модель удвоителя частоты. Тут можно посмотреть. Обратите внимание на начальный нестабильный участок.
                                • 0
                                  Во-первых, не понятно что это за модель, которая к TI вообще никакого отношения не имеет. Во-вторых, даже на этой модели видно, что сия нестабильность десяток тактов и потом все стабильно. Если учесть, что сам процесс инициализация на порядки более длительный, то к моменту окончания инициализации все уже стабильно. Собственно поэтому ни на GPIO18, ни у ШИМа не видно этого с помощью осциллографа, а значит к моменту запуска периферии все уже стабилизируется.
                        • 0

                          Интересно, а можно HRPWM сделать на stm32 с помощью dma?

                          • 0
                            Насколько я понимаю DMA burst у stm32 это что-то аналогичное.
                          • 0
                            Ну наконец-томожно выбросить ардуину и заняться чем-то серьезным.
                            Лет 10 назад ещё горел идеей собрать ЧП и поглядывал на F240 от TI. Они тогда позиционировались как Motor Control. Но как раз отсутствие док на родном и слабые знания в силовой электронике задвинули эту идею на полку. Кстати насколько помню одним из важнейших преимуществ применения специализированных МК в этой области перед те ми же STM32 — наличие аппратного контроля dead time, важного для IGBT транзисторов
                            • 0
                              У stm32 аппаратный деад тайм тоже есть, но очень специфичный. То есть, он привязан только к одной паре ШИМ-каналов и еще ряд «фич». У специализированных motor control все это куда более адекватно реализовано, более гибко в настройке.

                              На STM32 тоже можно управлять силовой частью, но не всегда, не везде и с большими страданиями, чем на специализированном камне. В комментах под первой статьей кто-то писал, что STM32F3 позиционируются как motor control, но я лично не впечатался.
                            • +1

                              А можно по подробнее про HRPWM? Насколько я знаю, он даёт возможность увеличить точность установки скважности — например не 100 или 101 тактов процессора, а 100.285, например. Но что гораздо быстрее происходит загрузка — вот это не очень понятно.

                              • 0
                                Да, разрешение 150 пс у данных контроллеров при условии, что частота тактирования больше 50 МГц для F28027. При меньшей частоте этой точности не будет. Под словом «быстрее» я подразумевал, что время, затрачиваемое на обновление данных (загрузку в счетчик) у обычного канала и точного — несколько отличается. Я не помню цифр для 28027, но у F28032 это цифра 12 тактов против 7.
                                • +1
                                  А где, если не секрет, можно посмотреть эти цифры? Просто в документации на модули ePWM и HRPWM я такого не нашёл, в обзоре линейки Piccolo тоже. Мне всегда казалось, что загрузка числа в регистр происходит мгновенно. Но, правда, там по умолчанию стоит использование «теневых» регистров для уставок сравнения, из которых загрузка в «реальные» регистры происходит по определённым событиям (типа счётчик достиг нуля или периода).
                              • 0
                                Вот тут есть макросы для GPIO, довольно удобные.
                                • +2

                                  О ужас. Запихивать код в препроцессор это какое-то быдлокодерство. Если уж хочется, то лучше сделать функцию-обертку или взять готовую. На tms320 есть библиотеки аля SPL, которые некоторую абстракцию добавляют

                                  • 0
                                    О ужас это каджый раз при правке кода раздупляться что такое
                                    GpioDataRegs.GPATOGGLE.bit.GPIO3 = 1; 

                                    вместо простого и понятного
                                    GPIO_TGL(LED_RED);

                                    Обёртка может быть, но это дополнительное время на выполнение этой самой обертки, это может быть критично. С инлайном тоже могут быть вопросы.
                                    • +2
                                      Я так понимаю вы коммерческий код не пишите? Иначе бы вас или уволили или прокляли. Советую прочитать «Совершенный код» для начала, там очень подробно рассказано почему препроцессор это плохо. Если кратко — они ни тип данных не проверяет, ничего не делает, просто заменяет код.

                                      Конечно вы можете писать как угодно, хоть main засунуть в дефайны. Но не надо мне про это рассказывать, мне потом кошмары сниться будут же
                                      • 0
                                        Есть и другая крайность, arudino, и потом начинаются вопросы, а почему
                                        while(1) {digitalWrite(ledPin, HIGH); digitalWrite(ledPin, LOW);}
                                        мигает на частоте всего несколько кГц, а не МГц.
                                        Макросы конечно впринципе зло, и не нужны, есть const и inline.
                                        Но вот для gpio так называемые макросы Волкова, когда в одном месте можно описать порт, пин, активное состояние, тип выхода, ..., — зло оправданное.
                                        #define PIN_LED PORTA, 4, H
                                        toggle(PIN_LED);
                                        Тип чего тут проверять? вместо PIN_LED туда что попало засунуть не получится.

                                        Да, есть шаблоны, и можно сделать не хуже по потреблению флэша/памяти
                                        www.webalice.it/fede.tft/stm32/stm32_gpio_and_template_metaprogramming.html
                                        но для каких-нибудь, например, 8051 или stm8 есть бесплатный с++ компилятор?
                                        • +1
                                          Можно писать как угодно, это касается любого софта. И именно поэтому одни разработчики зарабатывают 30 000 рублей, а другие 3000 евро. Спорить с кем-то о написание кода бестолково. Ардуинщики вон считают себя труЪ-программистами от Бога и никто и никогда не докажет им обратного))

                                          Могу ошибаться, но вроде IAR позволяет использовать плюсы для stm8.
                                          • +1
                                            я лишь к тому что в крайности (в обе стороны) впадать не надо.
                                            IAR с++ позволяет, но денег за это хочет.
                                            • +1
                                              А при чем тут крайности? Если прочитать книгу Страуструпа, собственно создателя языка С++, то там опять же черным по белому написано, что препроцессор использовать плохо и целую главу рассказывает почему именно так. Это не крайности, это элементарные базовые знания человека, который считает себя разработчиком.

                                              Денег хочет конечно. Все хотят, кто предлагает полноценный, стабильно работающий продукт
                                              • 0
                                                Крайности при том, что кто-то вместо обёртки для того же gpio в виде макросов, предлагает их запретить совсем, и использовать другие обёртки, а ведь на плюсах можно сделать обёртку куда более страшную, за примерами далеко ходить не надо.

                                                Оператор goto вот тоже считается что использовать плохо, сколько раз он в исходниках ядра линукса встречается?
                                        • –2
                                          Советую прочитать «Совершенный код» для начала, там очень подробно рассказано почему препроцессор это плохо. Если кратко — они ни тип данных не проверяет, ничего не делает, просто заменяет код.

                                          Откровенна чушь. Микроволновка это плохо. Если кратко — она не стирает бельё, ничего не делает, просто подогревает еду.
                                          Конечно вы можете засунуть свои грягные носки в микроволновку, но зачем…

                                          • +1
                                            Сэр, выпейте чаю, вам дурно.
                                            К тому же тут вроде только вы пытаетесь засунуть грязные носки (макросы для gpio) в микроволновку (препроцессор).

                                            P.S. повторюсь еще раз — вам никто не мешает быдлокодить, на здоровье. Вот только зачем другим пример то подавать?
                                            • +1
                                              Кроме по-детски безапеляционных заявлений вроде «это быдлокод» и «вот там вот написано что это плохо», адекватные аргументы будут в пользу того что макросы (приведённые мной в частности) для GPIO это плохо?
                                              • 0
                                                В краткой форме я уже писал, в подробном изложение сказал где прочитать. А то, что техническая литература для вас не аргумент — это я понял. Мне тут нечего добавить…
                                                • 0
                                                  В краткой форме я уже писал

                                                  Сорри, но в краткой форме написана редкая глупость, и я как мог старался это показать с метафорой про микроволновку.
                                                  Тем не менее предложенный вами «Совершенный код» почитаю.
                                                  • 0
                                                    Хм… «редкая глупость»… но не читал одну из базовых книг по программированию в принципе… Чувствуется мнение эксперта.

                                                    Почитайте и еще рекомендую «язык программирования с++» от Страутструпа. После этого в какой нибудь другой статье в комментах встретимся и обсудим еще раз. К тому моменту думаю нам проще будет спорить, сейчас просто кража времени друг и друга.
                                    • 0
                                      У нас был аутсорс, по доработке линейки приводов выпускаемых одной известной и солидной фирмой с доступом к исходным кодам под NDA. Макросы там, действительно, используются очень незатейливо. Но от основного кода волосы начинают шевелиться не только на голове — простое чтение позволило выявить весьма не слабые дыры, а в целом, весь код очень подходит под термин «быдлокода». Грамотно написанные макросы наоборот, могут заметно снизить вероятность ошибок.
                                      • 0
                                        Для начала бы все начали писать грамотный код, а уже потом о макросах говорить можно. Кстати не однократно слышал от разных гуру кода, правда высокоуровневых больше, что в 90% случаев можно избежать макросов, а если у вас не получается этого сделать, то вам стоит повысить квалификацию.

                                        Это не камень в чей-то огород тут, просто обобщенно. На деле хорошо написанный код и продуманная архитектура — ошибки практически исключает.
                                        • +2
                                          Макросов можно избежать в 100% случаев — просто написать код руками. Другое дело, что писать, возможно, придется заметно больше.

                                          Макросы, как и вообще любые средства любого языка, полезны при их разумном использовании. Не берусь сейчас формулировать правила. Это по ощущениям.
                                  • +1
                                    У TI, что SDK, что CCS ужасны. Не только к этому TMS, но и остальному. Хоть Keil и выглядит аскетично, но лучше пока не видел (из всего, что предлагается к загрузке). SES близко, но он из CrossWorks идет. А всё, что на основе eclipse, немного мрачновато для работы. Личное мнение. Так же как и JLink впереди планеты всей.
                                    • +1
                                      А чем Keil лучше? У нас на фирме всегда работали с MCU TI, разработка под которые идёт в Code Composer Studio. Потом нам нужно было сделать пару проектов на ARM на российском микроконтроллере. Мы попробовали Keil и IAR, но нам категорически не понравилось, как там выглядит редактор кода — ни подсветки, ни автодополнения. Ну и выглядит, как вы выразились, аскетично… В итоге пришлось самим копаться и делать себе среду на основе Eclipse + GCC + OpenOCD. Поэтому мне непонятно, какие же преимущества у этих сред.
                                      • +1
                                        Видимо на вкус и цвет фломастеры разные. По мне CCS очень неплох. Keil и IAR как верно заметили — обладают ужасными редакторами кода, они платные (да да, компаниям актуально) и вот сказать, что компилятор лучше тоже нельзя. Единственное что мне нравится у keil это отладчик, он просто отличный
                                    • 0
                                      Вот бы кто нибудь расписал работу с STM32 FOC для PMSM, желательно с энкодером.
                                      • 0
                                        А вот ещё вопрос, вы CLA используете? А то мы в курсе, что это и для чего, но задействовать ни разу так и не пришлось. Да и компилятор с СИ появился относительно недавно… Нет ли большего геморроя в его задействовании, чем в использовании чисел IQ (когда FPU нет на борту)?
                                        • 0
                                          Да, CLA использую, но либо в совсем больших проектах, например, высоковольтные инверторы с последовательным включением ключиков где каналов много, либо в проектах, где с одного камня управляются несколько преобразователей, например, UPS (pfc+2 инвертора+ЗУ). В остальных случаях можно легко обойтись без сопроцессора и наверное лучше обходиться))
                                          Каких либо сложностей сейчас нет, вернее я не сталкивался и у ti наконец-то появились для CLA нормальные примеры, что сильно облегчает жизнь при первом знакомстве. Где-то год или два назад были проблемы с доступом к шине, и иногда процессы с основного ядра занимали шину и данные терялись, приходилось самому следить за контролем доступа — это было неудобно, сейчас победили данную проблему.
                                        • 0
                                          На STM32 делаю преобразователи частоты и инверторы средней и большой мощности. От 10 кВт и до 2 МВт делаем. Использую F4 и F7, никаких проблем, управление скалярное, крутим насосы. :)
                                          • 0
                                            Скалярное на 2 МВт? На stm? Можно фото сего чуда и где купить? Русские или китайцы слепили?))
                                            • 0
                                              А в чем проблема? Такими приводами занимаюсь больше 10 лет… Сначала делал на С2000…
                                              Сейчас на STM. При чем тут китайцы? Сфера применения: насосы в нефтянке… погружные и наземные…
                                              • +1
                                                10 лет это конечно очень хорошо. А пример коммерческой железки на 2 МВт на STM32 можно все таки увидеть? И если вы их делаете, то интересно посмотреть на фото внутрянки.
                                                • 0
                                                  Про контроллер я писал на Хабре: Плата контроллера на базе STM32F7 с видеовыходом… такая статья была. Для меня принципиально было наличие большой памяти на борту, поскольку используется цветной ЖК монитор для вывода информации. У TI такие контроллеры появились только не так давно. Скалярный режим управления STM32 тянет без вопросов, да вектор бы потянул, просто не было необходимости пока реализовывать. :) FFT по 128 точкам делает за 1,5 мсек, если правильно помню свои замеры. Это для индикации гармоник в питающей сети. В DSP библиотеке идут штатные Кларк-Парк :)
                                                  • 0
                                                    Я так и не увидел ни ссылку на 2 МВт, ни фото силовой части на F7…

                                                    «Скалярный режим управления STM32 тянет без вопросов» — пруфов нет. Вот я говорю, что не тянет на 2 МВт скалярник. Тоже пруфов нет, но я считаю, что это так и не иначе.

                                                    Видеовыход для силовой электроники вообще не актуален. Если мне надо крутить картинки с голыми девками на панели оператора, чтобы рабочие не скучали, то ставится любой дешевый Cortex-A, на него линукс и все радуются. Вот только частотников с fullHD мониторами я не видел пока.

                                          • +2
                                            Я немного удивился и решил проверить — действительно на русском языке по семейству C2000 нет практически ничего (на фоне AVR, STM), а главное нет понятных стартовых гайдов

                                            Есть вот такая книга Встраиваемые высокопроизводительные цифровые системы управления, там про Texas предыдущей ревизии, до piccolo, но также с ядром C28. Начинается с азов языка Си, потом немного про мигание светодиодиком, и кончается синтезом цифрового фильтра и настройкой регуляторов тока. Нооткрыть её для себя действительно сложно, потому что название никак не намекает на Texas Instruments.
                                            • +2
                                              Спасибо за ссылку! Думаю всем будет полезно, включу ее в конце в статью.

                                              P.S. Приятно, что заглянули товарищи с «Вектор»-а, года 2 назад залипал в ваши шикарные статьи по приводу))
                                            • 0
                                              У акселератора (CLA) есть такой же доступ к периферии (ADC, DAC, PWM) как и у основного ядра (я работаю с TMS320F28377S). При работе с CLA необходимо необходимо указать соответствующий командный файл для линкера. С недавних пор на сайте TI все примеры применения расположены в папке C2000Ware_1_00_01_00 (за версию не ручаюсь), а не в controlSUITE. На мой взгляд, начинать работать лучше не с создания с нуля нового проекта, а с подходящего примера из C2000Ware. При работе с CLA надо учитывать, что обмен данными между ядром и CLA осуществляется через специальные области памяти, которые надо нестроить.
                                              • +1
                                                Не знаю, как сейчас, но года 2 назад TI мне вернули деньги за заказанные образцы с формулировкой типа «Сожалеем, но мы не работает с РФ». Я на них обиделся, хорошо, если исправились.
                                                • 0
                                                  Такое было в конце 2015, лично не попадал, но на контору не прислали. Это как понял проблема была именно со стороны курьера, с DHL до сих пор не всегда гладко кстати. Заказывал перед НГ пару плат — проблем не возникло, доставка была fedex-ом.
                                                • 0
                                                  Кстати, воровать — так миллион, UCD3138 намного круче, может, про них?
                                                  • 0
                                                    Для преобразователей круче, а для всего остального типа привода уже не круче)) Я с UCD3138 работал достаточно мало, поэтому рассказывать о них не решусь, ибо компетенции маловато. Может быть как нибудь потом, после крупного проекта на них, если он конечно будет.
                                                  • НЛО прилетело и опубликовало эту надпись здесь

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

                                                    Самое читаемое