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

Обсуждаем контроллеры компании Atmel.
vit007
Встал на лапы
Сообщения: 124
Зарегистрирован: Пн мар 22, 2010 18:07:52

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

Сообщение vit007 »

Подскажите,...
По всем ли пинам надо передавать через регистр SPDR? или только SDI
Т.к. это последовательный интерфейс при загрузке надо передавать один бит из последовательности. А положение бита играет роль?
00000001
00010000 или сразу всю последовательность и только потом дергать клок...
Вложения
3. SPI-diagram a.PNG
(38.25 КБ) 836 скачиваний
Реклама
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

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

Сообщение uk8amk »

О каких пинах идёт речь. Там только 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 не забываем, его придётся дёргать программно в соотвествии с протоколом устройства.
Реклама
vit007
Встал на лапы
Сообщения: 124
Зарегистрирован: Пн мар 22, 2010 18:07:52

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

Сообщение vit007 »

Под порядком бит, вы подразумеваите выбор срабатывание клок (SCK)? А меня интересует программное расположение бита при загрузке...
По прикрепленной диаграмме видно, что устройство начинает данные забивать с DB7 (последнего бита), так и в программе надо ставить загружаемый бит на последнее место, след. на 6... Или ставим загружаемый бит на первое место 00000001 загружаем в SPDR и он окажется DB7, DB6,...
Alkul
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

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

Сообщение Alkul »

vit007 писал(а):А меня интересует программное расположение бита при загрузке...
Давайте для начала - Вы SPI программно реализуете, или используете аппаратный модуль SPI?
Реклама
Эиком - электронные компоненты и радиодетали
vit007
Встал на лапы
Сообщения: 124
Зарегистрирован: Пн мар 22, 2010 18:07:52

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

Сообщение vit007 »

программно
Вложения
spi.txt
(1.63 КБ) 322 скачивания
Реклама
Alkul
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

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

Сообщение Alkul »

vit007 писал(а):А меня интересует программное расположение бита при загрузке...
МК у Вас какой - AVR?
Если Вы внимательно посмотрите даташит на МК, то увидите, что при аппаратной реализации за порядок расположения бит отвечает бит DORD регистра SPCR. Если DORD установлен, то передача идет младшим битом вперед, а если сброшен - то старшим.
Отсюда следует, что возможны оба варианта, и Вам нужно смотреть даташит на ту микросхему, которую Вы стыкуете с МК и делать так, как требуется там.
Если вы стыкуете два МК, то безразлично каким битом вперед передавать, лишь бы на обоих МК одинаково.
Реклама
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

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

Сообщение uk8amk »

При программной реализации интерфейса о каких регистрах 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 раз.
Alkul
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

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

Сообщение Alkul »

uk8amk писал(а):При программной реализации интерфейса о каких регистрах SPDR,SPCR,SPSR может идти речь?
Я так понял, что человек в принципе не знал, каким байтом вперед передается. Поэтому и сделал отсылку к аппаратной реализации, которую всегда надо брать за образец, будь то USART или SPI.
uk8amk писал(а): сдвинуть маску вправо
А зачем маску двигать, если есть удобная команда LSL (если старшим битом вперед)?
Выдвинуть старший бит в бит переноса и командами brcc либо brcs определить требуется ли сброс или установка линии выхода?
vit007
Встал на лапы
Сообщения: 124
Зарегистрирован: Пн мар 22, 2010 18:07:52

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

Сообщение vit007 »

Значит это не правиль, т.к. маска 0х01
Вложения
shift.txt
(930 байт) 244 скачивания
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6321
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

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

Сообщение Jack_A »

Код: Выделить всё

out 	SPDR,temp3 	; отправляем бит по SPI
Какая-то смешанина... Если используется SPDR, никакой бит никуда не отправляем - загружаем автомат SPI , и он самостоятельно бит за битом отправляет загруженный байт в линию, не забывая дергать клоки. "Закончив бросать, он напился воды "(С), автомат SPI выставляет бит SPIF в SPSR . Если программный SPI, забываем как кошмарный сон SPDR, которого в данном МК вообще может не быть, и передаваемый бит закидываем на пин, выбранный в качестве MOSI , дергаем клок, сдвигаем данные - и так до опупенияокончания.
Изображение
vit007
Встал на лапы
Сообщения: 124
Зарегистрирован: Пн мар 22, 2010 18:07:52

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

Сообщение vit007 »

mega8
Master/Slave SPI Serial Interface

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

т.е. если сразу закинуть байт в SPDR, то мк начиная со старшего бита (DORD=0) ч/з такт закидывать биты...
А при программном вообще не надо настраивать SPI, а только дергать правильные пины?
roman.com
Друг Кота
Сообщения: 9175
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

Сообщение roman.com »

vit007 писал(а):mega8Master/Slave SPI Serial Interface
Ну там же русским по белому написано как работает SPI Interface...

аппаратный SPI
1- Подключаем согласно схеме...
1.jpg
(251.8 КБ) 786 скачиваний
2- Выбираем: Режим SPI, (формат, фронт...) :
2.jpg
(229.26 КБ) 765 скачиваний
3- Затем:
"Ведущий SPI инициирует сеанс связи подачей низкого уровня на вход SS того подчиненного устройства, с которым необходимо обмениваться данными. Оба респондента (ведущий и подчиненный) подготавливают данные к передаче в своем сдвиговом регистре, при этом на стороне ведущего генерируются также импульсы синхронизации на линии SCK." ...
...
...

В даташите есть даже пример кода на asm и на Си...
3.jpg
(115.23 КБ) 783 скачивания
программный SPI - тоже самое... только вообще не надо настраивать SPI, а только дергать правильные пины.
:)
vit007
Встал на лапы
Сообщения: 124
Зарегистрирован: Пн мар 22, 2010 18:07:52

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

Сообщение vit007 »

вот как понял

аппаратный
spi_a.txt
(1.88 КБ) 309 скачиваний
программный
spi_p.txt
(2.44 КБ) 303 скачивания
roman.com
Друг Кота
Сообщения: 9175
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

Сообщение roman.com »

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

Рекомендую прочитать внимательно даташит, и прогнать всё в протеусе (посмотерть на осциллографе).
Если что не так, то всё будет понятно сразу что не так. :)
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6321
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

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

Сообщение Jack_A »

В аппаратном не нужно дергать клоки, это блок SPI делает сам, соответственно и цикл никакой там не нужен. Все это детально описано в ДШ. К примеру, для Меги8 это doc2486.pdf с сайта Атмела, стр. 129.
Вложения
SPI_.JPG
(58.95 КБ) 766 скачиваний
Изображение
Alkul
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

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

Сообщение Alkul »

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

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

У слейва же по завершению "вдвигания" принимаемого байта в регистр SPDR сработает прерывание SPI Serial Transfer Complete, в котором он должен будет, прочитав регистр SPDR, принять полученный байт и занести в регистр SPDR байт, который получит мастер в следующем цикле обмена, если инициирует его.
vit007
Встал на лапы
Сообщения: 124
Зарегистрирован: Пн мар 22, 2010 18:07:52

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

Сообщение vit007 »

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

поправил аппаратное - один в один пример шита
spi_a.txt
(1.75 КБ) 257 скачиваний
В студии не про симмулировать же...

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

Если надо отправить 10 бит, можно использовать и аппаратный и программный способ?
т.е. по диаграмме видно, если закидывать SPDR 00000011, то устройство не поймет, наверное....
spi_aр.txt
(2.52 КБ) 268 скачиваний
Alkul
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

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

Сообщение Alkul »

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 КБ) 745 скачиваний
Таким образом, длительность цикла обмена - 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.
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

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

Сообщение uk8amk »

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

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

И наверно стоит почитать о сдвиговых регистрах, что такое SPI вообще и как он реализован конкретно в вашем микроконтроллере(это в даташите).
Alkul
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

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

Сообщение Alkul »

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 раз.
Ответить

Вернуться в «AVR»