посоветуйте где я накосячил?) хочу передать по 1 байту между 2 МК атмега8 по SPI. число передаю 0b10000111 но приходит в оба МК не эти числа, ощущение что не хватило 1 такта что бы все число пришло?
фото симуляции светодиоды в симуляции типа индикаторы.
прошивка мастера Спойлер
Код:
;шаблон для атмега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
ldi r16, low(RAMEND) ;загрузка указателя стека out SPL, r16
ldi r16, high(RAMEND) ;загрузка указателя стека out SPH, r16
ldi r16, 0b11111111 ; порт D на выход out DDRD, r16
sbi PortB,2 ; устоновим в 1 бит РВ2(SS) заблокируем передачу данных ведомого МК высоким уровнем сигнала
nop nop nop nop nop nop nop nop nop
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
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
Слейв мастеру начинает слать что-то по spi У мастера срабатывает прерывание, т.к. по шине начинается передача.. И что же как вы думаете делает мастер!? Барабанная дробь!! Первой инструкцией в обработчике прерываний,вместо того чтоб принять байт, он запрещает слейву что слать и только потом читает регистр с данными, в котором конечно же мусор.
Меня всерьёз принимать не стоит. Предупреждаю что сам только знакомлюсь с миром микроконтроллеров и наверняка могу ошибаться...
Добавлено after 9 minutes 57 seconds: Я бы попробовал сначала дождаться пока данные обменяются, а только потом запретил передачу.. х.з. могу и ошибаться
Прячем тексты исходника под спойлер! Иначе собственные вопросы/ответы искать кошмарус будет. С собственно с аппаратным блоком SPI я пока не занимался - там и согласований/настроек моного и применение только "стандартными" 8-битными посылками. Добавляем настройку и обработку прерываний по завершению передачи/приема (при необходимости их анализ и перенастройку режимов работы), согласование скоростей обмена, внутренний буфер данных для приема и передачи, логику определения размера пакета и типа данных. Тогда уже и результат будет. Штука простая, если приемник аппаратный - вида "регистр с мозгами". А между МК обмен значительно посложнее (с учетом того, что и своих основных задач там достаточно). Вобщем разбираться надо в том числе и с аппаратной начинкой. К примеру... По протоколу мастер выполнил передачу и ждет данные от слейва. Следовательно модуль SPI мастера должен быть сразу же после передачи перенастроен на прием, а слейв перед своей передачей обязан выдержать определенную технологическую паузу.
По протоколу мастер выполнил передачу и ждет данные от слейва. Следовательно модуль SPI мастера должен быть сразу же после передачи перенастроен на прием, а слейв перед своей передачей обязан выдержать определенную технологическую паузу.
не говорите ерунды: обмен по SPI всегда идет ОДНОВРЕМЕННО, поэтому когда мастер закончил передачу, он уже имеет ответ ведомого. если технически невозможно реализовать одновременный обмен, вводится "лишний" байт для обмена: мастер передает первый байт, на который слейв реагирует, а потом байт-пустышку (обычно 0xFF, не вжано, лишь бы восемь фронтов SCK было), а слейв, принв первый байт тут же ставит в SPDR свой ответ и уже сам игнорирует пришедший байт-пустышку.
никакой перенастройки мастера и/или слейва не требуется!
разница между ними только в том, что слейв не генерирует фронты SCK, а мастер - генерирует.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Это при условии, что передающей определена только одна из сторон. Т.е. один МК только как мастер и один МК только как слейв, генератором тактов может быть только мастер. Так же как и инициатором цикла обмена данными также является только мастер. А если каждый из МК может быть инициатором обмена? Причем в произвольный момент времени ("мультимастер")...
Добавлено after 30 seconds: Re: Вопрос по SPI на asm Аж самому интересно стало...
Добавлено after 4 minutes 39 seconds: Re: Вопрос по SPI на asm Исходя из информации от arv передачу инициализирует мастер и только он.. значит мастеру прерывание spi без надобности, а вот слейв в этом прерывании должен какие-то данные пихать в spdr, правильно ли я понимаю?
лично я никогда слейвов на SPI не делал - нужда не возникала. а мастер делается проще пареной репы, особенно в случае единствнного слейва. но по логическому размышлению сделать слейва без прерываний затруднительно, и таки да, по прерыванию он должен посмотреть, что получил от мастера и побыстрее выдать ответ.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Я тоже только датчики опрашивал по спи. А прерывание интересно когда срабатывает, перед тем как первый бит поступит или после первого бита? Вы там что то про запасной бит писали..
3 вечера боюсь с этой проблемой) пока не догоняют в чем дело. Одновременный обмен байтом, и посыл обоих в порт д, чтоб зажеч светодиоды и радостно улыбался мол все работает, ан нет, где то косяк) прибывал всякое, менял полярность передачи в прошивках, норы добавлял и убирал, в симуляторе подтягивал линии к земле и к питанию через резюки,не помогает
_________________ глаза боятся, а руки что то не делают))
Ежли б местом назначения был не МК, а обычный 595й регистр и/или какой дисплейчик с протоколом SPI - никаких проблем не будет. Однако запхнуто ДВА МК - тут или жестко ставить один из них в режим приема а другой только на передачу (до прояснения более сложных вариантов), либо применять I2C/UART в качестве аппаратных модулей.
при чем тут первый бит? прервание возникает после приема/передачи последнего, т.е. 8-го бита.
Соответственно алгоритм опроса слейва мне видится так: СпойлерМастер шлёт байт (возможно команда какие именно данные хочет мастер) После передачи первого байта, мастер имеет мусор в посылке от слейва(прерывания то ещё нет) У слейва как только обменялся последний бит, срабатывает прирывание, в котором он считывает команду из spdr и в соответствии с командой сует в шину данные. Далее мастер, чтобы получить актуальные данные, делает ещё одну передачу(нулей например) и получает от слейва актуальные данные соответственно команде из предыдущей посылке. Слейв получил байт. Сработало прерывание. Видит что нули и ничего не делает(как вариант пихает нули обратно) Как то так???
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
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
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 53
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения