SPI-интерфейс

 

В состав всех AVR-входит модуль SPI-интерфейса. Он предназначен для подключения различного периферийного оборудования (АЦП, ЦАП, микросхемы flash-памяти) в данной статье описывается программирование этого модуля а также приведены  примеры односторонней  и двусторонней предачи данных между двумя микроконтроллерами. 

 

 

блок-схема модуля интерфейса SPI

 

 

Рис.1 блок-схема модуля интерфейса SPI

 

Для настройки интерфейса необходимо сконфигурировать три регистра – SPI STATUS REGISTER (SPSR), SPI CONTROL REGISTER (SPCR), и SPI Data Register (SPDR).

 

SPI CONTROL REGISTER (SPCR):

 

SPI CONTROL REGISTER

 

Бит 7 – SPIE: SPI Interrupt Enable,

Этот бит разрешает прерывания от SPI, если будет установлен SPIF в регистре  SPSR, и бит I в регистре SREG (общее разрешение прерываний), будет вызвана продпрограмма обработки прерывание  SPI_STC .

            -0 прерывания запрещены

-1 – разрешение прерывания.

Бит 6 – SPE: SPI Enable

Этот бит разрешает работу SPI,

            -0 в этом разряде означает запрет любых операций в SPI

-1 в этом разряде – разрешение работы.

Бит 5 – DORD: DORD: Data Order
Этот бит определяет порядок передачи данных,

            -0 в этом разряде – сначала будет передаваться младший разряд

            -1 в этом разряде – сначала будет передаваться старший разряд.

Бит 4 – MSTR: Master/Slave Select

Этот бит определяет режим работы модуля,

-1 в этом разряде – режим ведущего

-0 в этом разряде – режим ведомого.

Следующие 4 разряда определяют параметры тактового сигнала

Бит 3 – CPOL: Clock Polarity

Полярность сигнала синхронизации,

            -1 в этом разряде – тактовый сигнал в состоянии ожидания  - 1

-0 в этом разряде – тактовый сигнал в состоянии ожидания  - 0

CPOL

Передний фронт

Задний фронт

0

Нарастающий

Спадающий

1

Спадающий

Нарастающий

 

Бит2 -  CPHA: Clock Phase

Фаза сигнала синхронизации – определяет, по какому фронту будет производиться установка (выборка) - по переднему или заднему,

            -1 в этом разряде – установка (выборка) по переднему фронту

-0 в этом разряде – установка (выборка) по заднему фронту

CPHA

Передний фронт

Задний фронт

0

Выборка

Установка

1

Установка

Выборка

Биты  1, 0 – SPR1, SPR0: SPI Clock Rate Select 1 and 0

Соместно с  битом  SPI2x в регистре SPSR задают скорость передачи данных

 

SPI2X

SPR1

SPR0

Частота SCK

0

0

0

fosc /4

0

0

1

fosc /16

0

1

0

fosc /64

0

1

1

fosc /128

1

0

0

fosc /2

1

0

1

fosc /8

1

1

0

fosc /32

1

1

1

fosc /64

 

SPI STATUS REGISTER (SPSR).

 

SPI STATUS REGISTER

 

  

Бит 7 – SPIF: SPI Interrupt Flag

Флаг завершения передачи - устанавливается после завершения передачи (приема)  и вызывает прерывание (как у ведущего, так и у ведомого). В вызванном прерывании можно считывать и  записывать новые данные для передачи. Сбрасывается автоматически при входе в подпрограмму обработки прерывания.

Бит6 – WCOL: Write COLlision flag

Флаг наложения записи – устанавливается при чтении либо записи данных при незавершенной передаче. Автоматически сбрасывается чтением регистра SPSR а также при чтении (записи) в регистр данных (SPDR).

Бит0 – SPI2X: Double SPI Speed Bit

Соместно с  битами  SPR1 и  SPR0 в регистре SPСR задает скорость передачи данных, при его установки скорость работы SPI (частота SCK) удвоится, если SPI находится в режиме ведущего. Это означает, что минимальный период SCK будет равен двум периодам fosc. Если SPI работает как ведомый, то работа SPI гарантирована только на частоте fosc /4 или менее.

SPI Data Register – SPDR

 

SPI Data Register

 

 

Регистр данных SPI, запись в данный регистр инициирует передачу данных. При чтении данного регистра фактически считывается содержимое приемного буфера сдвигового регистра.

 

Режимы передачи данных

Комбинация бит CPHA и CPOL задает четыре возможных режима последовательной передачи данных. Форматы передачи данных для SPI представлены в таблице 73, а их временные диаграммы показаны на рис. 77 и 78. Биты данных выводятся сдвигом и фиксируются на входе противоположными фронтами синхросигнала SCK, тем самым гарантируя достаточное время на установление сигналов данных. Таким образом, можно обобщить информацию из табл. 70 и 71 и представить ее в следующем виде:

 

 

Передний фронт

Задний фронт

Режим SPI

CPOL = 0, CPHA = 0

Выборка нарастающим фронтом

Установка данных падающим фронтом

0

CPOL = 0, CPHA = 1

Установка данных нарастающим фронтом

Выборка падающим фронтом

1

CPOL = 1, CPHA = 0

Выборка падающим фронтом

Установка данных нарастающим фронтом

2

CPOL = 1, CPHA = 1

Установка данных падающим фронтом

Выборка нарастающим фронтом

3

   

 

 

 

 

  

Для нормального подключения необходимо:

Для ведущего настроить MOSI, SCL, SS на выход, MISO на вход.

Для ведомого настроить MOSI, SCL, SS на выход, MISO на выход.

При соединении одноименные выводы подключаются друг к другу

 

 

интерфейс SPI

 

  

1.      Примеры программ для обмена данными по SPI.

В данных примерах рассмотрен примеры одностороннего и двустороннего обмена данными .

Работа программ смоделирована в программе PROTEUS 7.5.

 

 

 

 

 

 

Программа ведущего (MASTER):

.include "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m8def.inc"

rjmp RESET ; Reset Handler

reti;rjmp EXT_INT0 ; IRQ0 Handler

reti;rjmp EXT_INT1 ; IRQ1 Handler

reti;rjmp TIM2_COMP ; Timer2 Compare Handler

reti;rjmp TIM2_OVF ; Timer2 Overflow Handler

reti;rjmp TIM1_CAPT ; Timer1 Capture Handler

reti;rjmp TIM1_COMPA ; Timer1 CompareA Handler

reti;rjmp TIM1_COMPB ; Timer1 CompareB Handler

reti;rjmp TIM1_OVF ; Timer1 Overflow Handler

reti;rjmp TIM0_OVF ; Timer0 Overflow Handler

rjmp SPI_STC ; SPI Transfer Complete Handler

reti;rjmp USART_RXC ; USART RX Complete Handler

reti;rjmp USART_UDRE ; UDR Empty Handler

reti;rjmp USART_TXC ; USART TX Complete Handler

reti;rjmp ADC ; ADC Conversion Complete Handler

reti;rjmp EE_RDY ; EEPROM Ready Handler

reti;rjmp ANA_COMP ; Analog Comparator Handler

reti;rjmp TWSI ; Two-wire Serial Interface Handler

reti;rjmp SPM_RDY ; Store Program Memory Ready Han

 

reset:

ldi r16,(1<<PB3)+(1<<PB5)+(1<<PB2)

out ddrb,r16      ;mosi, SS and sck is output

 

ldi r16,(1<<PB2)

out portb,r16

 

ldi r16,255

out portd,r16     ;input port (key) with pull-up res

 

ldi r16,(1<<spie)+(1<<spe)+(1<<mstr)

out spcr,r16      ;spi enableand, spi int. enable, master mode

 

 

ldi r16,high(RAMEND)

out SPH,r16      ;Set Stack Pointer to top of RAM

ldi r16,low(RAMEND)

out SPL,r16

sei                               ;Enable interrupts

 

rcall spi_transmit

 

main:

inc r17

cpi r17,255

brne main

;rcall spi_transmit

;ldi r16,(1<<PB2)

;out portb,r16    ;ss pin->0

rjmp main                     ;Main program start

 

SPI_STC:

;ldi r16,(1<<spie)+(1<<spe)+(1<<mstr)

;out spcr,r16     ;spi enableand, spi int. enable, master mode

 

in r16,pind                    ;read keyport

out spdr,r16      ;spi data transmitter write

reti

 

spi_transmit:

ldi r16,(1<<spie)+(1<<spe)+(1<<mstr)

out spcr,r16      ;spi enableand, spi int. enable, master mode

 

in r16,pind                    ;read keyport

out spdr,r16      ;spi data transmitter write

 

ldi r16,(0<<PB2)

out portb,r16     ;ss pin->0

ret

 

Программа ведомого (SLAVE):

 

.include "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m8def.inc"

rjmp RESET ; Reset Handler

reti;rjmp EXT_INT0 ; IRQ0 Handler

reti;rjmp EXT_INT1 ; IRQ1 Handler

reti;rjmp TIM2_COMP ; Timer2 Compare Handler

reti;rjmp TIM2_OVF ; Timer2 Overflow Handler

reti;rjmp TIM1_CAPT ; Timer1 Capture Handler

reti;rjmp TIM1_COMPA ; Timer1 CompareA Handler

reti;rjmp TIM1_COMPB ; Timer1 CompareB Handler

reti;rjmp TIM1_OVF ; Timer1 Overflow Handler

reti;rjmp TIM0_OVF ; Timer0 Overflow Handler

rjmp SPI_STC ; SPI Transfer Complete Handler

reti;rjmp USART_RXC ; USART RX Complete Handler

reti;rjmp USART_UDRE ; UDR Empty Handler

reti;rjmp USART_TXC ; USART TX Complete Handler

reti;rjmp ADC ; ADC Conversion Complete Handler

reti;rjmp EE_RDY ; EEPROM Ready Handler

reti;rjmp ANA_COMP ; Analog Comparator Handler

reti;rjmp TWSI ; Two-wire Serial Interface Handler

reti;rjmp SPM_RDY ; Store Program Memory Ready Han

 

reset:

ldi r16,(1<<pb4)

out ddrb,r16      ;miso is out

ldi r16,(1<<pb2)

out portb,r16     ;pull-up for ss

ldi r16,255

out ddrd,r16      ;output port (led)

 

ldi r16,(1<<spie)+(1<<spe)

out spcr,r16      ;spi enable and spi int. enable

 

ldi r16,high(RAMEND)

out SPH,r16                 ; Set Stack Pointer to top of RAM

ldi r16,low(RAMEND)

out SPL,r16

sei                               ; Enable interrupts

 

main:

rjmp main                     ; Main program loop

 

SPI_STC:

in r16,spdr                    ;read data register

out portd,r16                 ;and out to led port

reti

 

 

 

 

 

 

.include "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m8535def.inc"

rjmp RESET ; Reset Handler

reti; rjmp EXT_INT0 ; IRQ0 Handler

reti; rjmp EXT_INT1 ; IRQ1 Handler

reti; rjmp TIM2_COMP ; Timer2 Compare Handler

reti; rjmp TIM2_OVF ; Timer2 Overflow Handler

reti; rjmp TIM1_CAPT ; Timer1 Capture Handler

reti; rjmp TIM1_COMPA ; Timer1 Compare A Handler

reti; rjmp TIM1_COMPB ; Timer1 Compare B Handler

reti; rjmp TIM1_OVF ; Timer1 Overflow Handler

reti; rjmp TIM0_OVF ; Timer0 Overflow Handler

rjmp SPI_STC ; SPI Transfer Complete Handler

reti; rjmp USART_RXC ; USART RX Complete Handler

reti; rjmp USART_UDRE ; UDR Empty Handler

reti; rjmp USART_TXC ; USART TX Complete Handler

reti; rjmp ADC ; ADC Conversion Complete Handler

reti; rjmp EE_RDY ; EEPROM Ready Handler

reti; rjmp ANA_COMP ; Analog Comparator Handler

reti; rjmp TWSI ; Two-wire Serial Interface Handler

reti; rjmp EXT_INT2 ; IRQ2 Handler

reti; rjmp TIM0_COMP ; Timer0 Compare Handler

reti; rjmp SPM_RDY ; Store Program Memory Ready Handler

 

reset:

ldi r16,(1<<PB4)+(1<<PB5)+(1<<PB7)

out ddrb,r16      ;mosi, SS and sck is output

 

ldi r16,255

out portd,r16     ;input port (key) with pull-up res

out ddrc,r16      ;portc is ledport is out

 

ldi r16,(1<<spie)+(1<<spe)+(1<<mstr)

out spcr,r16      ;spi enableand, spi int. enable, master mode

 

;in r16,pind        ;read keyport

;out spdr,r16     ;spi data transmitter write

 

ldi r16,high(RAMEND)

out SPH,r16      ;Set Stack Pointer to top of RAM

ldi r16,low(RAMEND)

out SPL,r16

sei                               ;Enable interrupts

 

 

 

ldi r16,(1<<PB4);ss->1

out portb,r16

 

 

ldi r16,(1<<spie)+(1<<spe)+(1<<mstr)

out spcr,r16      ;master mode

 

main:

inc r17

cpi r17,255

breq spi_transmit

rjmp main                     ;Main program start

 

delay:

inc r18

brne delay

ret

 

SPI_STC:

 

in r16,spdr

out portc,r16

 

reti

 

 

spi_transmit:

ldi r17,0

 

 

in r16,pind                    ;read keyport

out spdr,r16      ;spi data transmitter write

 

ldi r16,(0<<PB4)

out portb,r16     ;ss pin->0

 

 

rjmp main

.include "C:\Program Files\Atmel\AVR Tools\AvrAssembler2\Appnotes\m8535def.inc"

rjmp RESET ; Reset Handler

nop;      rjmp EXT_INT0 ; IRQ0 Handler

nop; rjmp EXT_INT1 ; IRQ1 Handler

nop; rjmp TIM2_COMP ; Timer2 Compare Handler

nop; rjmp TIM2_OVF ; Timer2 Overflow Handler

nop; rjmp TIM1_CAPT ; Timer1 Capture Handler

nop;6 rjmp TIM1_COMPA ; Timer1 Compare A Handler

nop;0x007 rjmp TIM1_COMPB ; Timer1 Compare B Handler

nop;0x008 rjmp TIM1_OVF ; Timer1 Overflow Handler

nop;0x009 rjmp TIM0_OVF ; Timer0 Overflow Handler

rjmp SPI_STC ; SPI Transfer Complete Handler

nop;0x00B rjmp USART_RXC ; USART RX Complete Handler

nop;0x00C rjmp USART_UDRE ; UDR Empty Handler

nop;0x00D rjmp USART_TXC ; USART TX Complete Handler

nop;0x00E rjmp ADC ; ADC Conversion Complete Handler

nop;0x00F rjmp EE_RDY ; EEPROM Ready Handler

nop;0x010 rjmp ANA_COMP ; Analog Comparator Handler

nop;0x011 rjmp TWSI ; Two-wire Serial Interface Handler

nop;0x012 rjmp EXT_INT2 ; IRQ2 Handler

nop;0x013 rjmp TIM0_COMP ; Timer0 Compare Handler

nop;0x014 rjmp SPM_RDY ; Store Program Memory Ready Handler

 

reset:

ldi r16,(1<<pb6)

out ddrb,r16                  ;miso is out

 

;ldi r16,(1<<pb6)

;out portb,r16                ;pull-up for ss

 

ldi r16,255

out portd,r16                 ;pull-up for keyport

 

ldi r16,255

out ddrc,r16                  ;portc is ledport is out

 

ldi r16,(1<<spie)+(1<<spe)

out spcr,r16                  ;spi enable and spi int. enable

 

 

ldi r16,high(RAMEND)

out SPH,r16                  ; Set Stack Pointer to top of RAM

ldi r16,low(RAMEND)

out SPL,r16

sei                               ; Enable interrupts

 

main:

rjmp main                     ; Main program loop

 

SPI_STC:

 

in r16,spdr                    ;read data register

out portc,r16                 ;and out to led port

 

IN R16,PIND

out spdr,r16

 

;ldi r16,(1<<spie)+(1<<spe)

;out spcr,r16                 ;spi enableand and spi int. enable

 

reti

 

  Тексты программ и файлы PROTEUS.

 

 

Автор: Николай Матюшов