Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





При работе с большинством устройств через SPI, к сожалению, этой простой процедурой дело не ограничивается — чаще всего требуется, по крайней мере, вовремя правильно установить "выбор кристалла", причем иногда (если интерфейс у ведомого устройства недостаточно скоростной) с формированием искусственных задержек и прочими сложностями, сильно загромождающими программу.

Подробности
Если используется аппаратный SPI, то его выводы, как мы не раз говорили, в большинстве случаев совпадают с последовательным интерфейсом программирования. Если разъем для программирования установлен прямо в схеме, то я рекомендовал устанавливать внешние "подтягивающие" резисторы для повышения помехоустойчивости. В подавляющем большинстве случаев наличие этих резисторов никак не скажется на работе SPI. Однако следует учитывать, что формируя выводы MISO и SCK на выход и оставляя на них низкий уровень (как в режиме 0), тем самым мы обеспечим дополнительное потребление через "подтягивающие" резисторы на этих выводах, что может быть важно в устройствах с энергосберегающими режимами. В некоторых случаях наличие резистора на выводе MISO необходимо — например, если ведомое устройство работает от питания 2,7 В, а МК— от 5 В, то уровня лог. 1 на этом выводе может не хватить для нормальной работы МК, и резистор поможет решить эту проблему (кстати, МК семейства х51 этого недостатка лишены). Однако в таком случае неизбежна утечка через этот резистор и ограничивающий диод на входе ведомого устройства. По всем этим причинам в аппаратуре с применением режимов энергосбережения устанавливать "подтягивающие" резисторы по выводам SPI не рекомендуется (как и во многих других случаях, когда выводы программирования служат обычными портами на выход).

В процессе обмена возможны и прерывания SPI, но хотя это и разгрузит контроллер на время посылки байта, но менее удобно: сильно усложняется логика построения программы. Прерывание возникает всякий раз, когда заканчивается передача очередного байта, а связанные с этой передачей действия существенно различаются, и обработчик прерывания состоял бы из сплошной "лапши" условных переходов. В доступной литературе я ни разу не встречал примеров с реализацией прерывания SPI, ни на С, ни на ассемблере, т. к. обычная последовательная процедура куда проще в отладке — учитывая особенно, что в протоколе обмена по SPI с конкретными устройствами сама по себе посылка-прием байта протекает быстро, и в большинстве случаев еще не самое главное в программе, т. к. бывает обставлена всякими дополнительными условиями.

Программный вариант
Программный вариант процедур чтения-записи более громоздок, но зато позволяет задействовать любые удобные выводы портов МК (в том числе и таких, которые вообще аппаратного SPI не имеют) и не требует особой инициализации, кроме формирования направления работы соответствующих выводов. Листинг 11.5 иллюстрирует, как будет выглядеть чтение-запись в варианте, соответствующем режиму 0.

Листинг 11.5
.equ CS = 0 /выводы PortB .equ MOSI = 1 .equ MISO = 2 .equ SCK ='3
/инициализация SPI
/установка MOSI, SCK, CS на выход
ldi temp, (1«CS) I (l«MOSI) | (1«SCK)
out DDRB,temp
cbi PORTB,SCK
cbi PORTB,MOSI
sbi PORTB,CS
/чтение-запись
RW_spi: /запись/чтение через SPI посылаемый байт в data_out, /принимаемый в data_in cli /на случай, если в программе есть длинные прерывания, /иначе можно удалить ldi temp,8 ;счетчик бит
clr data_in spi_loop:
lsl data_out /старший бит в перенос
1эгсс put_0 /если в переносе 0 — перейти
sbi PORTB,mosi
пор ./задержка на один такт
rjmp r_bit put_0:
cbi PORTB,mosi
nop /задержка на один такт r_bit:
sbi PORTB,sck /выдали строб и подождали nop ;задержка на один такт sbic PINB,miso /читаем бит с miso rjmp rl_bit
clc /если 0 — сбросим перенос rjmp rend_bit rl_bit:
sec /если 1 — установим перенос *rend_bit:
rol data_in /перенос во входной байт cbi PORTB,sck /выдали строб и подождали пор dec temp
brne spi_loop sei /если команды cli нет, то тоже можно удалить ret



     
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru