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

Просмотров: 57780Комментарии: 5
Электроника. Схемотехника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 может быть реализован программно на любых ножках МК, но лучше пользоваться встроенным в МК.

Комментариев: 5 RSS

1 Аноним 18-08-2011 21:04

Найдите ошибку пожалуйста. Два микроконтроллера по 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

2 Андрей 23-01-2012 02:17

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

3 Dmitry 23-01-2012 03:17

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

4 damir 23-04-2012 06:10

спасибо за статью! то, что нужно!

5 Аноним 20-09-2012 19:23

отлично написано пример опробывал вродибы работает спасибо!

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

grin LOL cheese smile wink smirk rolleyes confused surprised big surprise tongue laugh tongue rolleye tongue wink raspberry blank stare long face ohh grrr gulp oh oh downer red face sick shut eye hmmm mad angry zipper kiss shock cool smile cool smirk cool grin cool hmm cool mad cool cheese vampire snake excaim question

Используйте нормальные имена. Ваш комментарий будет опубликован после проверки.

Вы можете войти под своим логином или зарегистрироваться на сайте.

(обязательно)