Print this page

Учебный курс AVR. Работа с SPI модулем. Чтение и запись данных. Ч2

22/10/2012 - 17:23 Павел Бобков

   Теперь вы имеете общее представление о последовательном периферийном интерфейсе и можно перейти к рассмотрению SPI модуля. 
   SPI модуль микроконтроллера AVR atmega16 использует для своей работы 4 вывода - MOSI, MISO, SCK и SS. Когда модуль не задействован, эти выводы являются линиями портов ввода/вывода общего назначения. Когда модуль включен, режим работы этих выводов переопределяются согласно следующей таблице.

 
   Если к микроконтроллеру подключено больше одного периферийного устройства, в качестве дополнительных выводов выбора (SS), можно использовать любые выводы общего назначения. При этом штатный вывод SS должен быть всегда правильно сконфигурирован, даже если он не используется.

Регистры SPI модуля

   В микроконтроллере atmega16 для работы с модулем SPI используются три регистра:

- управляющий регистр SPCR,
- статусный регистр SPSR, 
- регистр данных SPDR.

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

   Кофигурация модуля SPI устанавливается с помощью регистра SPCR (SPI Control Register).




SPIE – разрешает /запрещает прерывания от модуля SPI. Если бит установлен в 1, прерывания от SPI разрешены. 

SPE – включает/выключает модуль SPI. Если бит установлен в 1, модуль SPI включен.

DORD – определяет порядок передачи данных. Когда бит установлен в 1, содержимое регистра данных передается младшим битом вперед. Когда бит сброшен, то старшим битом вперед.

MSTR – определяет режим работы микроконтроллера. Если бит установлен в 1, микроконтроллер работает в режиме Master (ведущий). Если бит сброшен – в режиме Slave (ведомый). Обычно микроконтроллер работает в режиме master.

CPOL и CPHA – определяют в каком режиме работает SPI модуль. Требуемый режим работы зависит от используемого периферийного устройства.


SPR1
и SPR0 – определяют частоту тактового сигнала SPI модуля, то есть скорость обмена. Максимально возможная скорость обмена всегда указывается в спецификации периферийного устройства.


   Статусный регистр SPSR (SPI Status Register) предназначен для контроля состояния SPI модуля
, кроме того он содержит дополнительный бит управления скоростью обмена.


SPIF
– флаг прерывания от SPI. Он устанавливается в 1 по окончании передачи байта данных. Если разрешены прерывания модуля, одновременно с установкой этого флага генерируется прерывание от SPI. Также этот флаг устанавливается в 1 при переводе микроконтроллера из режима master в режим slave с помощью вывода SS.
   Сброс флага происходит аппаратно, при вызове подпрограммы обработки прерывания или после чтения регистра SPSR с последующим обращением к регистру данных SPDR.

WCOL- флаг конфликта записи. Флаг устанавливается в 1, если во время передачи данных выполняется попытка записи в регистр данных SPDR. Флаг сбрасывается аппаратно после чтения регистра SPSR с последующим обращением к регистру данных SPDR.

SPI2X — бит удвоения скорости обмена. Установка этого разряда в 1 удваивает частоту тактового сигнала SCK. Микроконтроллер при этом должен работать в режиме master.

Взаимосвязь между битами SPR0, SPR1, SPI2X и частотой тактового сигнала SCK показана в таблице. 


Где Fosc — тактовая частота микроконтроллера AVR.


   Для передачи и приема данных предназначен регистр SPDR (SPI Data Register)
. Запись данных в этот регистр инициирует передачу данных SPI модулем. При чтении этого регистра, считывается содержимое буфера сдвигового регистра SPI модуля.

   Программный код

   Минимальный программный код для работы с SPI модулем состоит из двух функций:

- функции инициализации.
- функции передачи/приема байта данных

   Инициализация SPI модуля

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


#define SPI_PORTX PORTB
#define SPI_DDRX DDRB

#define SPI_MISO 6 
#define SPI_MOSI 5
#define SPI_SCK 7
#define SPI_SS 4

/*инициализация SPI модуля в режиме master*/
void SPI_Init(void)
{

   /*настройка портов ввода-вывода
   все выводы, кроме MISO выходы*/
   SPI_DDRX |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(0<<SPI_MISO);
   SPI_PORTX |= (1<<SPI_MOSI)|(1<<SPI_SCK)|(1<<SPI_SS)|(1<<SPI_MISO);

   /*разрешение spi,старший бит вперед,мастер, режим 0*/
   SPCR = (1<<SPE)|(0<<DORD)|(1<<MSTR)|(0<<CPOL)|(0<<CPHA)|(1<<SPR1)|(0<<SPR0);
   SPSR = (0<<SPI2X);
}

   Передача/прием данных

   Процесс передачи/приема данных с помощью SPI модуля, работающего в режиме Master, состоит из следующей последовательности действий:

1. установка низкого логического уровня на линии SS
2. загрузка данных в регистр SPDR
3. ожидание окончания передачи (проверка флага SPIF)
4. сохранение принятых данных (чтение SPDR), если требуется
5. возврат на 2-ой шаг, если переданы не все данные
6. установка высокого логического уровня на линии SS

  Ниже приведено несколько вариантов функции передачи/приема данных.

  Передача одного байта данных по SPI


void SPI_WriteByte(uint8_t data)
{
   SPI_PORTX &= ~(1<<SPI_SS);
   SPDR = data;
   while(!(SPSR & (1<<SPIF)));
   SPI_PORTX |= (1<<SPI_SS); 
}


   Передача и прием одного байта данных по SPI


uint8_t SPI_ReadByte(uint8_t data)
{
   uint8_t report;
   SPI_PORTX &= ~(1<<SPI_SS);
   SPDR = data;
   while(!(SPSR & (1<<SPIF)));
   report = SPDR;
   SPI_PORTX |= (1<<SPI_SS); 
   return report; 
}


   Передача нескольких байтов данных по SPI 
*data – указатель на массив передаваемых данных, а num – размерность массива


void SPI_WriteArray(uint8_t num, uint8_t *data)
{
   SPI_PORTX &= ~(1<<SPI_SS); 
   while(num--){
      SPDR = *data++;
      while(!(SPSR & (1<<SPIF)));
   }
   SPI_PORTX |= (1<<SPI_SS); 
}

...

//Пример использования:
uint8_t buf[3] = {12, 43, 98};


SPI_WriteArray(3, buf);


   Передачи и прием нескольких байтов данных по SPI
*data – указатель на массив передаваемых данных, а num – размерность массива.
Принятые данные будут сохраняться в том же массиве.


void SPI_ReadArray(uint8_t num, uint8_t *data)
{
   SPI_PORTX &= ~(1<<SPI_SS); 
   while(num--){
      SPDR = *data;
      while(!(SPSR & (1<<SPIF)));
      *data++ = SPDR; 
   }
   SPI_PORTX |= (1<<SPI_SS); 
}

Файлы

   Простой SPI драйвер, в котором сведены все описанные выше функции - AVR_SPI_driver.rar

Остальные части

   Учебный курс AVR. Работа с модулем SPI. Ч1
   Учебный курс AVR. Работа с SPI. Управление сдвиговым регистром. Ч3

Related items