Микроконтроллеры серии TMS320C28xx (C2000) от Texas Instruments появились достаточно давно, однако до сих пор остаются актуальными в ряде задач.
Эти микроконтроллеры отличаются надёжностью, обладают значительным объёмом оперативной памяти, поддерживают операции с числами с плавающей точкой (float/double) на аппаратном уровне, а также оснащены одними из лучших в своём классе модулями ШИМ (PWM) и АЦП (ADC). При этом их стоимость остаётся весьма демократичной.

В этой статье я расскажу об особенностях работы с данными микроконтроллерами.
Преимущества
Продвинутый ШИМ (PWM)
Почти все микроконтроллеры в линейке оснащены достаточно большим количеством ШИМ-каналов (например, 4×2 канала), отличающихся высокой гибкостью настройки.
Быстрый и точный АЦП, который можно синхронизировать с ШИМ. Это особенно удобно в задачах с обратной связью, например, при регулировании тока.
Большой набор настраиваемых прерываний.
Аппаратная поддержка операций с числами с плавающей точкой (float/double) благодаря встроенному FPU.
Некоторые модели включают дополнительное вычислительное ядро CLA (Control Law Accelerator) для ускорения математических расчётов.
Высокая надёжность: микроконтроллеры устойчивы к воздействию высоких температур.
Продвинутые средства отладки, включая возможность пошагового выполнения, анализа регистров и профилирования в реальном времени.
Области применения
Силовая электроника
Управление бесколлекторными двигателями (BLDC)
Анализ сигналов (например, в измерительном оборудовании)
Недостатки
Основной недостаток микроконтроллеров серии TMS320C28xx - сложность разработки:
Нестандартная архитектура не позволяет напрямую использовать сторонние библиотеки или готовый код без значительной доработки.
Низкая популярность среди широкой аудитории и слабо развитое сообщество разработчиков.
Объёмная и сложная документация, требующая времени на освоение.
Недостаток примеров и библиотек, предоставляемых производителем, особенно по сравнению с более массовыми платформами.
Программатор и отладочная плата
Оригинальные программаторы от Texas Instruments стоят довольно дорого и не всегда легко доступны. Однако на рынке уже давно представлены китайские аналоги, которые можно приобрести, например, на AliExpress. За примерно 5 000 рублей можно получить комплект, включающий как сам программатор, так и отладочную плату.
Программатор поддерживает загрузку прошивки и отладку через интерфейс JTAG. У меня был китайский программатор. В целом он работал стабильно, но проявлял высокую чувствительность к длине соединительных проводов: при длине более 10–15 см начинались проблемы с надёжностью связи с микроконтроллером.
Свои эксперименты я проводил на микроконтроллере TMS320F28069. Он относится к младшей части линейки C2000, рекомендованной Texas Instruments для управления двигателями, и обладает следующими характеристиками:
100 КБ(800Кбит) оперативной памяти (RAM),
256 КБ(2048Кбит) флеш-памяти (Flash),
встроено вычислительное ядро CLA (Control Law Accelerator).

Среда разработки
В качестве официальной среды разработки Texas Instruments предлагает Code Composer Studio (CCS) - по сути, единственный полноценный вариант для работы с микроконтроллерами серии C2000. CCS построена на базе платформы Eclipse.

Установка среды проста и не требует сложной настройки. Единственное, что может потребоваться дополнительно - установка компилятора, специфичного для выбранного микроконтроллера.
CCS работает достаточно шустро, предоставляет все необходимые инструменты для написания, сборки и отладки кода прямо на микроконтроллере и в целом не вызывает серьёзных нареканий. Единственное - в интерфейсе встречаются отдельные мелкие неудобства, но они не критичны для повседневной работы.
Отладка
Отладка микроконтроллера осуществляется в реальном времени через интерфейс JTAG. В процессе выполнения программы можно просматривать значения переменных и содержимое памяти без остановки выполнения кода. Данные обновляются примерно раз в секунду, их можно редактировать, визуализировать в виде графиков или сохранять в файл для последующего анализа.

В среде Code Composer Studio доступны два типа точек остановки (breakpoint):
Программные точки остановки
Они вставляются непосредственно в код с помощью специальной ассемблерной инструкции (например, ESTOP0). Такие точки особенно удобны при отладке исключений или аварийных ситуаций.
После останова доступен стек вызовов (call stack), позволяющий проследить цепочку вызовов, приведшую к текущему состоянию. При наведении курсора на переменную в редакторе кода отображается её текущее значение.
Если плата запущена без подключённого отладчика, программные точки останова игнорируются, и выполнение программы продолжается без прерываний.
Аппаратные точки остановки
Устанавливаются щелчком мыши в поле рядом с строкой исходного кода во время выполнения программы. Они работают аналогично программным, но их количество аппаратно ограничено - обычно доступно всего 2 точки.
Попытка установить больше приводит к нестабильности отладчика: он может аварийно завершить работу. В этом случае необходимо вручную удалить все точки останова и перезапустить сессию отладки - это один из самых раздражающих моментов при работе с CCS.
Дополнительные возможности
При останове также доступны:
Дизассемблированный код - позволяет увидеть текущие машинные инструкции;
Карта памяти - отображает распределение переменных и функций по адресному пространству;
Анализ использования стека - даёт оценку глубины рекурсии и потенциальных переполнений.
Регистры и работа с периферией
Для микроконтроллеров серии TMS320C28xx Texas Instruments официально не предоставляет высокоуровневых библиотек для работы с периферией (в отличие, например, от STM32 HAL или CMSIS). Всё взаимодействие с периферийными модулями осуществляется напрямую через регистры. (Возможно, такие библиотеки существуют, но на момент написания статьи мне не удалось их обнаружить.)
По умолчанию в новом проекте типы и структуры регистров не подключены. Их необходимо вручную добавить в проект. Соответствующие заголовочные файлы (например, F2806x_Device.h, F2806x_Examples.h) обычно находятся в подкаталогах, поставляемых вместе с Code Composer Studio - в частности, в папке common или в примерах проектов (C2000Ware или встроенных примерах CCS).
Полное описание регистров содержится в документации на сайте производителя в документах Technical Reference Manual.
Особенность архитектуры C28xx - наличие защиты критических регистров от случайной записи. Это особенно важно при работе с указателями: ошибка в адресации не приведёт, например, к неожиданному переключению GPIO из входа в выход, что могло бы повредить внешнюю схему.
Для временного снятия защиты и записи в защищённые регистры используются две специальные ассемблерные инструкции:
EALLOW- разрешает запись в защищённые регистры;EDIS- вновь блокирует доступ к ним.
Память
Оперативная память микроконтроллеров серии TMS320C28xx разбита на страницы и секции. Логическое распределение этих секций по адресному пространству и их назначение (для кода, данных, стека и пр.) описывается в линкер-скрипте - файле с расширением .cmd, который является частью проекта.

В исходном коде вы можете явно указать, в какой секции должна размещаться переменная или функция, используя прагмы компилятора. Например:
#pragma DATA_SECTION(myBuffer, "mySection")
uint16_t myBuffer[128];
Теоретически такая организация памяти позволяет повысить производительность: архитектура C28x поддерживает параллельное обращение к разным банкам памяти в рамках одного цикла выполнения (например, выборка инструкции из одной секции и чтение данных из другой). Однако на практике эта возможность требует тщательного планирования размещения кода и данных. В моём опыте подобное разбиение чаще создавало дополнительные сложности, чем ощутимый выигрыш в скорости — особенно без глубокого понимания архитектуры памяти контроллера.
Размещение функций в оперативной памяти
Для ускорения выполнения критических по времени функций их можно разместить непосредственно в ОЗУ, а не во флеш-памяти. Для этого используется прагма CODE_SECTION:
#pragma CODE_SECTION(fastISR, "ramfuncs")
void fastISR(void) {
}
Однако микроконтроллер не копирует код из флеш-памяти в ОЗУ автоматически. Это необходимо делать вручную - обычно в функции инициализации, сразу после запуска системы. Пример:
memcpy(&ramfuncs_run, &ramfuncs_load, (size_t)&ramfuncs_size);
где ramfuncs_load - адрес образа функций во флеш-памяти, ramfuncs_run - адрес их размещения в ОЗУ, а ramfuncs_size - размер секции. Эти символы генерируются линкером на основе .cmd-файла.
Особенности языка разработки
На мой взгляд, одной из самых серьёзных сложностей при работе с микроконтроллерами серии C2000 являются особенности их архитектуры, накладывающие существенные ограничения на язык программирования.
Разработка ведётся на C и C++, однако использование C++ сопряжено с ограничениями. В C++ недоступны виртуальные функции при наследовании классов - это неприятно.
Микроконтроллеры серии C2000 построены на 16-битной архитектуре и в них полностью отсутствует возможность работы с 8-битными типами данных: размер минимального типа char в коде составляет 16 бит. Хоть это и допускается стандартом языка C, это создаёт множе��тво проблем и не позволяет использовать чужой код и библиотеки без адаптации. Мало кто готов к тому, что sizeof(int32_t) = 2. Скопировать класс или структуру в массив байт не получится без костылей. При этом многие регистры контроллера работают только с 8 битами. Например, просто так отправить char в UART или SPI не получится: нужно сначала отправить младшие 8 бит, потом старшие при помощи битового сдвига.
Многоядерность и CLA
В двухъядерных чипах одно ядро является основным, а второе - CLA, вспомогательным; оно используется для ускорения вычислений.
На ядре CLA запускаются различные вычислительные задачи. Например, можно привязать запуск задачи к окончанию преобразования АЦП и выполнить обработку данных непосредственно на CLA. По завершении задачи в основном ядре генерируется прерывание.
Для CLA используется отдельный компилятор, и программировать его можно только на языке C. Внутри CLA доступны не все регистры: например, прочитать результаты АЦП можно, но управлять ШИМ - нельзя.
Обмен данными между основным ядром и CLA осуществляется через общие участки памяти, переменные в которых доступны из обоих ядер.
Мне такой подход понравился - он прост и понятен, и в нём нет сложных моментов с блокировкой памяти при совместном доступе.
Недостаток данной реализации - сложность настройки. Разобраться, как всё это запустить и корректно настроить, не так просто.
Сообщество
Отдельно хочу рассказать о сообществе и ресурсах по данной семье микроконтроллеров.
Решения на базе Texas Instruments в большинстве случаев используются внутри компаний, и их авторы редко делятся наработками публично. Как следствие, в сети почти нет сторонних материалов - найти информацию можно разве что на официальном форуме производителя, но ответы там зачастую скудные и малоинформативные. Если возникает какая-то проблема, быстро найти решение обычно не удаётся.
Выводы
Контроллеры серии TMS320C28xx хорошо подходят для узкого круга задач, где требуется высокая производительность и предсказуемость в реальном времени.
Как универсальное решение такой контроллер не применим - разработка на нём будет сложнее и займёт больше времени.
