Samou4ka » 🐞 AVR.Начинающим » Интерфейс SPI микроконтроллеров AVR

Интерфейс SPI микроконтроллеров AVR

Интерфейс SPI (Serial Peripheral Bus) — интерфейс для обмена данными между микросхемами. Придуман компанией Motorola, но в настоящее время используется в продукции многих производителей. Шина SPI организована как «ведущий-подчиненный». В качестве ведущего чаще всего выступает микроконтроллер. Внешние устройства подключенные к ведущему являются подчиненными (ведомыми). Если соединить два микроконтроллера по шине SPI, то они могут по очереди становится ведущим или ведомым. Главное, что в конкретный момент времени на шине SPI только одно устройство может быть ведущим. Рассмотрим на примере mega8 какие ножки в МК связаны с шиной SPI и что они означают

Подключение устройств к ведущему понятно из рисунка ниже

При загрузке значения в регистр данных SPI ведущего он сразу же начинает генерить тактовый сигнал на SCK и побитно выдвигать данные на вывод MOSI, который соединен с входами MOSI ведомых устройств. Ведомое устройство получит данные, только если на выводе SS присутствует низкий уровень. Т.о. мы можем подключить к шине SPI микроконтроллера несколько SPI устройств и используя дополнительные ножки МК выбирать конкретное устройство с которым мы хотим в данный момент работать. Вывод SS ведущего можно сконфигурировать как выход и использовать его как выходной контакт. Если же он сконфигурирован как вход, его необходимо подключить к шине питания. Если на выводе SS ведущего устройства появится низкий уровень, то он переключится в режим ведомого.

Вообще, удобен этот интерфейс тем, что с ним очень просто работать. Давайте рассмотрим регистры МК, связанные с шиной SPI

SPDR — регистр данных, содержит посылаемый или принимаемый байт.

SPCR

Бит 7 — SPIE: разрешение прерываний. Прерывание генерится, если этот бит установлен и установлен бит глобального разрешения прерываний регистра SREG (6-й бит).

Бит 6 — SPE: включение SPI. Перед любыми действиями с SPI этот бит должен быть установлен в «1».

Бит 5 — DORD: порядок передачи данных. Если этот бит установлен в «1» то младший бит данных передается первым. Если этот бит сброшен в «0» — старший бит данных передается первым.

Бит 4 — MSTR: выбор режима работы. Если установлен в «1», то выбран режим ведущего, если в «0» — режим ведомого. Если SS сконфигурирован как вход и на него подан низкий уровень, в то время как бит MSTR установлен в «1», тогда этот бит сбросится в «0» и бит SPIF регистра SPSR (см. ниже) установится в «1».

Бит 3 — CPOL: полярность тактового сигнала. «0» — во время ожидания на SCK присутствует низкий уровень. «1» — во время ожидания на SCK присутствует высокий уровень.

Бит 2 — CPHA: фаза тактового сигнала. Если этот бит установлен в «1», то данные считываются по спадающему фронту SCK, если в «0» — по нарастающему фронту SCK.

Таким образом установкой этих бит мы можем выбирать один из четырех режимов работы шины SPI.

При соединении МК с каким-нибудь устройством, смотрите внимательно в документации на устройство режимы которые оно поддерживает. Ведущее и подчиненное устройства работающие в разных режимах не совместимы.

Биты 1:0 — SPR1:SPR0: скорость передачи (частота тактирования). Только для устройств в режиме ведущего. Если МК настроен на работу в качестве ведомого, установка этих бит не будет иметь никакого эффекта. В таблице ниже можно посмотреть какие значения нужно записать в эти биты, чтобы установить нужную скорость передачи (Бит SPI2X в регистре SPSR)

SPSR

Бит 7 — SPIF: флаг прерывания. Устанавливается по завершении передачи. Прерывание генерится если установлен бит SPIE регистра SPCR и бит I регистра SREG.

Бит 6 — WCOL: флаг коллизий записи. Устанавливается в «1» при попытке записи в регистр SPDR до окончания передачи.

Бит 0 — SPI2X: бит двойной скорости SPI. Если SPI сконфигурирован как ведущий, тогда мы можем работать с двойной частотой. Но если SPI сконфигурирован как ведомый, то мы не можем расчитывать на двойную скорость работы SPI.

Теперь рассмотрим пример инициализации МК, как мастера и функцию передачи байта.

#define DDR_SPI DDRB
#define DD_MOSI 3
#define DD_MISO 4
#define DD_SCK 5
#define SPE 6
#define MSTR 4
#define SPR0 0
#define SPIF 7
void SPI_MasterInit()
{
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);//настраиваем на выход
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);//вкл SPI, ведущий, частота fck/16
}
//функция передачи байта
void SPI_MasterTransmit(char cData)
{
SPDR = cData;//начинаем передачу
while(!(SPSR & (1<<SPIF)));//ждем пока передача завершится
}

Ну и чтобы, не лазать лишний раз в даташитsmile функции инициализации МК ведомым и функция приема байта.

void SPI_SlaveInit()
{
DDR_SPI = (1<<DD_MISO);//настраиваем на выход MISO, остальные на вход
SPCR = (1<<SPE);//включаем SPI
}
//функция приема байта
char SPI_SlaveReceive()
{
while(!(SPSR & (1<<SPIF)));//ждем если занят
return SPDR;//возвращаем байт данных
}

Вектор прерывания в WinAVR записывается так — SPI_STC_vect. Если хотим использовать прерывания, тогда должны установить соответствующие биты в регистрах и вызвать обработчик прерывания

ISR(SPI_STC_vect)
{}

Интерфейс SPI может быть реализован программно на любых ножках МК, но лучше пользоваться встроенным в МК.

Как вам статья? Ваша реакция:
+1
0
+1
0
+1
0
+1
0
+1
0
+1
0
Расскажите друзьям:
Оцените статью:

5 комментариев

  • «Найдите ошибку пожалуйста. Два микроконтроллера по SPI atmega8

    Один предает число другой принимает и виводит в порт Д

    1 контроллер код

    #include

    #define F_CPU 4000000L

    #include

    #define DDR_SPI DDRB

    #define DD_SS 2

    #define DD_MOSI 3

    #define DD_MISO 4

    #define DD_SCK 5

    #define SPE 6

    #define MSTR 4

    #define SPR0 0

    #define SPIF 7

    void SPI_MasterInit()

    {

    DDR_SPI = (1»

  • А как быть, если нужно передать(точнее считать с ведомого ус-ва) за раз не 8 а 12 бит?

  • за раз не получится. микроконтроллер 8ми битный и работает с 8-ми битными данными(( можно передать за два раза и потом собрать два бита в нужную величину используя побитовые операции

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