|
| |||||||
|
Опубликовано 2010-05-19 14:51:13 автором Admin Передача даних через SPI в AVR. Урок AVR 10Інтерфейс SPI широко застосовується для обміну даними в мікроконтролерній техніці, і , напевно, найпопулярніший на сьогоднішній день з послідовних інтерфейсів. Основні характеристики SPI це простота використання , невелика довжина передавальних проводів і висока швидкість передачі даних. У мікроконтролері atmega8 spi реалізований апаратно , саме його ми використовуємо для запису прошивки в мк . Особливість SPI полягає в тому, що є одне ведуче (Master) і одне або декілька ведених ( Slave) Розглянемо приклад передачі даних між двома мікроконтролерами , перший буде ведучий другий ведений .
тут :
Давайте зробимо передачу даних між двома мікроконтролерами . Завдання майстра послати дані , задача слейв прийнять їх і включити або виключити світлодіод Схема підключення в proteuse така : Майстер
# 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
# 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 )
{
} ;
}
Ось що вийшло
Я згадував, що до одного майстра можна підключити багато слейв , давайте реалізуємо це завдання. Задача: Майстер передає число спочатку першому слейв , слейв залежно від від переданого числа - нуль або одиниця - включає або вимикає світлодіод , потім майстер перемикається на слейв 2 (щоб включити потрібний slave , master на його ніжці ss встановлює логічний 0 . Таким чином слейв знає, що спілкування йде саме з ним. По завершенню сеансу передачі даних майстер встановлює на лінії ss логічну 1 ) . Схема в цьому випадку буде виглядати наступним чином Прошивкадля майстра нам прийдеться трохи модифікувати прошивку з першого прикладу. У прошивку потрібно додати перемикання слейв .
# 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 ;
} ;
}
Запускаємо , і дивимося
Вам як домашнє завдання: зробіть, щоб слейв виводив передані дані на lcd Комментарии - (0) Добавить комментарийДля отправки комментария вы должны авторизоваться. |
|||||||