PIC16F877 и его SPI

May 05, 2004 5 Replies

Hello everybody.



Пытаюсь завести сабж. Hасколько я понял, сразу после записи в SSPBUF одновременно начинаются передача и приём, и, когда приняты все 8 бит, они записываются в SSPBUF и взводится SSPIF. Hо у меня в SSPBUF почему-то оказывается сам передаваемый символ. Что так?



spi_init movlw b'00100000' movwf STATUS bcf TRISC,5 bcf TRISC,3 bcf PIE1, SSPIE movlw b'01000000' movwf SSPSTAT clrf STATUS movlw b'00110000' movwf SSPCON movwf SSPBUF ;чтобы взвести SSPIF в начале работы return



spi_txrx btfss PIR1,SSPIF goto spi_txrx movwf SSPBUF spi_rx btfss PIR1,SSPIF goto spi_rx movfw SSPBUF return



С другой стороны - 25LC160.



Ivan


IM> spi_txrx IM> btfss PIR1,SSPIF IM> goto spi_txrx IM> movwf SSPBUF что ты хочешь вставить в SSPBUF? Из раб. регистра?

IM> spi_rx btfss PIR1,SSPIF IM> goto spi_rx IM> movfw SSPBUF Это вообще не понятно. По идее, ты должен из SSPBUF считать в раб. регистр - movf SSPBUF, W Я твою команду не проверял - movfw - "это я еще не пробовал..." - вдруг сработает?

Привет!

Thu, 06 May 2004 00:09:41 +0400, Ivan Maximov писал:

...

Вот работающий код для обмена по SPI (подразумевается, что TRIS'ы в нужном состоянии):

;*===================================================================* ;* <> Инициализировать порт SPI * ;*===================================================================* InitSPI bsf CSM ; Снять сигнал CS ; - Инициализировать SPI bcf sspen ; Деактивировать SSP movlw b'00010000' ; SPI Master 1/4, Mode 0 movwf sspcon ; Установить режим работы SSP bsf sspen ; Активировать SSP return ;

;*===================================================================* ;* <> Провести обмен байтами по SPI * ;*===================================================================* SwopSPI movwf sspbuf ; Байт в приёмный регистр page1 ; Включить банк 1 SwopSPI0 bbc bf,SwopSPI0 ; = Передача ещё не завершена page0 ; Включить банк 0 movfw sspbuf ; Загрузить принятый байт return ;

Вот работающий код обмена с 25LC320:

;*===================================================================* ;* <> Начать чтение содержимого EEPROM * ;*===================================================================* EEPROM_Read bsf CSM ; Снять выборку EEPROM clrwdt ; Сбросить WDT bcf CSM ; Выбрать EEPROM movlw b'00000011' ; Команда READ goto SwopSPI ; Передать/принять байт по SPI

;*===================================================================* ;* <> Начать запись последовательности в EEPROM * ;*===================================================================* EEPROM_Write bsf CSM ; Снять выборку EEPROM clrwdt ; Сбросить WDT bcf CSM ; Выбрать EEPROM movlw b'00000110' ; Команда WREN call SwopSPI ; Передать байт по SPI bsf CSM ; Снять выборку EEPROM ; - Записать слово состояния. bcf CSM ; Выбрать EEPROM movlw b'00000001' ; Команда WRSR call SwopSPI ; Передать/принять байт по SPI movlw b'00000010' ; Снять все защиты call SwopSPI ; Передать/принять байт по SPI bsf CSM ; Снять выборку EEPROM ; - Ожидать готовности EEPROM EEPROM_Write0 bcf CSM ; Выбрать EEPROM movlw b'00000101' ; Команда RDSR call SwopSPI ; Передать/принять байт по SPI call SwopSPI ; Передать/принять байт по SPI bsf CSM ; Снять выборку EEPROM andlw b'00000001' ; Выделить флаг RDY bne EEPROM_Write0 ; = Запись ещё не завершена bsf CSM ; Снять выборку EEPROM ; - Подать команду WREN bcf CSM ; Выбрать EEPROM movlw b'00000110' ; Команда WREN call SwopSPI ; Передать/принять байт по SPI bsf CSM ; Снять выборку EEPROM ; - Начать запись bcf CSM ; Выбрать EEPROM movlw b'00000010' ; Команда WRITE goto SwopSPI ; Передать/принять байт по SPI

;*===================================================================* ;* <> Ожидать готовности EEPROM (окончания цикла записи) * ;*===================================================================* EEPROM_Ready bsf CSM ; Снять выборку EEPROM nop ; bcf CSM ; Выбрать EEPROM movlw b'00000101' ; Команда RDSR call SwopSPI ; Передать/принять байт по SPI call SwopSPI ; Передать/принять байт по SPI bsf CSM ; Снять выборку EEPROM andlw b'00000001' ; Выделить флаг RDY bne EEPROM_Ready ; = Запись ещё не завершена return ;

Пример чтения из 25LC320:

LoadParms4 call EEPROM_Read ; Начать чтение EEPROM movlw high LinkParms ; Старший байт адреса call SwopSPI ; Передать movlw low LinkParms ; Младший байт адреса call SwopSPI ; Передать call SwopSPI ; Прочитать

...

bsf CSM ; Снять выборку EEPROM

Пример записи в 25LC320 ; Произвести начальную инициализацию содержимого EEPROM call EEPROM_Write ; Произвести инициализацию Link-параметров movlw high LinkParms ; Старший байт адреса call SwopSPI ; Передать movlw low LinkParms ; Младший байт адреса call SwopSPI ; Передать movlw 1 ; Сетевой адрес call SwopSPI ; Записать

...

call EEPROM_Ready ; Ожидать окончания цикла записи

В коде используются нераспространённые макросы. Я боюсь исправляя что-нибудь ляпнуть, поэтому просто привожу их текст:

beq macro A btfsc z goto A endm

bne macro A btfss z goto A endm

bbc macro A,B,C btfss A,B goto C endm

page0 macro bcf rp0 endm

page1 macro bsf rp0 endm

Александр Голов, Москва, snipped-for-privacy@mtu-net.ru

Hello Alexander.

06 Май 04 13:51, you wrote to me: >> Пытаюсь завести сабж. Hасколько я понял, сразу после записи в SSPBUF >> одновременно начинаются передача и приём, и, когда приняты все 8 бит, >> они записываются в SSPBUF и взводится SSPIF. Hо у меня в SSPBUF >> почему-то оказывается сам передаваемый символ. Что так? AG> SwopSPI movwf sspbuf ; Байт в приёмный регистр AG> page1 ; Включить банк 1 AG> SwopSPI0 bbc bf,SwopSPI0 ; = Передача ещё не завершена ^^ AG> page0 ; Включить банк 0 AG> movfw sspbuf ; Загрузить принятый байт AG> return ; Как выяснилось, копать здесь. Я наивно полагал, что SSPIF сам собой сбрасывается при записи в SSPBUF (как это делают TXIF и RCIF). После замены его на BF всё стало работать. Спасиб.

Ivan

Hello Rifkat.

06 Май 04 09:52, you wrote to me: IM>> spi_txrx IM>> btfss PIR1,SSPIF IM>> goto spi_txrx IM>> movwf SSPBUF RA> что ты хочешь вставить в SSPBUF? Из раб. регистра? Хочу. У меня через него передаётся аргумент этой подпрограммы (байт, который надо передать). IM>> spi_rx btfss PIR1,SSPIF IM>> goto spi_rx IM>> movfw SSPBUF RA> Это вообще не понятно. По идее, ты должен из SSPBUF считать в раб. RA> регистр - movf SSPBUF, W Пыххх! А ведь, действительно, сейчас посмотрел - нет такой команды (movfw) в даташите! Тем не менее, ассемблер gpasm её успешно понимает (наверно, делая из неё movf reg, w).

З.Ы. Как мне уже подсказали, проблема была в отлове окончания передачи.

Ivan

Привет Ivan!

10 Май 04 01:57, Ivan Maximov -> Rifkat Abdulin:

IM>>> movfw SSPBUF RA>> Это вообще не понятно. По идее, ты должен из SSPBUF считать в RA>> раб. регистр - movf SSPBUF, W IM> Пыххх! А ведь, действительно, сейчас посмотрел - нет такой команды IM> (movfw) в даташите! Тем не менее, ассемблер gpasm её успешно понимает IM> (наверно, делая из неё movf reg, w). Да, конечно понимает, "делая из", как и команды: b k = goto k ,negf f = comf f,1+incf f,d ; bc k, bz k, bnz k, skpz, setc, skpnc, tstf f, lcall k, clrc, и пр. Мелочь, но пользоваться приятно :) До свидания, Alexandr.

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required