| |||||||
Опубликовано 2010-05-19 14:51:13 автором Admin Передача данных через SPI в AVR. Урок AVR 10Интерфейс SPI широко применяется для обмена данными в микроконтроллерной технике, и, наверное, самый популярный на сегодняшний день из последовательных интерфейсов. Основные характеристики SPI это простота использования, небольшая длина передающих проводов, и высокая скорость передачи данных. В микроконтроллер atmega8 spi реализован аппаратно, именно его мы используем для записи прошивки в мк. Особенность SPI заключается в том, что есть одно ведущее (Master) и одно или несколько ведомых (Slave) Рассмотрим пример передачи данных между двумя микроконтроллерами, первый будет ведущий, второй ведомый. здесь:
Схема подключения в proteuse такая: Здесь нам прийдется написать две прошивки - одну для мастера, другую для слейва. В CodeWizard AVR переходим во вкладку 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#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) Добавить комментарийДля отправки комментария вы должны авторизоваться. |