PIC16F877 и его SPI

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

Reply to
Ivan Maximov
Loading thread data ...

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 - "это я еще не пробовал..." - вдруг сработает?

Reply to
Rifkat Abdulin

Привет!

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

Reply to
Alexander Golov

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

Reply to
Ivan Maximov

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

Reply to
Ivan Maximov

Привет 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.

Reply to
Alexandr Kuhtenkov

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.