|
| |||||||
|
Опубликовано 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) Добавить комментарийДля отправки комментария вы должны авторизоваться. |
|||||||