Содержание
Урок 1. Первый проект
Урок 2. Управление кнопками
Урок 3. Подключение LCD
Урок 4. Использование ШИМ
Урок 5. Таймеры
Урок 6.1. Статическая индикация
Урок 6.2. Динамическая индикация
Урок 7.1. Генерация звука
Урок 7.2. Генерация звука. Продолжение
Урок 8.1. Передача данных через UART
Урок 8.2. Передача данных через UART. Продолжение»
Урок 9. Передача данных через SPI
Урок 10. Изучение АЦП. Простой вольтметр
Урок 11. Получение синуса при помощи ШИМ
Урок 12. Измерение температуры
Урок 13. Внешние прерывания.
Урок 14. Использование отладчика
Урок 15.1. Управление инкрементальным энкодером
Урок 15.2. Управление громкостью, при помощи энкодера
Урок 16. Управление RGB светодиодом
Урок 17. Использование ИК
Урок 18.1. Знакомство с графическим дисплеем
Урок 18.2 Вывод изображения на графический дисплей
Урок 18.3 Вывод русскоязычного текста
Урок 19. Формирование сигнала, при помощи ЦАП (R2R)
Урок 20. Опрос матричной клавиатуры
Урок 21. Сторожевой таймер
Урок 22.1 Воспроизведение wav. Введение.
Урок 22.2 Воспроизведение wav. Продолжение.
Урок 23.1 Работа с внешней памятью
Урок 23.2 Работа с файловой системой Fat

spi_loДанный урок посвящен последовательному интерфейсу — SPI. Интерфейс позволяет передавать информацию между несколькими устройствами, не обязательно микроконтроллерами. Особенность заключается в том, что имеется одно ведущее устройство и одно или несколько ведомых. Так же интерфейс используется многими программаторами для прошивки микроконтроллеров.

SPI достаточно прост в использовании, рассмотрим пример, в котором используется один ведущий (master — босс :D) и два ведомых микроконтроллера (slave — работяги).

spi1

SCK — Тактовый сигнал. Используется для синхронизации данных.

MOSI — передатчик ведущего, приемник ведомого

MISO — приемник ведущего, передатчик ведомого

SS — выбор ведомого

Для того, чтобы ведомый 0 принимал команды, нужно на его вход SS подать логический 0. Тогда он будет знать, что общение идет именно с ним, ведомый 1 будет все игнорировать. Аналогично, чтобы «активировать» ведомого 1, нужно подать на его вход SS логический 0, а на вход SS ведомого 0 — логическую единицу. В таком случае слушать команды будет только ведомый 1.

В отличие от предыдущих уроков, здесь придется создать 2 прошивки. Задача ведущего: активировать ведомого 0, послать команду мигнуть светодиодом, переключиться на 1, снова послать команду мигнуть светодиодом, повторить. Задача ведомых принять команду и мигать светодиодом. Получится одна прошивка для ведущего, вторая для двух ведомых. Создаем проект, на закладке SPI для master настройки слева, для slave справа. Не забудьте поставить галочку SPI Interrupt у slave.

spi conf

Прошивка для ведущего будет выглядеть так:

#include <mega8.h>
#include <spi.h>
#include <delay.h>
 
void main(void)
{
// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=Out Func4=In Func3=Out Func2=Out Func1=Out Func0=Out
// State7=T State6=T State5=0 State4=T State3=0 State2=0 State1=1 State0=0
PORTB=0x02;
DDRB=0x2F;
 
PORTC=0x03;
DDRC=0x00;
 
// 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.2=0; //Переключаемся на ведомого 0
spi('1');  //Отсылаем ему 1, чтобы он включил светодиод 
delay_ms(100); //ждем
spi('0');  //Отсылаем ему 0, чтобы он выключил светодиод
delay_ms(100); //ждем
PORTB.2=1; //Делаем ведомого 0 не активным
 
PORTB.1=0; //Переключаемся на ведомого 1, далее по аналогии с 0
spi('1');
delay_ms(100);
spi('0');
delay_ms(100);
PORTB.1=1;
 
};
}

Для ведомых прошивка будет выглядеть так:

#include <mega8.h>
 
interrupt [SPI_STC] void spi_isr(void)
{
unsigned char data;
data=SPDR;    //читаем приходящие байты
if(data=='1') //если пришла 1, включить светодиод
{
PORTD=0xFF;
}
if(data=='0') //если пришел 0, выключить светодиод
{
PORTD=0x00;
}
 
}
 
void main(void)
{
PORTB=0x00;
DDRB=0x10;
 
PORTD=0x00;
DDRD=0xFF;
 
// 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, автоматически начнет исполняться код в прерывании.

В результате микроконтроллеры будут весело перемигиваться. Прошивки и файл протеуса тут
gg

 

46 комментариев: Урок 9. Передача данных через SPI в AVR микроконтроллерах

  • Идут 0 и 1 и идут они таким образом первая пачка допустим у вас 2 байта в двоичном коде указывает принимающему контроллеру сколько будет передано информации тоже в 1 и 0 и приняв эту переменную он в битах получит её.
    Можно увеличить количество контактов, будет больше передавать битов одновременно пачкой.

  • сейчас на стмках уже это есть аппаратное quadspi :)

  • Что-то я не понял…почему все в каких-то кавычках?передавать можно только символы что-ли?

  • Не стесняемся читаем http://avr-start.ru/?p=4557

  • Скажите пожалуйста как обращаться к памяти flash AVR если память больше 128кб,к примеру 256кб атмега2560.
    Ведь адрес обозначается как 16 бит,значит можно указать 0xffff число а это 65535 байт или
    64кб,Значит мы можем обратиться к 64кб младших байт и 64 кб старших байт всего 128 кб.
    а как к обращаться ко второй половине 256 кб ???

  • если я правильно понял суть проблемы в есть функции которые позволяют обращаться по 32битному адресу pgm_read_byte_far(address_long)

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Последние комментарии
  • Загрузка...
Архивы
Счетчик
Яндекс.Метрика