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

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

Сб мар 16, 2019 23:32:57

посоветуйте где я накосячил?) хочу передать по 1 байту между 2 МК атмега8 по SPI. число передаю 0b10000111 но приходит в оба МК не эти числа, ощущение что не хватило 1 такта что бы все число пришло?

фото симуляции Изображение
светодиоды в симуляции типа индикаторы.

прошивка мастера

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

Вс мар 17, 2019 00:53:37

Слейв мастеру начинает слать что-то по spi
У мастера срабатывает прерывание, т.к. по шине начинается передача..
И что же как вы думаете делает мастер!?
Барабанная дробь!!
Первой инструкцией в обработчике прерываний,вместо того чтоб принять байт, он запрещает слейву что слать и только потом читает регистр с данными, в котором конечно же мусор.

Меня всерьёз принимать не стоит. Предупреждаю что сам только знакомлюсь с миром микроконтроллеров и наверняка могу ошибаться...

Добавлено after 9 minutes 57 seconds:
Я бы попробовал сначала дождаться пока данные обменяются, а только потом запретил передачу.. х.з. могу и ошибаться

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

Вс мар 17, 2019 09:18:35

Прячем тексты исходника под спойлер!
Иначе собственные вопросы/ответы искать кошмарус будет.
8)
С собственно с аппаратным блоком SPI я пока не занимался - там и согласований/настроек моного и применение только "стандартными" 8-битными посылками. Добавляем настройку и обработку прерываний по завершению передачи/приема (при необходимости их анализ и перенастройку режимов работы), согласование скоростей обмена, внутренний буфер данных для приема и передачи, логику определения размера пакета и типа данных.
Тогда уже и результат будет.
Штука простая, если приемник аппаратный - вида "регистр с мозгами".
А между МК обмен значительно посложнее (с учетом того, что и своих основных задач там достаточно).
Вобщем разбираться надо в том числе и с аппаратной начинкой.
К примеру...
По протоколу мастер выполнил передачу и ждет данные от слейва.
Следовательно модуль SPI мастера должен быть сразу же после передачи перенастроен на прием, а слейв перед своей передачей обязан выдержать определенную технологическую паузу.
:roll:

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

Вс мар 17, 2019 10:01:50

BOB51 писал(а):По протоколу мастер выполнил передачу и ждет данные от слейва.
Следовательно модуль SPI мастера должен быть сразу же после передачи перенастроен на прием, а слейв перед своей передачей обязан выдержать определенную технологическую паузу.
не говорите ерунды: обмен по SPI всегда идет ОДНОВРЕМЕННО, поэтому когда мастер закончил передачу, он уже имеет ответ ведомого. если технически невозможно реализовать одновременный обмен, вводится "лишний" байт для обмена: мастер передает первый байт, на который слейв реагирует, а потом байт-пустышку (обычно 0xFF, не вжано, лишь бы восемь фронтов SCK было), а слейв, принв первый байт тут же ставит в SPDR свой ответ и уже сам игнорирует пришедший байт-пустышку.

никакой перенастройки мастера и/или слейва не требуется!

разница между ними только в том, что слейв не генерирует фронты SCK, а мастер - генерирует.

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

Вс мар 17, 2019 10:35:50

Это при условии, что передающей определена только одна из сторон.
Т.е. один МК только как мастер и один МК только как слейв, генератором тактов может быть только мастер.
Так же как и инициатором цикла обмена данными также является только мастер.
8)
А если каждый из МК может быть инициатором обмена?
Причем в произвольный момент времени ("мультимастер")...
:roll:

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

Вс мар 17, 2019 10:46:30

:facepalm:

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

Вс мар 17, 2019 11:13:07

Так что же у тс не так с кодом?

Добавлено after 30 seconds:
Re: Вопрос по SPI на asm
Аж самому интересно стало...

Добавлено after 4 minutes 39 seconds:
Re: Вопрос по SPI на asm
Исходя из информации от arv передачу инициализирует мастер и только он.. значит мастеру прерывание spi без надобности, а вот слейв в этом прерывании должен какие-то данные пихать в spdr, правильно ли я понимаю?

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

Вс мар 17, 2019 11:24:53

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

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

Вс мар 17, 2019 11:43:34

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

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

Вс мар 17, 2019 11:50:15

при чем тут первый бит? прервание возникает после приема/передачи последнего, т.е. 8-го бита.

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

Вс мар 17, 2019 12:08:54

:facepalm:

Понятно, что в таком случае I2C полезнее, но всегда хочется "вроде бы попроще".
8)

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

Вс мар 17, 2019 12:15:24

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

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

Вс мар 17, 2019 12:29:09

Ежли б местом назначения был не МК, а обычный 595й регистр и/или какой дисплейчик с протоколом SPI - никаких проблем не будет.
Однако запхнуто ДВА МК -
тут или жестко ставить один из них в режим приема а другой только на передачу (до прояснения более сложных вариантов), либо применять I2C/UART в качестве аппаратных модулей.
:dont_know:

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

Вс мар 17, 2019 12:40:06

Боб51 да разобраться бы хотелось. 2 однотипных мк , передача по 1 байта и засада

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

Вс мар 17, 2019 13:39:30

Чтение лучше делать так :)
Код:
   IN   R16,SPDR
;     ldi r16, SPDR    ;?????????????????????????;читаем регистр данных SPDR модуля SPI
     out PORTD, r16   ;пересылаем эти данные в порт D
   reti

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

Вс мар 17, 2019 20:25:24

при чем тут первый бит? прервание возникает после приема/передачи последнего, т.е. 8-го бита.

Соответственно алгоритм опроса слейва мне видится так:

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

Вс мар 17, 2019 21:07:16

akl спасибо за подсказку) в жизнь б не заметил такой недочет) в коде ведомого мк накосячил а в мастере правильно написал)

вот исправленные исходники)
Код:
;шаблон для атмега8
;
;настройка SPI , МК настроим в режим Master
;
;
;однократная передача байта по SPI от нашего МК(Master) к ведомому МК(Slave). оба атмега8
;режим работы SPI 0
;скорость работы fclk/128
;
;пин РВ2(SS) нашего МК подключен к транзистору, а транзистор подключен к пину РВ2(SS) инверсно.  (смысл решения таков,если  наш пин РВ2 выставить в 1, то  пин РВ2 ведомого МК сбросится в 0)
;
;
;
;
;
;
;
;;****************************************************************************************
.cseg
.include "m8Adef.inc"
;
;;***********************************************************************
.org   $000 rjmp RESET                  ;Reset Handler
;.org   $001 reti                       ;rjmp EXT_INT0 ; IRQ0 Handler
;.org   $002 reti                       ;rjmp EXT_INT1 ; IRQ1 Handler
;.org   $003 reti                       ;rjmp TIM2_COMP ; Timer2 Compare Handler
;.org   $004 reti                       ;rjmp TIM2_OVF ; Timer2 Overflow Handler
;.org   $005 reti                        ;rjmp TIM1_CAPT ; Timer1 Capture Handler
;.org   $006 reti                       ;rjmp TIM1_COMPA ; Timer1 CompareA Handler
;.org   $007 reti                       ;rjmp TIM1_COMPB ; Timer1 CompareB Handler
;.org   $008 reti                       ;rjmp TIM1_OVF ; Timer1 Overflow Handler
;.org   $009 reti                       ;rjmp TIM0_OVF ; Timer0 Overflow Handler
.org   $00a rjmp SPI_STC                               ; SPI Transfer Complete Handler
;.org   $00b reti                       ;rjmp USART_RXC ; USART RX Complete Handler
;.org   $00c reti                       ;rjmp USART_UDRE ; UDR Empty Handler
;.org   $00d reti                       ;rjmp USART_TXC ; USART TX Complete Handler
;.org   $00e reti                       ;rjmp ADC ; ADC Conversion Complete Handler
;.org   $00f reti                       ;rjmp EE_RDY ; EEPROM Ready Handler
;.org   $010 reti                       ;rjmp ANA_COMP ; Analog Comparator Handler
;.org   $011 reti                       ;rjmp TWSI ; Two-wire Serial Interface Handler
;.org   $012 reti                       ;rjmp SPM_RDY ; Store Program Memory Ready Handler




;***********************************************************************
RESET:

  cli                         ;запретить все прерывания

     ldi r16, low(RAMEND)     ;загрузка указателя стека
     out SPL, r16

     ldi r16, high(RAMEND)    ;загрузка указателя стека
     out SPH, r16




     ldi r16, 0b11111111    ; порт D  на выход
     out DDRD, r16


 
 
   
                         




     ldi r17, (1<<PB3)|(1<<PB5)|(1<<PB2)
     out DDRB, r17                      ; биты  РВ3(MOSI), РВ5(SCK), РВ2(SS) настроим  на выход (Для ведущего настроить MOSI, SCK, SS на выход, MISO на вход)
 
     ldi r16, (1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0)|(1<<SPIE)    ; выставим бит номер 6(SPE) в 1, включим модуль SPI, выставим бит номер 4(MSTR) в 1 настроим наш МК в режим Master. бит SPIE разрешает прерывание по SPI
     out SPCR, r16                      ; биты номер 3(CPOL) и 2(СPHA) сброшены в 0, настроен режим работы 0 по умолчанию
                                        ; бит номер 5(DORD) сброшен в 0 по умолчанию, поэтому первым в передаче данных  передается 7-ой старший бит
                              ; бит (SPI2X) регистра SPSR по умолчанию сброшен в 0,  биты 1(SPR1) , 0(SPR0) регистра SPCR выставим в 1 и работает режим скорости fclk/128


     cbi PortB,2                   ; сбросим в 0 бит  РВ2(SS) активизируем ведомый МК низким уровнем сигнала на передачу данных
                           ; .




     
     ldi r16, 0b10000111    ; запишем число в регистр данных SPDR и передача байта по SPI автоматически началась
     out SPDR, r16
 

 
 
 
 
 
  sei                         ;разрешаем прерывания


;***********************************************************************************************

MAIN:


     rjmp MAIN

;*********************************************************************************************** 

SPI_STC:



   


     in r16, SPDR    ; читаем регистр данных SPDR и пишем прочтеное в r16
     out PORTD, r16  ; пишем число из регистра r16 в PORTD






  reti




ведомый

Код:
;шаблон для атмега8
;
;настройка SPI , МК настроим в режим Slave
;
;
;однократный прием байта по SPI от  МК(Master) к нашему МК(Slave). оба атмега8
;режим работы SPI 0
;скорость работы fclk/128
;
;пин РВ2(SS) нашего МК подключен к транзистору, а транзистор подключен к пину РВ2(SS) инверсно.  (смысл решения таков,если  наш пин РВ2 выставить в 1, то  пин РВ2 ведомого МК сбросится в 0)
;
;
;
;
;
;
;
;;****************************************************************************************
.cseg
.include "m8Adef.inc"
;
;;***********************************************************************
.org   $000 rjmp RESET                  ;Reset Handler
;.org   $001 reti                       ;rjmp EXT_INT0 ; IRQ0 Handler
;.org   $002 reti                       ;rjmp EXT_INT1 ; IRQ1 Handler
;.org   $003 reti                       ;rjmp TIM2_COMP ; Timer2 Compare Handler
;.org   $004 reti                       ;rjmp TIM2_OVF ; Timer2 Overflow Handler
;.org   $005 reti                        ;rjmp TIM1_CAPT ; Timer1 Capture Handler
;.org   $006 reti                       ;rjmp TIM1_COMPA ; Timer1 CompareA Handler
;.org   $007 reti                       ;rjmp TIM1_COMPB ; Timer1 CompareB Handler
;.org   $008 reti                       ;rjmp TIM1_OVF ; Timer1 Overflow Handler
;.org   $009 reti                       ;rjmp TIM0_OVF ; Timer0 Overflow Handler
.org   $00a rjmp SPI_STC             ; SPI Transfer Complete Handler
;.org   $00b reti                       ;rjmp USART_RXC ; USART RX Complete Handler
;.org   $00c reti                       ;rjmp USART_UDRE ; UDR Empty Handler
;.org   $00d reti                       ;rjmp USART_TXC ; USART TX Complete Handler
;.org   $00e reti                       ;rjmp ADC ; ADC Conversion Complete Handler
;.org   $00f reti                       ;rjmp EE_RDY ; EEPROM Ready Handler
;.org   $010 reti                       ;rjmp ANA_COMP ; Analog Comparator Handler
;.org   $011 reti                       ;rjmp TWSI ; Two-wire Serial Interface Handler
;.org   $012 reti                       ;rjmp SPM_RDY ; Store Program Memory Ready Handler




;***********************************************************************
RESET:

  cli                         ;запретить все прерывания

     ldi r16, low(RAMEND)     ;загрузка указателя стека
     out SPL, r16

     ldi r16, high(RAMEND)    ;загрузка указателя стека
     out SPH, r16

     ldi r16, 0b11111111    ;порт D на выход целиком
     out DDRD, r16





     ldi r17, (1<<PB4)                  ;
     out DDRB, r17                      ; бит PB4(MISO)  устанавливаем в 1, у ведомого МК (MISO) ставится на выход а  (MOSI), (SS), (SCK) на вход





 
     ldi r16, (1<<SPE)|(1<<SPR1)|(1<<SPR0)|(1<<SPIE)       ; выставим бит номер 6(SPE) в 1, включим модуль SPI,  бит номер 4(MSTR) сброшен в 0, наш  МК в режим (Slave). разрешим прерывание битом (SPIE)
     out SPCR, r16                      ; биты номер 3(CPOL) и 2(СPHA) сброшены в 0, настроен режим работы 0 по умолчанию
                                        ; бит номер 5(DORD) сброшен в 0 по умолчанию, поэтому первым в передаче данных  передается 7-ой старший бит
                              ; бит (SPI2X) регистра SPSR по умолчанию сброшен в 0,  биты (SPR1) , (SPR0) регистра SPCR выставим в 1 и работает режим скорости fclk/128


   




     
     ldi r16, 0b10000111    ; запишем число в регистр данных SPDR для отправки мастеру, чтоб видеть что передача произошла
     out SPDR, r16
 

 
 
 
 
 
  sei                         ;разрешаем прерывания


;***********************************************************************************************

MAIN:


     rjmp MAIN


;**********************************************************************************************


SPI_STC:


     in r16, SPDR    ;читаем регистр данных SPDR модуля SPI и пишем число в регистр r16
     out PORTD, r16   ;пересылаем эти данные в порт D из регистра r16

     


reti







Изображение

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

Вс мар 17, 2019 21:13:47

Работает?

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

Вс мар 17, 2019 21:22:58

bafomet911 да работает, скрин симуляции выше в картинке)

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

Пн мар 18, 2019 09:14:13

Ага, спасибо. Скоро тоже буду подобное делать. Только я буду делать ответ в зависимости от команды мастера..
Ответить