PIC16F877 и его SPI

Do you have a question? Post it now! No Registration Necessary

Threaded View
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


Re: PIC16F877 и его SPI

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

--
Rifkat < Team /Grave\ >
Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru

Re: PIC16F877 и его SPI
  Привет!

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

...

Quoted text here. Click to load it

Вот работающий код для обмена по 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


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

PIC16F877 и его SPI
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


Re: PIC16F877 и его SPI
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


Re: PIC16F877 и его SPI
   Привет 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.


Site Timeline