Рубрики
Схемы на PIC

Использование интерфейса SPI в микроконтроллере PIC16F877A

Микроконтроллеры PIC отличаются достаточно низкой ценой и возможностями, не уступающими большинству современных микроконтроллеров. Они имеют широкий набор интерфейсов для взаимодействия с другими устройствами: USART, I2C и SPI. Ранее на нашем сайте мы уже рассматривали использование в микроконтроллерах PIC интерфейса I2C и USART (последовательный порт связи). В этой же статье мы рассмотрим использование интерфейса SPI в микроконтроллере PIC16F877A.

Также на нашем сайте мы рассматривали использование интерфейса SPI в других микроконтроллерах (платах):

Что такое SPI

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

Принципы работы интерфейса SPI

Для работы по принципу ведущий/ведомый (master/Slave) протокол SPI использует 4 линии (провода). В этом протоколе ведущий всегда один, а ведомых может быть несколько. В качестве ведущего устройства обычно выступает микроконтроллер, а в качестве ведомых устройств могут выступать микроконтроллеры, датчики, АЦП, ЦАП, ЖК дисплеи и т.д.

На следующем рисунке показан принцип работы протокола SPI с одним ведущим (Master) и одним ведомым (Slave).

SPI интерфейс для своей работы использует 4 линии – MISO, MOSI, SS, and CLK. Их назначение следующее:

  • MISO (Master in Slave Out) – линия ведомого для передачи данных ведущему;
  • MOSI (Master Out Slave In) – линия ведущего для передачи данных ведомому;
  • SCK (Serial Clock) – по этой линии передаются сигналы (импульсы) синхронизации, формируемые ведущим;
  • SS (Slave Select) – ведущий (Master) может использовать эту линию для включения и выключения определенных устройств (ведомых).

На следующем рисунке показан принцип работы протокола SPI с одним ведущим (Master) и несколькими ведомыми (Slave).

Чтобы начать связь (взаимодействие) между ведущим и ведомым нам необходимо установить на контакте ведомого Slave Select (SS) напряжение низкого уровня чтобы он мог взаимодействовать с ведущим. Когда на этом контакте напряжение высокого уровня (high) ведомый игнорирует ведущего. Это позволяет иметь множество ведомых устройств, работающих по протоколу SPI, использующих одни и те же (общие) линии MISO, MOSI и CLK ведущего устройства. Как вы можете видеть из представленного рисунка для 4-х ведомых устройств линии SCLK, MISO, MOSI общие для соединения с ведущим, а линии (контакты) SS каждого ведомого устройства подключены к отдельным контактам SS (SS1, SS2, SS3, SS4) ведущего устройства. При помощи установки на требуемом контакте SS напряжения низкого уровня (LOW) ведущий (master) может взаимодействовать с нужным ему ведомым (slave).

Отличия между интерфейсами I2C и SPI

В общем и целом эти два интерфейса решают похожие задачи – передача данных в устройствах встраиваемой электроники на небольшие расстояния. Но каждый из этих интерфейсов имеет свои преимущества и недостатки друг перед другом. Достоинством интерфейса I2C по сравнению с SPI является то, что при связи между двумя устройствами он использует всего 2 линии против 4-х у SPI, соответственно, он задействует меньшее число контактов микроконтроллера. Данное преимущество интерфейса I2C еще более возрастает в ситуациях, когда ведомых устройств (slaves) несколько, интерфейс I2C в данном случае будет точно также использовать 2 линии, а вот количество используемых линий ведущим устройством в интерфейсе SPI значительно увеличится (больше чем 4).

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

Работа с интерфейсом SPI в микроконтроллере PIC16F877A с помощью компилятора XC8

В данной статье мы будем рассматривать работу с интерфейсом SPI в микроконтроллере PIC16F877A только с помощью компилятора XC8, для других микроконтроллеров PIC работа с интерфейсом SPI будет аналогична рассматриваемым нами процессам, однако возможны небольшие изменения. Также для более «продвинутых» серий микроконтроллеров PIC, например, для серии PIC18F, компилятор уже содержит инструменты (библиотеки) для работы с интерфейсом SPI, однако для микроконтроллера PIC16F877A такой библиотеки нет, поэтому нам придется написать ее самим. Код данной библиотеки вы можете скачать по ссылке в конце статьи.

В данном проекте мы напишем небольшую программу, которая будет использовать протокол SPI для записи и чтения данных с шины SPI. Тестирование работы проекта мы произведем с помощью симулятора Proteus. В программе для работы с интерфейсом SPI мы будем подключать заголовочный файл библиотеки PIC16f877a_SPI.h. Вы можете использовать данную библиотеку и в других проектах, в которых требуется работа с интерфейсом SPI. Код программы и код данной библиотеки можно скачать по следующей ссылке.

Объяснение кода библиотеки для работы с интерфейсом SPI

Прежде чем начать работу с интерфейсом SPI в микроконтроллере PIC16F877A желательно посмотреть даташит на данный микроконтроллер. Из него можно узнать что для работы с протоколом SPI в микроконтроллере PIC16F877A используются регистры SSPSTAT и SSPCON. Более подробно об этом можно прочитать на страницах 74 и 75 даташита на микроконтроллер.

Для настройки работы интерфейса SPI можно использовать достаточно много параметров, но наиболее часто используемый из них это частота синхронизации (clock frequency). В данном проекте мы ее установим равной Fosc/4. Вы можете изменить ее по своему усмотрению. Далее кратко рассмотрим функции, которые включает наша библиотека для работы с интерфейсом SPI.

SPI_Initialize_Master()

Эта функция используется для инициализации интерфейса SPI в режиме ведущего устройства (Master). Внутри данной функции мы будем задавать режимы работы контактов RC5 и RC3 на вывод данных. Затем мы будем конфигурировать регистры SSPTAT и SSPCON.

SPI_Initialize_Slave()

Эта функция используется для инициализации интерфейса SPI в режиме ведомого устройства (slave). Внутри нее мы будем устанавливать режим работы контакта RC5 на вывод данных, а контакта RC3 – на ввод данных. Затем мы будем конфигурировать регистры SSPSTAT и SSPCON таким же образом, как и для ведущего устройства.

SPI_Write(char incoming)

Эта функция используется для записи данных на шину SPI. В качестве параметра она использует символ, задаваемый пользователем, который она пересылает в регистр передачи (Buffer register). Регистр SSPBUF будет очищен импульсом синхронизации, после чего данные на шину SPI будут передаваться последовательно, бит за битом.

SPI_Ready2Read()

Эта функция будет проверять приняты ли данные с шины SPI полностью и могут ли они быть считаны. Регистр SSPSTAT содержит бит BF, который устанавливается в 1 если данные приняты полностью. Поэтому в функции нам всего лишь необходимо проверить значение данного бита.

SPI_Read()

Эта функция используется для считывания данных с шины SPI в микроконтроллер PIC. Данные, присутствующие на шине SPI, будут сохраняться в регистре SSPBUF, нам необходимо подождать пока данные не будут приняты полностью (для этого мы проверяем бит BF регистра SSPSTAT), после чего мы можем считать их в переменную.

Объяснение основной программы для микроконтроллера PIC

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

Первым делом в программе мы настроим биты конфигурации и подключим заголовочный файл библиотеки для работы с интерфейсом SPI.

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

Внутри функции main нам необходимо инициализировать интерфейс SPI в микроконтроллере PIC в режиме ведущего (Master). После этого в бесконечном цикле мы будем записывать на шину SPI три случайных шестнадцатеричных значения.

Моделирование работы проекта

Моделировать работу нашего проекта мы будем в симуляторе Proteus, который для мониторинга данных, передаваемых по шине SPI, содержит такой удобный инструмент как SPI debugger. Схема нашего проекта, нарисованная в симуляторе Proteus, будет выглядеть следующим образом.

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

Для тестирования работы проекта загрузите hex файл в микроконтроллер PIC16F877A и нажмите на кнопку play чтобы запустить программу на выполнение. После этого на экране появится всплывающее окно, в котором будут отображаться данные, передаваемые по шине SPI, как показано на следующем рисунке.

Если мы посмотрим на них внимательнее, то мы увидим те самые три значения, которые мы передаем в шину SPI в программе.

Данные будут приниматься в том же самом порядке, в котором мы передаем их в программе. На основе данной программы вы также можете попробовать осуществить связь по интерфейсу SPI между двумя микроконтроллерами PIC, один из которых будет ведущим, а другой – ведомым.

Исходный код программы

Все необходимые файлы для проекта вы можете скачать по этой ссылке.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *