Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: не работает SPI
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
skef
есть 2 мк ATMEGA8, необходимо организовать обмен данными между ними по SPI
CODE
.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)
out ddrb,r16 ;mosi and sck is output

ldi r16,255
out portd,r16 ;input port (key)

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

main:
rjmp main ;Main program start

SPI_STC:
ldi r16,(1<<mstr)
out spcr,r16 ;master mode

in r16,pind ;read keyport
out spdr,r16 ;spi data transmitter write
reti


и программа slave:

CODE
.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,255
out ddrd,r16 ;output port (led)

ldi r16,(1<<spie)+(1<<spe)
out spcr,r16 ;spi enableand 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 start

SPI_STC:
in r16,spdr
out portb,r16
reti


схема смоделирована в протеусе.
обмена данными нет, шины молчат...
может быть кто-нибудь подскажет, где я ошибся?
Злодей
Перывания SPI Transfer Complete не происходит, поскольку Transfer-а не было... Сделайте первую передачу после инициализации.

Мастер
Код
reset:
;...
sei;Enable interrupts

call SPI_STC;           <-- как-то так

main:
rjmp main;Main program start

SPI_STC:
ldi r16,(1<<mstr)
out spcr,r16;master mode

in r16,pind;read keyport
out spdr,r16;spi data transmitter write
reti;
skef
вставил. результат тот же.
еще в обработчике вместо

SPI_STC:
ldi r16,(1<<mstr)
out spcr,r16 ;master mode

вставил
SPI_STC:
ldi r16,(1<<spie)+(1<<spe)+(1<<mstr)
out spcr,r16;master mode

на шинах появились данные и синхронизация
УРА!!! передатчик работает!

а приемник нет.
аналогично добавил в обработчик приемника

SPI_STC:
ldi r16,(1<<spie)+(1<<spe)
out spcr,r16 ;spi enableand spi int. enable
in r16,spdr
out portb,r16
reti

а он все то же. и судя по симуляции он в прерывание вообще не заходит.
и еще... протеус сообщил у мастера write collision. мне кажется это со вставленным rcall SPI_STC связано...
V_G
А чипселект-то мастер дергает? SS называется в интерфейсе SPI. Он автоматом вроде как не обслуживается, самому надо!
skef
а в какой момент (в программе) мастер должен им дергать?
arttab
то ли мне не поглазам: где выдача данных от слейва?
V_G
Цитата(skef @ Nov 5 2009, 15:46) *
а в какой момент (в программе) мастер должен им дергать?

Перед посылкой мастер должен установить SS в 0 и не отпускать до окончания сеанса обмена. Я связку двух процев не использовал, а проц-флэш,модем и пр. периферия - очень много. В инструкции к периферии временные диаграммы всегда расписаны.
Да, и нужно помнить, что обменом всегда управляет мастер, т.е. он при приеме данных всегда посылает в spdr пустые данные, чтобы выдавался тактирующий сигнал.
skef
дописал

ldi r16,(1<<PB3)+(1<<PB5)+(1<<PB2)
out ddrb,r16 ;mosi, SS and sck is output

ldi r16,(0<<PB2)
out portb,r16 ;записать в SS 0,

результаты те же.

обмен данными пока односторонний, от slave ничего не идет.
V_G
Ножки SS у мастера и слейва, надеюсь, соединены?
А по ресету и вне обмена SS=1 ?
Можете ли отловить прерывание от приема данных в слейве?
А после перевода слейва в передачу тактируете ли ее мастером?

При тактировании мастером прерывание по приему данных должно возникнуть вне зависимости от того, послал слейв что-то, или нет. Просто приняты будут все нули или все единицы (в каком состоянии нога MISO).
skef
похоже слэйв в прерывание не входит.
в мастере в главном цикле заносится 1 в SS.
Злодей
Прикрепите, пожалуйста, проект.
skef
вот... пока так.
skef
и снова переписано...
мастер:
CODE
.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

in r16,pind ;read keyport
out spdr,r16 ;spi data transmitter write

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_STC;

main:
inc r17
cpi r17,255
breq spi_transmit
rjmp main ;Main program start

SPI_STC:


ldi r16,(1<<spie)+(1<<spe)+(1<<mstr)
out spcr,r16 ;master mode

reti


spi_transmit:

in r16,pind ;read keyport
out spdr,r16 ;spi data transmitter write

ldi r16,(0<<PB2)
out portb,r16 ;ss pin->0
rjmp main


и слэйв:
CODE
.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

ldi r16,(1<<spie)+(1<<spe)
out spcr,r16 ;spi enableand and spi int. enable

reti


вроде все работает...
однако случается что в мастере что-то происходит, протеус про data collision сообщает...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.