Последовательный интерфейс SPI.
Последовательный интерфейс SPI обеспечивает синхронный ввод-вывод данных в последовательном формате через линии ввода-вывода порта В сигналами SCK (альтернативная функция линии ввода-вывода РВ7), MOSI (альтернативная функция линии РВ5), MISO (альтернативная функция РВ6), SS (альтернативная функция РВ4). Контроллер при обмене данными может работать в режиме ведущий (master) или ведомый (slave). Структурная схема, поясняющая алгоритмы работы интерфейса, приведена на рис.18. Этот же интерфейс используется для внутрисистемного программирования микроконтроллера с записью данных во флэш-память и ППЗУ.
SPI-master управляет обменом данных, формируя информационную 8-битовую последовательность на выходе MOSI, стробирующую выдачу данных последовательность тактовых импульсов на выходе SCK и одновременно может принимать на входе MISO 8-битовую последовательность, стробируемую импульсами SCK. Если РВ4 конфигурируется как выход (DDB4=1), сигнал SS не используется, и РВ4 может работать в стандартном режиме вывода. Если РВ4 конфигурируют как вход (DDB4=0), при SS=1 продолжается работа в режиме SPI-master; SS=0, поступающий от другого устройства должен рассматриваться как запрос на переход в режим SPI-slave для приема данных.
Рис. 18. Интерфейс SPI.
SPI-slave управляется последовательностью импульсов на входе SCK и принимает информационную 8-битовую последовательность, подаваемую на его вход MOSI. Параллельно с приемом данных по этим же стробирующим импульсам SCK может формироваться выходная информационная последовательность на выходе MISO. Для этого режима РВ4 должен конфигурироваться входом. При SS=0 реализуется режим SPI-slave, если SS=1, интерфейс переходит в пассивное состояние и перестает работать.
Для режима SPI-master конфигурирование порта В следующее: MISO -вход, MOSI - выход, SCK - выход, SS - вход (как вход используется только при необходимости), для режима SPI-slave: MISO - выход, MOSI - вход, SCK - вход, SS - вход (задается сигнал логического нуля для работы интерфейса). Обмен данными между SPI-master и SPI-slave производится по алгоритму кольцевого регистра сдвига (рис.18), по каждому такту SCK данные сдвигаются на один бит, после 8 тактов содержимое регистра-master и регистра-slave меняется местами. Соединение MOSI - MOSI обеспечивает передачу от SPI-master к SPI-slave, а соединение MISO - MISO используется при необходимости передачи данных в обратном направлении.
Управление интерфейсом SPI производится тремя регистрами файла регистров ввода-вывода: регистром данных - SPDR, регистром управления - SPCR, регистром состояния - SPSR. SPDR и SPCR программно доступны и для чтения, и для записи, SPSR доступен только для чтения.
SPDR служит для записи передаваемых данных и чтения данных, которые поступили в регистр сдвига. SPCR содержит 8 бит управления интерфейсом (слева в таблице символических имен старший бит).
Символические имена битов управления в регистре SPCR
SPIE - бит разрешения прерывания SPI, 0 запрещает прерывания.
SPE - бит разрешения работы; при 0 запрещены любые операции в SP1,
1 разрешает работу интерфейса.
DORD - при 1 первым передается младший бит слова данных,
при 0 -старший бит.
MSTR - при 1 определяется режим SPI-master, при 0 - режим SPI-slave.
Младшие 4 бита SPCR определяют параметры тактового сигнала
SCK:
CPOL - определяет пассивный уровень сигнала SCK в перерывах передачи данных, т.е. при 0 тактовый сигнал в пассивном состоянии интерфейса тоже нулевой.
СРНА - при 0 запись данных должна производиться каждым первым фронтом сигнала SCK после пассивного уровня, при 1 - каждым вторым фронтом сигнала после пассивного уровня.
SPR1 и SPR0 задают частоту сигнала SCK; коэффициент деления тактовой частоты микроконтроллера для интерфейса определяется этими битами следующим образом:
00 - коэффициент деления 4,
01- коэффициент деления 16,
10 - коэффициент деления 64,
11 - коэффициент деления 128.
В регистре SPSR используется только 2 старших бита. SPIF (бит 7) - флаг прерывания, WCOL (бит 6) - флаг коллизии. SPIF устанавливается в 1 после каждого цикла передачи данных или после отмены режима SPI-master сигналом SS и вызывает вектор прерывания SPI_STC (адрес вектора $00а), если бит SPIE=1 (разрешение прерывания в SPCR) и установлен флаг глобального прерывания I в регистре состояния SREG". Флаг прерывания очищается автоматически при вызове вектора прерывания SPI_STC либо одновременно с очисткой флага WCOL. Флаг коллизии устанавливается в случае чтения регистра SPDR в период передачи данных в SPI (некорректное чтение данных) и автоматически очищается одновременно с флагом SPIF после чтения регистра SPSR и последующего обращения к регистру SPDR.
Если биты в регистре управления SPCR для выбора необходимого режима заданы, запись байта данных в регистр SPDR контроллера в режиме SPI-master приводит к началу рабочего цикла интерфейса. SPI-master (рис.4) передает на MOSI данные, с входа MISO может записывать данные от SPI-slave и на выходе SCK формирует 8 импульсов, управляющих передачей байта данных. Под управлением этих же сигналов SCK SPI-slave (рис. 16) принимает данные с входа MOSI и может передавать из своего регистра SPDR данные на выход MISO.
После завершения рабочего цикла обмена данными контроллер, работающий в любом режиме, устанавливает флаг прерывания для вызова вектора прерывания SPI_STC. Подпрограмма обработки этого вектора должна выполнять операции доступа к регистрам SPI для реализации необходимых функций интерфейса. Например, чтение из SPDR поступивших в предыдущем цикле данных и запись в него новых данных для передачи в следующем цикле. К контроллеру SPI-master для обмена данными вместо второго контроллера может быть подключен и обычный регистр сдвига разрядности, соответствующей формату данных.
Таким образом, интерфейс SPI обеспечивает за один рабочий цикл и передачу байта данных из SPDR на выход, и запись в этот же регистр нового байта данных, поступивших на вход. Запуск рабочего цикла производится записью в SPI-master очередного байта данных в регистр SPDR.
7.1. Прикладная программа микроконтроллерного регулятора.
Программирование микроконтроллера начинается с внесения в ППЗУ при помощи программатора табулированных значений функции
, при помощи которых определяем знак нелинейного воздействия.Словесный алгоритм функционирования микроконтроллерного регулятора:
1. Инициализация и настройка МК на ввод сигналов x1 и x2.
Порт B на вывод.
2. Измеряем текущее значение x2
3. Проверяем условие
4. Измеряем значение x1
5. Если условие в пункте 3 ложно, переходим к пункту 8,
6. Проверяем условие
.7. Если оно истинно, то подаём на выход линейное управляющее воздействие и переходим к пункту 2
8. Считываем
и сравниваем с x19. Если
, то подаём на вывод нелинейное управляющее воздействие, иначе подаём его же, но с отрицательным знаком.10. Переход к пункту 2.
Листинг программы:
.NOLIST
.INCLUDE "8535def.inc"
.LIST
.CSEG
.org $000
rjmpreset;прерывание по reset
.org $00e
rjmpadc0 ;прерывание по завершению преобразования АЦП
.ORG$011
reset:ldi r16, low(RAMEND)
out SPL, r16
ldi r16, high(RAMEND)
outSPH, r16 ;определить в указателе стека адрес RAMENDldir16, 0b11111110
outadmux, r16;преобразовывать сигнал с первого выхода мультиплексора РА1
outDDRA, r16 ; определить все биты порта A на ввод
ldir16, 0b11111110
out portA, r16 ; определить пассивный высокий уровень сигнала для всех битов порта А
ser r16 ;установить все биты $ff в регистр r16
out DDRB, r16 ;порт B на вывод
ldi r16, 0b11001110
out adcsr, r16;инициализация АЦП
ldi r16, 0b00000110 ;инициализация записи в ППЗУ
out EECR, r16
ldi r16, 0b00000000 ;инициализация чтения из ППЗУ
out EECR, r16
sei ;флаг глобального разрешения прерываний
main:
nop
rjmpmain
adc0: ;подпрограмма обработки прерываний АЦП
inc r20
cpi r20, 1
brne adc1
in r17, ADCL ;занести младший байт кода результата преобразования АЦП в регистр r17
inr18, ADCH;занести старший байт кода результата преобразования АЦП в регистр r18
ldir16, 0b00000001
out admux, r16 ;преобразовывать сигнал с первого выхода мультиплексора РА0 x1
sbi adcsr, ADSC ;запустить АЦП для однократного преобразования
reti
adc1:
clr r20
in r21, ADCL ;занести младший байт кода результата преобразования АЦП в регистр r21
in r22, ADCH ;занести старший байт кода результата преобразования АЦП в регистр r22
ldi r23, 0b10110011
ldi r24, 0b01101011 ;занести С1
ldi r27, 0b00000110
ldir28, 0b11010101 ;занести С2
cpir28, r18 ;сравнить C2 и x2
brneu1;перейти если разность (C2-x2) отрицательная
cpir27, r17
brneu1
cpir22, r24 ;сравнить С1 и x1
brneu1;перейти если разность (С1-х1) отрицательная
cpir21, r23
brneu1
ldir16,0b0000001;загрузить U2 линейная зависимость
out PORTB, r16
reti
u1:
lsl r17