Опубликовано 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)

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

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