Обсуждаем контроллеры компании Atmel.
Ответить

Вопрос по SPI на asm

Чт сен 01, 2016 10:34:47

Подскажите,...
По всем ли пинам надо передавать через регистр SPDR? или только SDI
Т.к. это последовательный интерфейс при загрузке надо передавать один бит из последовательности. А положение бита играет роль?
00000001
00010000 или сразу всю последовательность и только потом дергать клок...
Вложения
3. SPI-diagram a.PNG
(38.25 KiB) Скачиваний: 781

Re: Вопрос по SPI на asm

Чт сен 01, 2016 10:52:53

О каких пинах идёт речь. Там только MOSI-MISO-SCK-SS.
Надо правильно инициализировать SPI(скорость, полярность клока, порядок бит), дальше только пользоваться подпрограммой посылки.
Код:
SPI_MasterInit:
; Set MOSI and SCK output, all others input
ldi r17,(1<<DD_MOSI)|(1<<DD_SCK)
out DDR_SPI,r17
; Enable SPI, Master, set clock rate fck/16
ldi r17,(1<<SPE)|(1<<MSTR)|(1<<SPR0)
out SPCR,r17
ret

SPI_MasterTransmit:
; Start transmission of data (r16)
out SPDR,r16
Wait_Transmit:
; Wait for transmission complete
sbis SPSR,SPIF
rjmp Wait_Transmit
ret

Про NSS не забываем, его придётся дёргать программно в соотвествии с протоколом устройства.

Re: Вопрос по SPI на asm

Пт сен 02, 2016 09:36:34

Под порядком бит, вы подразумеваите выбор срабатывание клок (SCK)? А меня интересует программное расположение бита при загрузке...
По прикрепленной диаграмме видно, что устройство начинает данные забивать с DB7 (последнего бита), так и в программе надо ставить загружаемый бит на последнее место, след. на 6... Или ставим загружаемый бит на первое место 00000001 загружаем в SPDR и он окажется DB7, DB6,...

Re: Вопрос по SPI на asm

Пт сен 02, 2016 10:01:40

vit007 писал(а):А меня интересует программное расположение бита при загрузке...

Давайте для начала - Вы SPI программно реализуете, или используете аппаратный модуль SPI?

Re: Вопрос по SPI на asm

Пт сен 02, 2016 11:32:49

программно
Вложения
spi.txt
(1.63 KiB) Скачиваний: 254

Re: Вопрос по SPI на asm

Пт сен 02, 2016 11:53:23

vit007 писал(а):А меня интересует программное расположение бита при загрузке...

МК у Вас какой - AVR?
Если Вы внимательно посмотрите даташит на МК, то увидите, что при аппаратной реализации за порядок расположения бит отвечает бит DORD регистра SPCR. Если DORD установлен, то передача идет младшим битом вперед, а если сброшен - то старшим.
Отсюда следует, что возможны оба варианта, и Вам нужно смотреть даташит на ту микросхему, которую Вы стыкуете с МК и делать так, как требуется там.
Если вы стыкуете два МК, то безразлично каким битом вперед передавать, лишь бы на обоих МК одинаково.

Re: Вопрос по SPI на asm

Пт сен 02, 2016 11:56:15

При программной реализации интерфейса о каких регистрах SPDR,SPCR,SPSR может идти речь?
По рисунку видно что используется SPI Mode0 или Mode 3.
Самым первым выгружается старший разряд байта RAM data.
Значит
Код:
SCL=0
если RamData AND маска 0x80 = 1 тогда SDI=1 иначе SDI=0
SCL=1
NOP
SCL=0
сдвинуть маску вправо
повторить оставшиеся 7 раз.

Re: Вопрос по SPI на asm

Пт сен 02, 2016 11:59:57

uk8amk писал(а):При программной реализации интерфейса о каких регистрах SPDR,SPCR,SPSR может идти речь?

Я так понял, что человек в принципе не знал, каким байтом вперед передается. Поэтому и сделал отсылку к аппаратной реализации, которую всегда надо брать за образец, будь то USART или SPI.

uk8amk писал(а):сдвинуть маску вправо

А зачем маску двигать, если есть удобная команда LSL (если старшим битом вперед)?
Выдвинуть старший бит в бит переноса и командами brcc либо brcs определить требуется ли сброс или установка линии выхода?

Re: Вопрос по SPI на asm

Пт сен 02, 2016 12:14:54

Значит это не правиль, т.к. маска 0х01
Вложения
shift.txt
(930 байт) Скачиваний: 194

Re: Вопрос по SPI на asm

Сб сен 03, 2016 08:37:17

Код:
out    SPDR,temp3    ; отправляем бит по SPI

Какая-то смешанина... Если используется SPDR, никакой бит никуда не отправляем - загружаем автомат SPI , и он самостоятельно бит за битом отправляет загруженный байт в линию, не забывая дергать клоки. "Закончив бросать, он напился воды "(С), автомат SPI выставляет бит SPIF в SPSR . Если программный SPI, забываем как кошмарный сон SPDR, которого в данном МК вообще может не быть, и передаваемый бит закидываем на пин, выбранный в качестве MOSI , дергаем клок, сдвигаем данные - и так до опупенияокончания.

Re: Вопрос по SPI на asm

Сб сен 03, 2016 10:28:41

mega8
Master/Slave SPI Serial Interface

Понял, что надо уточнить про понимание видов SPI, есть два, аппаратный - это через специальный адаптер spi, мы конектимся к устройству с spi, а программный - напрямую в устройство...

т.е. если сразу закинуть байт в SPDR, то мк начиная со старшего бита (DORD=0) ч/з такт закидывать биты...
А при программном вообще не надо настраивать SPI, а только дергать правильные пины?

Re: Вопрос по SPI на asm

Сб сен 03, 2016 11:12:00

vit007 писал(а):mega8Master/Slave SPI Serial Interface

Ну там же русским по белому написано как работает SPI Interface...

аппаратный SPI
1- Подключаем согласно схеме...
1.jpg
(251.8 KiB) Скачиваний: 730


2- Выбираем: Режим SPI, (формат, фронт...) :
2.jpg
(229.26 KiB) Скачиваний: 714


3- Затем:
"Ведущий SPI инициирует сеанс связи подачей низкого уровня на вход SS того подчиненного устройства, с которым необходимо обмениваться данными. Оба респондента (ведущий и подчиненный) подготавливают данные к передаче в своем сдвиговом регистре, при этом на стороне ведущего генерируются также импульсы синхронизации на линии SCK." ...
...
...

В даташите есть даже пример кода на asm и на Си...
3.jpg
(115.23 KiB) Скачиваний: 722


программный SPI - тоже самое... только вообще не надо настраивать SPI, а только дергать правильные пины.
:)

Re: Вопрос по SPI на asm

Сб сен 03, 2016 11:21:32

вот как понял

аппаратный
spi_a.txt
(1.88 KiB) Скачиваний: 254


программный
spi_p.txt
(2.44 KiB) Скачиваний: 244

Re: Вопрос по SPI на asm

Сб сен 03, 2016 11:39:28

Извините.. я на асме не шарю)) Я только на Си...

Рекомендую прочитать внимательно даташит, и прогнать всё в протеусе (посмотерть на осциллографе).
Если что не так, то всё будет понятно сразу что не так. :)

Re: Вопрос по SPI на asm

Сб сен 03, 2016 14:51:25

В аппаратном не нужно дергать клоки, это блок SPI делает сам, соответственно и цикл никакой там не нужен. Все это детально описано в ДШ. К примеру, для Меги8 это doc2486.pdf с сайта Атмела, стр. 129.
Вложения
SPI_.JPG
(58.95 KiB) Скачиваний: 722

Re: Вопрос по SPI на asm

Сб сен 03, 2016 17:51:36

С выкопировкой из даташита, приведенной Jack_A, согласен.

Но на самом деле и это лишнее. Как правило, чаще всего удобнее работать через прерывания.
То есть, после настройки интерфейса SPI мастер просто посылает передаваемый байт в SPDR, после окончания передачи срабатывает прерывание SPI Serial Transfer Complete, в нем мастер, прочитав SPDR, может принять байт, полученный от слейва и если надо, занести в регистр SPDR следующий передаваемый байт и выйти из обработчика прерывания.

У слейва же по завершению "вдвигания" принимаемого байта в регистр SPDR сработает прерывание SPI Serial Transfer Complete, в котором он должен будет, прочитав регистр SPDR, принять полученный байт и занести в регистр SPDR байт, который получит мастер в следующем цикле обмена, если инициирует его.

Re: Вопрос по SPI на asm

Сб сен 03, 2016 19:57:51

Jack_A, а здесь тема правильного описания процесса, на asm... я видел примеры в шите, мне нужна механика для понимания процесса - просто так мне лучше понимать... :solder:

поправил аппаратное - один в один пример шита
spi_a.txt
(1.75 KiB) Скачиваний: 199


В студии не про симмулировать же...

Значит когда данные будут в SPDR произойдет прерывание (это и до форума знал) и пока идет проверка на ед. в прерывание происходит загрузка данных в устройство.

Если надо отправить 10 бит, можно использовать и аппаратный и программный способ?
т.е. по диаграмме видно, если закидывать SPDR 00000011, то устройство не поймет, наверное....

spi_aр.txt
(2.52 KiB) Скачиваний: 218

Re: Вопрос по SPI на asm

Сб сен 03, 2016 22:10:44

vit007 писал(а):поправил аппаратное - один в один пример шита
В студии не про симмулировать же...

У Вас не совсем верно делается настройка.
Для начала, забудьте про конструкции вида
Код:
sbi PORTB,2         // Вывод SS на +5
sbi PORTB,4          // На MISO подключаем подтягивающий резистор
ldi temp0,0b11010001       // Настраиваем SPI, SPIE и SPE = 1 это разрешит прерывания и

Гораздо лучше написать вот так:
Код:
.equ SS=2
.equ MISO=4

...

sbi PORTB,SS
sbi PORTB,MISO
ldi temp,((1<<SPIE)|(1<<SPE)|(1<<MSTR)|(1<<SPR0))
out SPCR,temp

В такой записи Вы никогда не ошибетесь в установке бит, и с первого взгляда понятно, что делается в команде.

Обработчик прерывания SPI_STC у Вас записан неправильно. Зачем в прерывании ждать установки флага SPIF, если сам обработчик вызывается только после установки этого флага? Флаг SPIF очищается аппаратно при выполнении обработчика. Я не помню, очищается флаг при вызове обработчика или при выходе из него (скорее всего, первое). В первом случае Вы будете бесконечно "висеть" в цикле опроса этого флага внутри обработчика прерывания, ожидая установки только что сброшенного перед этим флага SPIF, который не установится никогда. Во втором случае Вы внутри обработчика проверяете флаг, который и так установлен и выходите из обработчика, не взяв полученные данные. Ради чего тогда обмен затевался?

Смотрите - логика работы SPI такова: перед началом обмена в регистре SPDR слейва находится какое-то число (если не инициализировали регистр SPDR слейва, то там мусор). Когда мастер помещает передаваемое число в свой регистр SPDR, то его аппаратный блок SPI автоматически начинает передачу, генерируя импульсы на выходе SCK, на каждом импульсе побитно выдвигая содержимое своего регистра SPDR (старший бит) в регистр SPDR слейва (в младший бит), одновременно с этим старший бит регистра SPDR слейва выдвигается в младший бит регистра SPDR мастера, как показано на картинке из даташита
spi.jpg
(36.68 KiB) Скачиваний: 693

Таким образом, длительность цикла обмена - 8 тактов на SCK, после завершения обмена содержимое регистра SPDR мастера переносится в регистр SPDR слейва, и наоборот. То есть в одном цикле обмена мастер и слейв меняются содержимым своих регистров SPDR.

Поэтому в обработчике прерывания SPI_STC мастер должен прочитать содержимое своего регистра SPDR, чтобы определить, что же послал ему слейв, а потом, если необходимо продолжить обмен, занести в регистр SPDR новое передаваемое число и выйти из обработчика. После завершения передачи этого числа вновь будет вызван обработчик прерывания SPI_STC.

Таким образом, если мастер хочет получить от слейва один байт данных, обмен должен состоять из двух циклов и строиться так:
Вначале (в первом цикле) мастер должен занести в свой SPDR число-команду, которая сообщит слейву, какие именно данные от него требуются, после завершения первого цикла передачи мастер получит то содержимое SPDR слейва, которое было там при инициализации, эти данные мастеру не интересны. Одновременно с этим, после завершения первого цикла передачи у слейва тоже вызовется обработчик SPI_STC, в котором слейв должен прочитать свой SPDR, взяв оттуда полученную от мастера число-команду, указывающую, какие данные запрашивает мастер, выбрать нужные мастеру данные, поместить их в свой SPDR и выйти из обработчика прерывания.
Мастер через некоторое время для начала второго цикла обмена должен снова поместить в свой регистр SPDR число. Начнется второй цикл обмена, после которого в SPDR мастера окажется байт переданных слейвом данных, а в регистре SPDR слейва окажется число, помещенное мастером в свой SPDR для начала второго цикла обмена.
Если мастеру требуется получить только один байт, то на этом обмен прекращается, а число, помещенное в SPDR мастера для начала второго цикла обмена, должно сказать слейву, что на этом обмен прекращается и следующие данные можно не готовить.

Далее. Внутри любого обработчика прерываний не надо использовать команды CLI и SEI, так как при вызове любого обработчика прерываний у контроллеров семейства AVR флаг глобального разрешения прерываний I регистра SREG сбрасывается аппаратно, при этом все прерывания запрещаются, а команда RETI, одновременно с возвратом в точку, из которой был вызван обработчик, наоборот, устанавливает флаг I, глобально разрешая прерывания. Этим, собственно, команда RETI и отличается от команды RET, которая делает все то же самое, что и RETI, но не трогая флаг I.
А Вы, разрешив прерывания внутри обработчика, сможете получить неприятный трудноотлавливаемый глюк, когда у Вас внутри одного обработчика вызовется другой, если в этот момент возникнет какое-то иное прерывание.

Далее. Для того, чтобы слейв был слейвом, на его входе SS должен быть уровень лог.0. Вы, подавая на вывод SS мастера уровень лог.1 чего хотите добиться? У вас вывод SS мастера соединен с выводом SS слейва? Если да, то подачей лог.1 на вывод SS мастера Вы отключаете слейв.
Вот эта строка, которой настраивается мастер,
Код:
ldi temp,((1<<SPIE)|(1<<SPE)|(1<<MSTR)|(1<<SPR0))

у слейва должна выглядеть точно также, за исключением того, что бит MSTR должен быть сброшен.
То есть, у слейва строка должна быть такой:
Код:
ldi temp,((1<<SPIE)|(1<<SPE)|(1<<SPR0))


vit007 писал(а):В студии не про симмулировать же...

Настройте правильно мастера, занесите в SPDR число и через время, определенное битами SPI2X, SPR1, SPR0 у Вас вызовется обработчик прерывания SPI_STC. Можно просто в окне I/O View установить галку на бите SPIF.

Re: Вопрос по SPI на asm

Вс сен 04, 2016 09:40:37

Все это так, но автору темы требуется 10-битный кадр. Аппаратно на атмегах такое не сделать(регистры то 8-битные). Либо переходить на другие контроллеры где SPI с регулируемой длиной посылки, либо реализовывать его программным дерганьем линий GPIO, что само по себе медленно.

Чтобы устройство приняло байт 0b00000011 нужно в SPDR записать 0b00000011, затем подождать окончания пересылки. И конечно сам SPI для этого должен быть правильно настроен.

И наверно стоит почитать о сдвиговых регистрах, что такое SPI вообще и как он реализован конкретно в вашем микроконтроллере(это в даташите).

Re: Вопрос по SPI на asm

Вс сен 04, 2016 10:00:34

uk8amk писал(а):Все это так, но автору темы требуется 10-битный кадр.

Фраза про 10-ти битный кадр возникла в самом конце, я так понял, что автор просто спросил, как ему передать еще и 10-ти битный кадр.

Конечно, 10 бит - только программно.

uk8amk писал(а):либо реализовывать его программным дерганьем линий GPIO, что само по себе медленно.

Ну, что значит медленно, все относительно. Конечно тактовую Fclk равной Fosc/2 ... Fosc/16 получить трудновато, но Fosc/64 - запросто. Только придется для этого таймер задействовать.

vit007 писал(а):Если надо отправить 10 бит, можно использовать и аппаратный и программный способ?

Что-то у Вас там все в кучу, кони, люди... Надо использовать что-то одно - или программный, или аппаратный способ. Не надо в коде делать мешанину.
Исключение - когда у Вас по SPI подключается два устройства - одно требует 8-ми битные кадры, другое - кадры нестандартной длины. Тогда первое устройство можно подключить к аппаратному SPI и пользоваться всеми его удобствами и простотой, а для второго - писать программную реализацию, естественно, на свободных выводах МК, штатные MOSI MISO SCK задействуются для подключения первого ("стандартного" устройства).
Последний раз редактировалось Alkul Вс сен 04, 2016 10:06:49, всего редактировалось 1 раз.
Ответить