Опубликовано 2010-05-19 14:51:13 автором Admin

Передача данных через SPI в AVR. Урок AVR 10


Интерфейс SPI широко применяется для обмена данными в микроконтроллерной технике, и, наверное, самый популярный на сегодняшний день из последовательных интерфейсов. Основные характеристики SPI это простота использования, небольшая длина передающих проводов, и высокая скорость передачи данных. В микроконтроллер atmega8 spi реализован аппаратно, именно его мы используем для записи прошивки в мк. Особенность SPI заключается в том, что есть одно ведущее (Master) и одно или несколько ведомых (Slave) Рассмотрим пример передачи данных между двумя микроконтроллерами, первый будет ведущий, второй ведомый. схема SPI здесь:
  • SCK — Тактовый сигнал. Используется для синхронизации данных (на этом выводе master генерирует синхроимпульсы)
  • MOSI (Master Out, Slave In) — передатчик ведущего, приемник ведомого (по этому выводу master передаёт данные slave)
  • MISO (Master In, Slave Out) — приемник ведущего, передатчик ведомого (по этому выводу master принимает данные от slave)
  • SS (Slave Select) — выбор ведомого
Для начала передачи данных мастер должен установить на выводе SS ведомого логический 0. Таким образом, ведомый будет знать, что общение идет именно с ним, так как к одному ведущему можно подключить много ведомых схема SPI Давайте сделаем передачу данных между двумя микроконтроллерами. Задача мастера послать данные, задача слейва прийнять их и включить или выключить светодиод
Схема подключения в proteuse такая:
схема SPI Здесь нам прийдется написать две прошивки - одну для мастера, другую для слейва. В CodeWizard AVR переходим во вкладку SPI и выставляем все как показано на рисунке
Мастер
схема SPI уберем инициализацию неиспользуемых устройств и допишем код для передачи данных
	#include  <mega8.h > 
// SPI functions 
#include  <spi.h > 
 #include  <delay.h > 
void main(void) 
{ 
PORTB=0x00; 
DDRB=0x2C; 
 
// SPI initialization 
// SPI Type: Master 
// SPI Clock Rate: 125,000 kHz 
// SPI Clock Phase: Cycle Half 
// SPI Clock Polarity: Low 
// SPI Data Order: MSB First 
SPCR=0x52; 
SPSR=0x00; 
 
while (1) 
      { 
      delay_ms(100); 
       spi('1'); // отсылаем 1 чтобы ведомый включил светодиод 
        delay_ms(100);  // делаем задержку в 1 секунду 
        spi('0'); // отсылаем 0 чтобы ведомый выключил светодиод 
      }; 
} 
Слейв.
Для слейва нужно включить прерывания при приходе данных, ну и соответственно выбрать тип SPI
схема SPI
#include  <mega8.h > 
 
// SPI interrupt service routine 
interrupt [SPI_STC] void spi_isr(void) 
{ 
unsigned char data; 
data=SPDR; 
 if (data=='1') PORTC=0x01;   // если пришла 1,  то включить светодиод 
 else if   (data=='0')  PORTC=0x00; // если пришел 0,  то выключить светодиод 
}  
void main(void) 
{ 
// Port B initialization 
PORTB=0x00; 
DDRB=0x10; 
 
// Port C initialization 
PORTC=0x00; 
DDRC=0x01; 
 
// SPI initialization 
// SPI Type: Slave 
// SPI Clock Rate: 125,000 kHz 
// SPI Clock Phase: Cycle Half 
// SPI Clock Polarity: Low 
// SPI Data Order: MSB First 
SPCR=0xC2; 
SPSR=0x00; 
 
// Clear the SPI interrupt flag 
#asm 
    in   r30,spsr 
    in   r30,spdr 
#endasm 
 
// Global enable interrupts 
#asm("sei") 
 
while (1) 
      { 
      }; 
} 
 


Вот, что получилось

симуляция SPI в proteus

Я упоминал, что к одному мастеру можно подключить много слейвов. Давайте реализуем эту задачу.
Задача:
Мастер передает число сначала первому слейву, и слейв, в зависимости от переданного числа – «ноль» или «единица» включает или выключает светодиод, потом мастер переключается на слейв 2 (чтобы включить нужный slave, master на его ножке ss устанавливает логический «0». Таким образом, слейв знает, что общение идет именно с ним. По завершению сеанса передачи данных мастер устанавливает на линии ss логическую 1).
Схема в этом случае будет выглядеть следующим образом передача данных по SPI один master много slave
Прошивка
для мастера нам придется немного модифицировать прошивку из первого примера. В прошивку нужно добавить переключение слейвов.

#include  <mega8.h > 
// SPI functions 
#include  <spi.h > 
 #include  <delay.h > 
void main(void) 
{ 
PORTB=0x06; 
DDRB=0x2E; 
 
// SPI initialization 
// SPI Type: Master 
// SPI Clock Rate: 125,000 kHz 
// SPI Clock Phase: Cycle Half 
// SPI Clock Polarity: Low 
// SPI Data Order: MSB First 
SPCR=0x52; 
SPSR=0x00; 
 
while (1) 
      { 
      	PORTB.1=0; // Переключаемся на ведомого 1 
		spi('1');  // Отсылаем ему 1, чтобы он включил светодиод  
		delay_ms(100); // ждем 0.1 секунды  
		spi('0');  // Отсылаем ему 0, чтобы он выключил светодиод 
		delay_ms(100); // ждем 0.1 секунды 
		PORTB.1=1; // Делаем ведомого 1 не активным 
  
		PORTB.2=0; // Переключаемся на ведомого 2  
		//дальше все по аналогии 
		spi('1'); 
		delay_ms(100); 
		spi('0'); 
		delay_ms(100); 
		PORTB.2=1; 
      }; 
}

Запускаем, и смотрим
передача байт по SPI схема

Вам как домашнее задание: сделайте, чтобы слейв выводил переданные данные на lcd.

Комментарии - (0)

Добавить комментарий

Для отправки комментария вы должны авторизоваться.