Урок 24
Знакомство с шиной SPI
Сегодня мы начинаем знакомство с шиной SPI (Serial Peripheral Interface).
Данная шина очень широко используется в электронике. Она очень удобна, являясь синхронной и полнодуплексной, поэтому, применяется во многих схемах для общения между различными цифровыми усторйствами — датчиками, контроллерами, драйверами и прочими устройствами.
Ещё одним важнейшим фактором необходимости нашего с ней знакомства является то, что данная шина аппаратно организована в контроллерах AVR.
Мало того, хотим мы этого или не хотим, с интерфейсом SPI мы с вами общаемся уже давным-давно, как только начали первый раз прошивать наш контроллер, так как прошивается он именно посредством данного интерфейса.
Поэтому хочется познакомиться с данной шиной поближе.
Давайте откроем техническую документацию на контроллер Atmega8, откроем страницу, где изображена распиновка данного контроллера и посмотрим, что от 16 до 19 ножки и находятся выводы шины SPI
Теперь немного подробнее о данных выводах
SS (chip select) — это ножка выбора устройства. Если на ведомом устройстве на данной ножке установится низкий уровень, то данное устройство будет откликаться и обмениваться информацией по шине SPI, если высокий, то не будет.
MOSI (master output slave input) — это ножка выхода ведущего устройства и входа ведомого устройства.
MISO (master input slave output) — наоборот, выход ведомого, вход ведущего.
SCK — ножка синхронизации. Ко всем устройствам, участвующим в обмене информации по данной шине, подаются синхроимпульсы с определённой частотой.
Вот схема реализации шины SPI в контроллере Atmega8
Как в любой шине, здесь имеется ряд регистров, в которых хранится определённая информация.
Нам интересен SHIFT REGISTER, через него и происходит обмен информации. Как только на ножке синхронизации будет определённый фронт, или нисходящий или восходящий, в зависимости от настройки, данные регистры у ведомого и ведущего устройства обменяются информацией, причем не всей информацией, а только одним битом. Данные регистры сдвинутся влево и старшие биты из каждого регистра уйдут в младшие биты такого же регистра сопряженного устройства. То есть ведомый передаст свой старший бит через ножку MOSI ведущему, который его запишет в освободившийся засчет сдвига влево младший бит, а ведомый свой вытесненный засчет сдвига передаст старший бит через ножку MISO в младший бит ведущего. Вот так и идёт обмен, то есть за 8 полных циклов тактирования они полностью обменяются байтами
Как только все 8 бит одного байта информации передадутся, определённый регистр нам просигнализирует о том, что данный процесс закончен. Вернее, определённый бит определённого регистра.
Также в блок-схеме мы видим делитель, на вход которого поступают тактовые импульсы и уже потом разделённые на определенное значение поступают по цепочке на ножку SCK и уже оттуда подаются на ведомое устройство на одноимённую ножку. Этим и обеспечивается синхронность работы устройств. Частота тактовых импульсов выбирается из наименьшей поддерживаемой всеми устройствами, участвующими в обмене.
Я говорю во множественном числе, так как может быть не только два устройства в данной цепи. Как это обеспечивается при условии, что у устройств нет никаких адресов, я сейчас и расскажу.
Существует несколько способов обмена информацией между несколькими устройствами, то есть когда на одно ведущее устройство приходится несколько ведомых. Мы рассмотрим два самых распространённых из них.
Первый способ — радиальный (нажмите на картинку для увеличения изображения)
Здесь мастер направляет данные к определённому устройству, включая на ножке SS логический 0. При данном способе возможно выбрать только одно устройство, также потребуются несколько свободных ножек портов контроллера.
Есть ещё один интересный способ — кольцевой или каскадный (нажмите на картинку для увеличения изображения)
Здесь мы видим, что ножки выбора все запараллелены и обмен идёт по кругу. Тем самым скорость падает, засчёт того, что увеличивается круг передачи, но зато экономятся лапки портов.
Всё это мы в очередных занятиях изучим подробнее, когда будем использовать определённые устройства в наших проектах.
Ну, вроде со схемотехникой передачи данных по шине SPI мы разобрались.
Теперь разберёмся, как же данным процессом управлять на уровне аппаратных регистров контроллера AVR.
Данные регистры мы видим в блок-схеме выше на странице.
У Atmega8 существуют следующие регистры для обслуживания шины SPI.
SPDR (SPI Data Register) — регистр данных, в блок-схеме это DATA BUFFER. В этот регистр мы будем заносить байт для последующей его передачи на ведомое устройство и из него же будем читать байт информации, пришедший с ведомого устройства. Также не обязательно что у нас контроллер будет ведущим устройством. Впоследствии мы соберём схему из двух контроллеров, один из которых будет ведомым. Так что именно в этом регистре будет находиться байт и для отправки и для приёма.
SPCR (SPI Control Register) — управляющий регистр
Данный регистр включает в себя следующие биты:
SPIE (SPI Interrupt Enable) — бит, который разрешает прерывания.
SPE (SPI Enable) — бит, включающий шину SPI.
DORD (Data Order) — бит, устанавливающий порядок отправки бит, Если он установлен в 1, то первым отправляется младший бит, если в 0 — старший.
MSTR (Master/Slave Select) — бит, который назначает устройство ведущим либо ведомым. При установке данного бита 1 устройство будет ведущим.
CPOL (Clock Polarity) — полярность синхронизации, определяет, при каком фронте синхронизирующего импульса будет инициироваться режим ожидания
Если данный бит в 1, то режим ожидания будет у нас при восходящем фронте, а если в 0, то при нисходящем.
CPHA (Clock Phase) — бит, отвечающий за фазу тактирования, то есть по какому именно фронту будет осуществляться передача бита.
Посмотрим диаграммы передачи данных в зависимости от установки CPOL и CPHA
Вот такая вот интересная зависимость. Порой мы иногда видим в технических характеристиках какого-нибудь устройства, что оно, к примеру, может работать в режиме SPI 0:0 и SPI 1:1, вот это как раз и касается настройки этих битов.
SPR1, SPR0 (SPI Clock Rate Select) — это биты, отвечающие за значение делителя частоты синхронизации, работают совместно с битом SPI2X, находящемся в регистре статуса. Он также управляющий, так как восьми бит в управляющем регистре под все настройки не хватило, а в статусном много свободных.
SPSR (SPI Status Register) — статусный регистр
SPI2X (Double SPI Speed Bit) — бит, удваивающий скорость, работающий совместно с битами SPR1 и SPR0 управляющего регистра.
Посмотрим зависимость частоты от данных трёх битов
SPIF (SPI Interrupt Flag) — Флаг прерывания. Установку данного бита в единицу мы ждём. когда принимаем байт. Как только байт от другого устройства появится полностью у нас в буфере, то данный флаг установится. Данный флаг работает только в случае установки бита, разрешающего прерывания, а также разрешения глобальных прерываний.
WCOL (Write COLlision Flag) — флаг конфликта, или коллизий, установится в том случае, если во время передачи данных будет конфликт битов, если во время передачи данных выполнится попытка записи в регистр данных.
Ну теперь мы, можно сказать, немного познакомились с интерфейсом SPI.
В следующем занятии мы уже попытаемся данную шину использовать на практике, подключив к нашему контроллеру какое-нибудь ведомое устройство.
Предыдущий урок Программирование МК AVR Следующий урок
Купить программатор можно здесь (продавец надёжный) USBASP USBISP 2.0
Смотреть ВИДЕОУРОК (нажмите на картинку)
Добрый вечер! Хорошые статти, в меня вопрос решыл собрать комутатор на мультиплекорах 4051, для мини АТС, SPI будет управлять здвиговым регистром НС595, а его выводы будут переключать мультиплексор 4051, вопрос втом какую максимальную частоту я смогу получить на вихода НС595? Контроллер AVR 16МГц.
Здравствуйте! Спасибо за оценку уроков!
Частоту Вы получите ровно такую, какую сможет дать Ваш контроллер. Регистр HC595 Вас в этом точно не ограничит, у него частота тактирования допустима до 100 МГц.
Добрый день.
Я яркий фанат вашего канала,пишу с проблемой.
Как мне правильно с конфиг.spi для приёма одного байта на beaglebone(master)<-atmega328(slave).Прошу помощи!
Доброго вечера!
Admin у Вас есть наработки c FLASH памятью AT45D161 с SPI интерфейсом, объёмом 16 Мбит?
Причём тут Admin и наработки?
В тексте есть опечатка! Автор, поправь ее. Конкретнее, описание к рисунку 58 и как происходит обмен побитно от мастера к слэйву.
Нашел три грамматические ошибки — исправил. Просто я не понял, какой именно из рисунков 58-й. Приведите, пожалуйста цитату, где именно ошибка.
«То есть ведомый передаст свой старший бит через ножку MOSI ведущему, который его запишет в освободившийся засчет сдвига влево младший бит, а ведомый свой вытесненный засчет сдвига передаст старший бит через ножку MISO в младший бит ведущего. »
Правильно должно быть: То есть ВЕДУЩИЙ…через ножку MOSI ВЕДОМОМУ, …
Добрый ден! Уроки хорошие и вполне понятные. Но у меня сть один вопрос. Мне нужно передать двумерный масссив, в котром заключен пиксельный риснук(в ргб) на матрицу ws2812 8 на 8. Вот функция которая за то отвечает. Подскажите в чем проблема?
void Write(unsigned int** temp)
{
for (int i = 0; i < 64; i++)
{
for (int o; o < 3; o++)
{
int a = 0x80;
for (int s = 0; s < 8; s++)
{
if (temp[i][s]&a == 0)
{
SPDR = 224;
}
else
{
SPDR = 252;
}
while(!(SPSR & (1<>1;
}
}
}
}