Sck[1].htm — как исправить ошибки [решено]

Описание SPI

Serial Peripheral Interface (SPI) — это последовательный, синхронный, полнодуплексный протокол передачи данных между главным (master) контроллером (обычно микроконтроллером или другими устройством с программируемой функциональностью) и несколькими ведомыми (slave) устройствами. Как мы увидим далее, SPI позволяет передавать данные как в полнодуплексном, так и в полудуплексном режиме. Спецификация SPI стандарт в протоколах передачи данных и была разработана в конце 70-х компанией Motorola и на данный широко используется как протокол передачи данных для многих цифровых микросхем. В отличие от протокола I2C, SPI не задает жестких условий в протоколе передачи данных по шине, давая ведомым (slave) устройствам полную свободу в структуре сообщений обмена данными.

Рисунок 1: Архитектура типовой SPI шины.

Типовая шина SPI содержит 4 сигнала, как показано на рисунке 1, даже, если возможно управлять некоторыми SPI устройствами, используя лишь 3 сигнала (в таком случае мы говорим о 3-проводном SPI).

  • SCK: сигнал, используемый для генерации тактовой частоты синхронизации передачи данных по SPI. Генерируется master устройством и это означает, что каждая передача по шине SPI всегда начинается по инициативе master устройства. В отличие от I2C SPI более быстрый интерфейс передачи данных и тактовая частота обычно в районе нескольких мегагерц. В наше время вполне обычно найти SPI устройства со скоростью обмена данными от 100 МГц и выше. Более того, протокол SPI позволяет работать в одной шине на различных скоростях в одно и то же время.
  • MOSI: расшифровывается как Master Output Slave Input и используется для передачи данных от главного (master) устройства к ведомому (slave). В отличие от I2C, где для обмена между устройствами используется лишь один провод, в SPI предусмотрено две линии передачии данных.
  • MISO: расшифровывается как Master Input Slave Output и используется для передачи данных от ведомого (slave) устройства к главному (master).
  • SSn: Slave Select используется для адресации устройств в шине SPI, где „n“ — количество линий адресации. В отличие от I2C, SPI не использует адреса ведомых (slave) устройств, а использует физические линии адресации, которые устанавливаются в низкий логический уровень для выбора устройства. В типовой SPI шине только одно ведомое (slave) устройство может быть активно в одно время путем установки линии SS в низкий уровень. В этом причина того, что в одной и той же шине могут быть устройства с разной скоростью передачи данных.

Имея две раздельные шины данных, MOSI и MISO, SPI по сути является полнодуплексным интерфейсом передачи данных, таким образом ведомое (slave) устройство может отдавать данные главному (master) пока одновременно принимает данные от него же. В одноранговых шинах (когда одно главное (master) и одно ведомое (slave) устройства), сигнал SS может не использоваться, лишь достаточно его подтянуть к «земле» резистором на несколько килоом, линии MISO/MOSI соединяются в одно общую линию Slave In/Slave Out (SISO). В таком случае мы говорим о двухпроводном SPI, хотя по существу он конечно же трехпроводной.

Рисунок 2: Как передаются данные по шине SPI в полнодуплексном режиме

Каждая транзакция в шине начинается с подачи тактирования в линию SCK в соответствии с допустимой тактовой частотой ведомого (slave) устройства. В то же время главное (master) устройство устанавливает LOW уровень на линии SS и передача данных начинается. Обычно обмен данными подразумевает использование двух регистров (в основном 8-битные, хотя некоторые slave устройства поддерживают 16-битный размер слова), одного в главном (master) устройстве и один в ведомом (slave). Данные побитно сдвигаются в сдвиговом регистре, начиная со старшего бита, пока младший бит сдвигается в этот же самый регистр. В это же самое время, данные от ведомого (slave) устройства сдвигаются в младший бит регистра данных. Когда все биты регистра будут сдвинуты в одну и другую сторону обмен данными будет осуществлен. Если необходимо передать более одного слова данных, сдвиговые регистры обнуляются и процесс повторяется. Обмен данными может продолжаться сколько угодно большое количество циклов тактового генератора. Когда обмен завершен master выключает тактовый сигнал и линия SS возвращается в исходное состояние высокого логического уровня.
Рисунок 2 показывает процесс обмена данными в полнодуплексном режиме, рисунок 3 же демонстрирует процесс в полудуплексном режиме.

Рисунок 3: Как передаются данные по шине SPI в полудуплексном режиме

Малюємо за допомоги touch screen

ILI9341статтіincsrc

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ili9341.h"
#include "XPT2046_touch.h"
/* USER CODE END Includes */
/* USER CODE BEGIN 2 */
  lcdBacklightOn();
  lcdInit();
  lcdSetOrientation(LCD_ORIENTATION_PORTRAIT);
  lcdFillRGB(COLOR_BLACK);
  /* USER CODE END 2 */
void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin)
{
 if (GPIO_Pin == T_IRQ_Pin)
 {
  if(XPT2046_TouchPressed())
  {
   uint16_t x = , y = ;
   if(XPT2046_TouchGetCoordinates(&x, &y))
   {
    lcdFillCircle((lcdGetWidth() - x), y, 2, COLOR_GREENYELLOW);
   }
  }

 }
}

CubeMX

За основу візьмемо проект з попередньої статті. Згідно схеми, сенсорну панель підключено до SPI2 мікроконтролеру, де T_SCK — PB13, T_MISO — PB14, T_MOSI — PB15, сигнал чип-селект T_CS — PB12, а сигнал готовності даних при натисканні T_IRQ (T_PEN) — PC5 (виділено червоним):

Схема підключення touchscreen

Завантажимо до CubeMX проект з попередньої статті. В мене це «STM32F407VE_Black_ILI9341.ioc», робимо потрібні налаштування та зберігаємо з іншим ім’ям, як окремий проект.

Налаштування SPI:

Налаштування SPI
  1. В розділі «Connectivity» обираємо SPI2;
  2. Mode -> Full-Duplex Master;
  3. Prescaller -> 32 (можна спробувати 16), щоб Baud Rate було 1.3125 Mbits/s (2.625 Mbits/s);
  4. Перевірте щоб SPI2 був на шпильках як зазначено на малюнку.

Налаштування GPIO для Chip Select:

Налаштування T_CS
  1. В розділі «System Core» обираємо GPIO;
  2. Тиснемо на PB12;
  3. Налаштовуємо як на малюнку GPIO output level -> High, GPIO mode -> Output Push Pull, GPIO Pull-up, Maximum output speed -> High, User Label -> T_CS;
  4. Перевіряємо щоб назва PB12 була T_CS.

Налаштування GPIO для T_IRQ:

Налаштування T_IRQ
  1. В розділі «System Core» обираємо GPIO;
  2. Тиснемо на PC5;
  3. Налаштовуємо як на малюнку. GPIO mode -> External Interrupt Mode with Rising/Falling edge trigger detection, GPIO Pull-up, User Label -> T_IRQ;
  4. Перевіряємо щоб назва PC5 була T_IRQ.

Налаштування переривання від шпильки T_IRQ:

Налаштування переривань
  1. В розділі «System Core» обираємо NVIC;
  2. Позначаємо «галочкою» (checkbox) «EXTI line interrupts».

Налаштування FSMC залишаємо як є з попередньої статті. Або, як проект створили новий, то налаштовуємо, як в статті «STM32: Бібліотека дисплею ILI9341 по інтерфейсу FSMC».

Зберігаємо проект, та генеруємо код проекту. Відкриваємо чи експортуємо проект до свого засобу розробки.

spi.setup()¶

Set up the SPI configuration.
Refer to for details regarding the clock polarity and phase definition.

Calling will route the HSPI signals to the related pins, overriding previous configuration and control by the module. It is possible to revert any pin back to gpio control if its HSPI functionality is not needed, just set the desired for it. This is recommended especially for the HSPI /CS pin function in case that SPI slave-select is driven from a different pin by — the SPI engine would toggle pin 8 otherwise.

Parameters

  • SPI ID number: 0 for SPI, 1 for HSPI
  • select master or slave mode

    • — not supported currently
  • clock polarity selection
  • clock phase selection
  • number of bits per data item 1 — 32
  • SPI clock divider, f(SPI) = 80 MHz / , 1 .. n (0 defaults to divider 8)
  • duplex mode

    • (default when omitted)

3Стандартная библиотека для работы по интерфейсу SPI

Для Arduino написана специальная библиотека, которая реализует протокол SPI. Она устанавливается вместе со средой разработки Arduino IDE. Подключается она так: в начале программы добавляем #include SPI.h.

Чтобы начать работу по протоколу SPI, нужно задать настройки и затем инициализировать протокол с помощью процедуры SPI.beginTransaction(). Можно выполнить это одной инструкцией: SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE0))

Это значит, что мы инициализируем протокол SPI на частоте 14 МГц, передача данных идёт, начиная с MSB (наиболее значимого бита), в режиме SPI_MODE0.

После инициализации выбираем ведомое устройство, переводя соответствующий пин SS в состояние LOW. Затем передаём ведомому устройству данные командой SPI.transfer(). После передачи возвращаем SS в состояние HIGH.

Временная диаграмма работы интерфейса SPI

Работа с протоколом завершается командой SPI.endTransaction().

Желательно минимизировать время выполнения передачи между инструкциями SPI.beginTransaction() и SPI.endTransaction(), чтобы не возникло накладок, если другое устройство попробует инициализировать передачу данных, используя другие настройки.

Если вы планируете в своём скетче использовать стандартные пины Arduino, можно не описывать их в начале программы, т.к. они уже определены в самой библиотеке и имеют следующие имена:

#define PIN_SPI_SS    (10)
#define PIN_SPI_MOSI  (11)
#define PIN_SPI_MISO  (12)
#define PIN_SPI_SCK   (13)

Данные пины определены в файле pins_arduino.h , который находится по пути %programfiles%\arduino-(версия)\hardware\arduino\avr\variants\ (если вы устанавливали программу в стандартное расположение). То есть, например, чтобы опустить пин выбора ведомого в состояние «0», можно написать:

digitalWrite(PIN_SPI_SS, LOW);

Реализация алгоритма в аппаратуре

  • Начальное формирование частоты. Линии CS и MOSI должны находиться в состоянии логической единицы.
  • Передача данных в SD-карту.
  • Прием данных от SD-карты.
  • Ожидание завершения команды. Используется, когда после формирования ответа SD-карта притягивает линию MISO к нулю, что бы дождаться появления единицы.
  • Чтение ответа при записи данных.
  • Ожидание токена при чтении данных.
  • Тактовый сигнал для инициализации.
  • Тактовый сигнал для работы.
  • Компонент физического уровня, который подключен непосредственно к SD-карте, формирует сигналы SCLK, CS, DI, читает с DO.
  • Компонент командного уровня, который осуществляет подготовку всех данных для компонента физического уровня.
  • Компонент общения с внешним миром, который скрывает всё внутренне устройство и предоставляет интерфейс для команд (чтение, запись, стирание) и данных.

2.1 Компонент физического уровня

  • iPhyTxData содержит данные для уровня, а iPhyMode содержит режим, как эти данные обрабатывать.
  • iPhyTxWrite показывает, в какой момент iPhyTxData и iPhyMode корректны.
  • oPhyTxReady показывает, когда компонент готов к приему данных. Фактически представляет собой выход FULL FIFO, используемого для синхронизации компонентов.
  • oPhyRxData данные и статус, прочитанные с SD-карты.
  • oPhyRxWrite показывает, в какой момент значение oPhyRxData корректно.
  • oPhyCmdEnd признак, что компонент завершил обработку команды.
  • oSdCS сигнал выбора микросхемы (CS) для SD-карты.
  • oSdClk тактовый сигнал для SD-карты.
  • oSdMosi линия передачи данных в SD-карту.
  • oSdMosiT линия управления буфером линии передачи данных в SD-карту.
  • iSdMiso линия приема данных от SD-карты.
  • sclk тактовый сигнал для работы с SD-картой (50 МГц).
  • pclk тактовый сигнал, на котором работает командный уровень.
  • rst сигнал сброса, активный уровень единица.
  • Состояние sDummy обеспечивает начальное формирование частоты, 128 переключений.
  • Состояние sTxBits обеспечивает передачу данных в SD-карту.
  • Состояние sRxBits обеспечивает прием данных от SD-карты.
  • Состояние sBusy обеспечивает ожидание готовности SD-карты (карта отпускает линию MISO к уровню единицы).
  • Состояние sResp реализует чтение ответа при записи данных.
  • Состояние sToken реализует ожидание токена при чтении данных.

2.2 Компонент командного уровня

  • oSdInitComp признак завершение инициализации SD-карты.
  • oSdInitFail признак неудачного завершения инициализации.
  • iSdAddress адрес в SD-карте для выполнения команды.
  • iSdStartErase запуск выполнения команды стирания.
  • iSdStartRead запуск выполнения команды чтения.
  • iSdStartWrite запуск выполнения команды записи.
  • oSdCmdFinish статус завершения команды. Нулевой бит равен единице, команда завершена успешно. Первый бит равен единице, команда завершена с ошибкой.
  • oSdhcPresent признак обнаружения карты SDHC/SDXC.
  • oSdReadData чтение данных для записи в SD-карту.
  • iSdDataR данные для записи в SD-карту.
  • oSdWriteData признак записи данных, прочитанных с SD-карты.
  • oSdDataW данные, прочитанные с SD-карты.

2.3 Компонент общения с внешним миром

  • iSdCommand код команды для выполнения.
  • iSdAddress адрес для выполнения команды.
  • iSdStart запуск выполнения команды.
  • oSdStatus статус завершения команды. Нулевой бит равен единице — команда завершена. Первый бит равен единице — команда завершена с ошибкой.
  • oSdInitFail признак неудачного завершения инициализации.
  • iSdTxData. Интерфейс Axi-Stream для записи данных в SD-карту. Порт с данными.
  • iSdTxValid. Интерфейс Axi-Stream для записи данных в SD-карту. Порт с сигналом записи.
  • iSdTxLast. Интерфейс Axi-Stream для записи данных в SD-карту. Порт с признаком последнего dw в данных.
  • oSdTxReady. Интерфейс Axi-Stream для записи данных в SD-карту. Порт с признаком готовности к приему данных.
  • oSdRxData. Интерфейс Axi-Stream для чтения данных из SD-карты. Порт с данными.
  • oSdRxValid. Интерфейс Axi-Stream для чтения данных из SD-карты. Порт с сигналом записи.
  • oSdRxLast. Интерфейс Axi-Stream для чтения данных из SD-карты. Порт с признаком последнего dw в данных.
  • iSdRxReady. Интерфейс Axi-Stream для чтения данных из SD-карты. Порт с признаком готовности к приему данных.
  • Состояние sIdle. Ожидание завершения инициализации и команды на выполнение.
  • Состояние sWaitCmd. Проверка типа команды.
  • sReadCmd. Проверка места в FIFO, что поместится пакет, который будет прочитан из SD-карты и формирование сигнала запуска команды чтения.
  • sWriteCmd. Проверка, что в FIFO есть пакет для записи в SD-карту, и формирование сигнала запуска команды записи.
  • sEraseCmd. Формирование сигнала запуска команды стирания.
  • sWaitEnd. Ожидание завершения выполнения команды от командного уровня.
  • sFinish. Выход из автомата, команда выполнена.

ШИМ

ШИМ на втором таймере настраивается так же, как в предыдущей истории, с двумя отличиями:

Во-первых, нам надо включить прерывание на Update Event (UEV), которое будет вызывать функцию, переключающую активный LED. Делается это изменением бита Update Interrupt Enable в регистре с говорящим названием

Второе отличие связано с таким явлением мультиплексинга, как ghosting – паразитное свечение диодов. В нашем случае оно может появитсья из-за того, что таймер, вызвав прерывание на UEV, идет тикать дальше, и обработчик прерывания не успевает переключить LED прежде чем таймер уже начнет что-то писать в выводы

Для борьбы с этим придется инвертировать логику (0 = максимальная яркость, 255 = ничего не горит) и не допускать крайних значений скважности. Т.е

добиться того, чтобы после UEV светодиоды полностью гасли на один такт ШИМ.

Меняем полярность:

Избегаем установки r, g и b в 255 и не забываем их инвертировать при использовании.

Прерывания

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

Когда мы в первый раз создали проект в ST Visual Develop, то кроме мы получили окно с загадочным файлом , автоматически включенным в проект. В этом файле на каждое прерывание привязана функция . Нам надо привязать свою функцию к нужному прерыванию.

В даташите есть таблица векторов прерываний, где мы находим нужные:

Нам надо менять LED при UEV, так что нужно прерывание №13.

Соответственно, во-первых, в файле меняем имя функции, отвечающей за прерывание №13 (IRQ13) по умолчанию на свое:

Во-вторых, нам придется создать файл такого содержания:

Ну и, наконец, прописать эту функцию в своем :

Осталось включить прерывания. Делается это ассемблерной командой – искать ее придется в :

Другая ассемблерная команда – – выключает прерывания. Их надо отключать на время записи новых значений в «видеопамять», чтобы вызванное в неудачный момент прерывание не испортило массив.

Весь код – .

Если хоть кому-то эта статья пригодится, значит, я не зря ее писал. Буду рад комментариям и замечаниям, постараюсь ответить на все.

Какими бывают SPI контроллер и SPI RGB лента.

Как и обычные RGB, SPI контроллер и SPI RGB лента могут иметь влагозащищенное исполнение и боковое свечение (модели со словом Side в названии). Последнее достигается применением специальных светодиодов с оптическими осями параллельными плоскости пайки. Такие модели удобны для монтажа в узких щелях или на горизонтальных поверхностях при горизонтальном же направлении максимума излучения, что очень часто требуется в подсветке дизайнерских потолков и наружных архитектурных элементов, для окантовки вывесок и рекламных щитов или отдельных объёмных букв и т. п.

Технически независимое регулирование яркости каждого диода в каждом пикселе (которых могут быть тысячи) обеспечивается, конечно, не прокладкой кабеля с соответствующим количеством жил, а цифровыми методами. Для кодированного управляющего сигнала, в котором заключена информация для всех пикселей, достаточно одного или двух проводников, кроме общего. Каждый пиксель (3 диода разных цветов или несколько таких групп) питается от встроенного в ленту возле него микрочипа-драйвера, который и регулирует свечение в соответствии с последним пришедшим кодом.

Управление SPI RGB лент (от английского Serial Peripheral Interface) последовательный: каждый драйвер «берёт» из управляющего кода свою часть информации, а остальное переправляет на следующий. Поэтому выход из строя любого из них останавливает всю ленту. Но благодаря огромному сроку службы и высокой надёжности светодиодов отказы происходят крайне редко, в основном только из-за механических повреждений. Зато не требуется более хлопотная пуско-наладка с прописыванием индивидуального адреса каждого пикселя, как в более универсальном протоколе DMX, а любой повреждённый участок ленты достаточно просто физически – без какой-либо последующей настройки – заменить аналогичной по количеству пикселей (юнитов), то есть просто такой же длины. (Напомним, что юнитами называются кратчайшие отрезки ленты с повторяющейся структурой, по специально обозначенным границам которых её можно резать).

Включаем тактирование

За тактирование отвечают часики, они же Clock. И мы уже могли заметить аббревиатуру RCC. Ищем ее в документации: это Reset and Clock Control (Управление сбросом и тактированием).

Как выше было сказано, к счастью, самое сложное из темы тактирования за нас сделали люди из STM, за что им большое спасибо (еще раз дам ссылку на , чтобы было понятно, насколько это заморочено). Нам нужны всего лишь регистры, отвечающие за включение тактирования периферии (Peripheral Clock Enable Registers). Для начала найдем базовый адрес RCC, он в самом начале «Карты памяти»:

И в них, соответственно, биты, включающие тактирование SPI2, IOPB (I/O Port B) и альтернативных функций (AFIO).

Финальный код можно найти .

Если есть возможность и желание потестить, то подключаем DM634 так: DAI к PB15, DCK к PB13, LAT к PB14. Питаем драйвер от 5 вольт, не забываем объединить земли.

ШИМ на STM8

Когда я только планировал эту статью, я решил для примера попробовать освоить какой-нибудь функционал незнакомого мне чипа с помощью только даташита, чтобы не получался сапожник без сапог. STM8 на эту роль подходил идеально: во-первых, у меня была пара китайских плат с STM8S103, а во-вторых, он не слишком популярен, а потому соблазн почитить и найти решение в интернете упирается в отсутствие этих самых решений.

К чипу также есть и , в первом распиновка и адреса регистров, во втором – все остальное. Программируется STM8 на C в страшненькой IDE .

Тактирование и ввод-вывод

По умолчанию STM8 работает на частоте 2 МГц, это надо сразу исправить.

Находим адрес регистра в даташите, описание в refman и видим, что регистр надо очистить:

Поскольку мы собираемся запускать ШИМ и подключать светодиоды, смотрим распиновку:

Чип маленький, многие функции подвешены на одни и те же пины. То, что в квадратных скобках – «альтернативный функционал», он переключается «байтами опций» (option bytes) – что-то вроде фьюзов Атмеги. Менять их значения можно программно, но не нужно, т.к. активируется новый функционал только после перезагрузки. Проще воспользоваться ST Visual Programmer (качается вместе с Visual Develop), умеющим менять эти байты. В распиновке видно, что выводы CH1 и CH2 первого таймера спрятаны в квадратные скобки; надо в STVP проставить биты AFR1 и AFR0, причем второй также перенесет вывод CH1 второго таймера с PD4 на PC5.

Таким образом, управлять светодиодами будут 6 пинов: PC6, PC7 и PC3 для первого таймера, PC5, PD3 и PA3 для второго.

Настройка самих пинов ввода-вывода на STM8 проще и логичнее, чем на STM32:

  • знакомый по Atmega регистр направления данных DDR (Data Direction Register): 1 = вывод;
  • первый контрольный регистр CR1 при выводе задает режим «тяни-толкай» (1) или открытый сток (0); поскольку я подключаю светодиоды к чипу катодами, оставляю тут нули;
  • второй контрольный регистр CR2 при выводе задает скорость тактирования: 1 = 10 МГц

Programming for SPI

Many microcontrollers have built-in SPI peripherals that handle all the details of sending and receiving data, and can do so at very high speeds. The SPI protocol is also simple enough that you (yes, you!) can write your own routines to manipulate the I/O lines in the proper sequence to transfer data. (A good example is on the Wikipedia SPI page.)

If you’re using an Arduino, there are two ways you can communicate with SPI devices:

  1. You can use the shiftIn() and shiftOut() commands. These are software-based commands that will work on any group of pins, but will be somewhat slow.

  2. Or you can use the SPI Library, which takes advantage of the SPI hardware built into the microcontroller. This is vastly faster than the above commands, but it will only work on certain pins.

You will need to select some options when setting up your interface. These options must match those of the device you’re talking to; check the device’s datasheet to see what it requires.

  • The interface can send data with the most-significant bit (MSB) first, or least-significant bit (LSB) first. In the Arduino SPI library, this is controlled by the setBitOrder() function.

  • The slave will read the data on either the rising edge or the falling edge of the clock pulse. Additionally, the clock can be considered «idle» when it is high or low. In the Arduino SPI library, both of these options are controlled by the setDataMode() function.

  • SPI can operate at extremely high speeds (millions of bytes per second), which may be too fast for some devices. To accommodate such devices, you can adjust the data rate. In the Arduino SPI library, the speed is set by the setClockDivider() function, which divides the master clock (16MHz on most Arduinos) down to a frequency between 8MHz (/2) and 125kHz (/128).

  • If you’re using the SPI Library, you must use the provided SCK, MOSI and MISO pins, as the hardware is hardwired to those pins. There is also a dedicated SS pin that you can use (which must, at least, be set to an output in order for the SPI hardware to function), but note that you can use any other available output pin(s) for SS to your slave device(s) as well.

  • On older Arduinos, you’ll need to control the SS pin(s) yourself, making one of them low before your data transfer and high afterward. Newer Arduinos such as the Due can control each SS pin automatically as part of the data transfer; see the Due SPI documentation page for more information.

Программирование микроконтроллеров STM32

Микропроцессором называется программно-управляемое устройство, осуществляющее процесс обработки цифровой информации и управление им. Микропроцессор реализуется в виде большой (БИС) или сверхбольшой (СБИС) интегральной микросхемы. Микропроцессор выполняет роль процессора в цифровых системах различного назначения.
Главной особенностью микропроцессора является возможность программирования логики работы.Микроконтроллер (MCU) – микросхема, предназначенная для управления электронными устройствами. Типичный микроконтроллер сочетает в себе функции процессора и периферийных устройств, может содержать ОЗУ и ПЗУ. По сути, это однокристальный компьютер, способный выполнять простые задачи. Использование одной микросхемы, вместо целого набора, как в случае обычных процессоров, применяемых в персональных компьютерах, значительно снижает размеры, энергопотребление и стоимость устройств, построенных на базе микроконтроллеров.Микропроцессорная система (МПС) представляет собой функционально законченное изделие, состоящее из одного или нескольких устройств, главным образом микропроцессорных: микропроцессора и/или микроконтроллера.Микропроцессорное устройство (МПУ) представляет собой функционально и конструктивно законченное изделие, состоящее из нескольких микросхем, в состав которых входит микропроцессор; оно предназначено для выполнения определенного набора функций: получение, обработка, передача, преобразование информации и управление.Основные преимущества микропроцессорных систем по сравнению с цифровыми системами на «жесткой логике».

  • Многофункциональность: большее количество функций может быть реализовано на одной элементной базе.
  • Гибкость: возможность исправления и модификации программы микропроцессора для реализации различных режимов работы системы.
  • Компактность: миниатюрные габариты микросхем и уменьшения их количества по сравнению с реализацией на «жесткой логике» позволяют уменьшить габариты устройств.
  • Повышение помехоустойчивости: меньшее количество соединительных проводников способствует повышению надежности устройств.
  • Производительность: возможность применения больших рабочих частот и более сложных алгоритмов обработки информации.
  • Защита информации: возможность защитить программу микропроцессора от считывания позволяет защитить авторские права разработчиков.

Хотя микропроцессор является универсальным средством для цифровой обработки информации, однако отдельные области применения требуют реализации определенных специфических вариантов их структуры и архитектуры. Поэтому по функциональному признаку выделяются два класса: микропроцессоры общего назначения и специализированные микропроцессоры. Среди специализированных микропроцессоров наиболее широкое распространение получили микроконтроллеры, предназначенные для выполнения функций управления различными объектами, и цифровые сигнальные процессоры (DSP – Digital Signal Processor), которые ориентированы на реализацию процедур, обеспечивающих необходимое преобразование аналоговых сигналов, представленных в цифровой форме.
Неполный список периферии, которая может присутствовать в микроконтроллерах, включает в себя:

  • различные интерфейсы ввода-вывода, такие как UART, I²C, SPI, CAN, USB, ETHERNET;
  • аналого-цифровые и цифро-аналоговые преобразователи;
  • компараторы;
  • широтно-импульсные модуляторы;
  • таймеры-счетчики;
  • генератор тактовой частоты;
  • контроллеры дисплеев и клавиатур;
  • массивы встроенной флэш-памяти.

Идея размещения на одном кристалле микропроцессора и периферийных устройств принадлежит инженерам М. Кочрену и Г. Буну, сотрудникам Texas Instruments. Первым микроконтроллером был 4-х разрядный TMS1000 от Texas Instruments, который содержал ОЗУ (32 байта), ПЗУ (1 кбайт), часы и поддержку ввода-вывода. Выпущенный в 1972 году, он имел новую по тем временам возможность – добавление новых инструкций.
В 1976 году (через 5 лет после создания первого микропроцессора) на свет появился первый микроконтроллер фирмы Intel, получивший имя 8048. Помимо центрального процессора, на кристалле находились 1 килобайт памяти программ, 64 байта памяти данных, два восьмибитных таймера, генератор часов и 27 линий портов ввода-вывода. Микроконтроллеры семейства 8048 использовались в игровых консольных приставках Magnavox Odyssey, в клавиатурах первых IBM PC и в ряде других устройств.
На сегодняшний день среди крупных производителей микроконтроллеров следовало бы упомянуть Atmel, Microchip, ST Microelectronics, Texas Instruments, Freescale Semiconductor, NXP и др.

Регистры модуля SPI

Существует ещё один интерфейс, который похож на SPI, под названием I2S. В stm32 оба интерфейса объединены в один модуль, а значит и делят общие регистры. Всего в stm32f103c8 имеется целых три модуля SPI — (шина APB2) и , (шина APB1). Рассмотрим только то, что нам необходимо для работы с микросхемой max7219.

Как и у другой любой периферии начать стоит с регистров настройки и .

Первые два бита, и , нам уже знакомы, они отвечают за режим работы интерфейса. , как можно догадаться, задаёт роль устройства на шине. Записав микроконтроллер становится ведущим, и наоборот, записав делает его ведомым. Следующая группа битов позволяет настроить делитель частоты тактирования шины: соответствует делению на 2; делению на 4; и т.д. Бит разрешает или запрещает работу модуля; трогать его следует в самый последний момент, когда настройка завершена. как понятно из названия отвечает за порядок бит. Биты и задают работу CS, обычно её оставляют программной, для ведущего устройства. Бит задаёт размер данных, соответствует 8 битам, 16-ти. Модуль может аппаратно вычислять суммы CRC, но мы их использовать не будем (биты и ). Последние два бита задают конфигурацию проводов: задаёт двунаправленный () или однонаправленный () режим, а говорит какая из линий в однонаправленном режиме будет использоваться, MOSI () или MISO (). Бит работает влияет на работу только двухпроводной линии, при записи туда SPI будет работать только на приём данных.

Следующий регистр в основном отведён под прерывания. Всего событий от модуля SPI может быть три: буфер передачи пуст (); буфер заполнен (); произошла ошибка (). Биты и разрешают или запрещают запрос к модулю DMA по завершению передачи или приёма соответственно.

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

Бит сигнализирует, что идёт приём или передача данных (буфер не пуст). Если данные будут приходить быстрее, чем они будут считываться, то очевидно часть данных будет потеряно. Модуль в таком случае выставит в бите . Флаг сообщает, что произошла ошибка режима работы, ножка CS была подтянута к нулю из вне. Данный флаг удобен, когда нужно организовать работу нескольких ведущих устройств на шине. Так как данные проходят через среду, они могут быть испорчены. Флаг сигнализирует о такой ошибке. предназначен для I2S. Последние два флага отвечают за прерывания по завершению приёма () и передачи ().

Так как SPI и I2S разные интерфейсы, но повешены на один модуль, то нужно указать какой именно интерфейс мы собираемся использовать. Делается это через регистр , а конкретно через бит . Записав туда модуль будет работать в режиме SPI.

Последний регистр который нам понадобиться — буфер . Он устроен хитрым образом: при записи в него он перекладывает данные в буфер отправки, а при чтении отдаёт то, что хранится в буфере приёма.

Можно приступать к написанию драйвера для микросхемы MAX7219.

Назад |
Оглавление |
Дальше

Оцените статью:
Оставить комментарий