Интерфейс SPI (Serial Peripheral Bus)

При загрузке значения в регистр данных 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.

SPSR

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

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

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


Код программы разработки драйвера MAX5400 в трех частях.

//-------------------------1.c---------------------------
// Target: M16
// Crystal: 10.000Mhz
//---------------------------------------------------------------------
#include <iom16v.h>
#include <macros.h>
#include <delay.h>
#include "def.h"
#include "init.h"

void main(void)
{
init_devices(); //Ініціалізація мікроконтролера
//--------------------------
while (1) //Головний цикл
{
Data1270=DRVstatusR1W0 (0, AC, 0x1FFABC);

}
}

//---------------------------def.h----------------------
#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

//spi pins

#define CS (1<<4)

#define DIN (1<<5)

#define SCK (1<<7)


//---------------------------------------------------------------------------


//-------------------------init.h-------------------------
void
port_init(void)
{
PORTA = 0x00;
DDRA = 0xFF;
PORTB = 0x00;
DDRB = 0xFF;
PORTC = 0x00; //m103 output only
DDRC = 0xFF;
PORTD = 0x00;
DDRD = 0x00;
}


//---------------------------delay.h-----------------------
void
DelayMcs (unsigned int t_mcs)
{ while (t_mcs--)
{
asm("nop");
asm("nop");
asm("nop");
asm("nop");
}
}
//--------------------------------------------------------------------------
//Функция задержки на "t_ms" милисекунд
void DelayMs (unsigned int t_ms)
{ while (t_ms--)
{
DelayMcs(1000);
}
}
//Функция задержки на "t_s" секунд
void DelayS (unsigned int t_s)
{ while (t_s--)
{
DelayMs(1000);
}
}

#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)));//ждем пока передача завершится

}




Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: