Можно уложиться в 2 такта на битMeteor писал(а):Если не ошибаюсь, то минимум - 4 такта на бит.
Т.о. 8 бит будут переданы за 32 такта.
Ассемблер (ASM) для AVR в вопросах и ответах
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- Реклама
- Сообщения: 3961
- Зарегистрирован: Пн июл 13, 2009 14:37:39
- Откуда: Московская область, наукоград.....
Пропустил слово "программная" и ответил на аппаратный SPI.
Не получится за 2 такта, ибо это время необходимое на импульс записи (SCK). К этому добавить сдвиг (1 команда)+ определение бита С (2 команды)+ установка/сброс бита (2 команды) итого минимум 7 команд на бит.Можно уложиться в 2 такта на бит
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Я тожеMeteor писал(а):Пропустил слово "программная" и ответил на аппаратный SPI.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Короче, получилось 84 такта (считая инструкцию вызова). Может можно сделать что-то ещё?
Код: Выделить всё
SPI_send_byte:
CLR SPIdataRX
cbi PORTB,MOSI
SBRC SPIdataTX,7
sbi PORTB,MOSI
sbi PORTB,SCK
SBIC PINB,MISO
ori SPIdataRX,0b10000000
cbi PORTB,SCK
cbi PORTB,MOSI
SBRC SPIdataTX,6
sbi PORTB,MOSI
sbi PORTB,SCK
SBIC PINB,MISO
ori SPIdataRX,0b01000000
cbi PORTB,SCK
cbi PORTB,MOSI
SBRC SPIdataTX,5
sbi PORTB,MOSI
sbi PORTB,SCK
SBIC PINB,MISO
ori SPIdataRX,0b00100000
cbi PORTB,SCK
cbi PORTB,MOSI
SBRC SPIdataTX,4
sbi PORTB,MOSI
sbi PORTB,SCK
SBIC PINB,MISO
ori SPIdataRX,0b00010000
cbi PORTB,SCK
cbi PORTB,MOSI
SBRC SPIdataTX,3
sbi PORTB,MOSI
sbi PORTB,SCK
SBIC PINB,MISO
ori SPIdataRX,0b00001000
cbi PORTB,SCK
cbi PORTB,MOSI
SBRC SPIdataTX,2
sbi PORTB,MOSI
sbi PORTB,SCK
SBIC PINB,MISO
ori SPIdataRX,0b00000100
cbi PORTB,SCK
cbi PORTB,MOSI
SBRC SPIdataTX,1
sbi PORTB,MOSI
sbi PORTB,SCK
SBIC PINB,MISO
ori SPIdataRX,0b00000010
cbi PORTB,SCK
cbi PORTB,MOSI
SBRC SPIdataTX,0
sbi PORTB,MOSI
sbi PORTB,SCK
SBIC PINB,MISO
ori SPIdataRX,0b00000001
cbi PORTB,SCK
retЭто получилось для любых передаваемых значений? По моим прикидкам, в худшем случае только на перекачку байта уйдёт 88 тактов.AI_Disable писал(а):Короче, получилось 84 такта (считая инструкцию вызова).
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
- Реклама
Да, точно, считал, кода на приём и передачу 0x00. С 0xFF вышло 108 тактов, теперь даже в 100 не укладываюсь...
Насколько критично, чтобы остальные порты в это время работали нормально?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Точно! Спасибо, этим способом сэкономится ещё 32 такта, что меня уже устраивает.Gudd-Head писал(а):Насколько критично, чтобы остальные порты в это время работали нормально?
В общем, вы наверное поняли, но я всё же на всякий случай изложу свою мысль:AI_Disable писал(а):Точно! Спасибо, этим способом сэкономится ещё 32 такта, что меня уже устраивает.
Установить все порты, кроме одного на вход. В какой-нить регистр засунуть то, что мы хотим передать. После каждого переданного бита его содержимое сдвигать влево (вправо), возможно через перенос. Так же сдвигать регистр с принятой информацией.
Самый шик был бы объединить эти два регистра: т.е. мы передали бит, на его место записали принятый, сдвинули регистр. И так 7 (один раз можно не сдвигать) или 8 раз подряд
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Вообще, нет, я подумал о другом: пользовать инструкцию out вместо sbi и cli. Ваша идея понравилась, но боюсь, что для её реализации, придётся повесить на землю резики для SS и SCK и подтянуть к плюсу SS.
Господа знающие, как можно общаться с вот такого рода массивом?
это собственно шрифт, выгружать выборочно строками, одна поправка, код не полный, в строке массива 48 байт
Код: Выделить всё
.db 0b00011110,0b00111111,0b00011111,0b00111111
.db 0b00100001,0b00100001,0b00100001,0b00100001
.db 0b00100001,0b00000001,0b00100001,0b00000001
.db 0b00100001,0b00011111,0b00011111,0b00000001
.db 0b00111111,0b00100001,0b00100001,0b00000001
.db 0b00100001,0b00100001,0b00100001,0b00000001
.db 0b00100001,0b00011111,0b00011111,0b00000001
.db 0b00000000,0b00000000,0b00000000,0b00000000
Ммм... Ну, всякие команды типа LD или LPM, например.DR_MORRO писал(а):Господа знающие, как можно общаться с вот такого рода массивом?
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Не обязательно. Главное, чтобы во время работы программного SPI из прерываний состояние этих портов не менялось.Gudd-Head писал(а):Установить все порты, кроме одного на вход.
Когда речь идёт о максимальной скорости, сдвигать невыгодно. Цикл всё равно развёрнут и в каждом месте выгоднее по скорости применить нужную маску, чем всё время одну и ту же маску и сдвиг. Кроме того, полезно вспомнить о BLD/BSTGudd-Head писал(а):После каждого переданного бита его содержимое сдвигать влево (вправо), возможно через перенос. Так же сдвигать регистр с принятой информацией.
Как-то так (в зависимости от нужного режима SPI, фаз сдвига и опроса), тело функции без расходов на вызов и на ret - 66 тактов независимо от данных.
Код: Выделить всё
.nolist
#define __SFR_OFFSET 0
#include <avr/io.h>
.list
.text
.global spi_io
#define txbuf r16
#define rxbuf r17
#define temp r18
#define SCK 0
#define MOSI 1
#define MISO 2
spi_io:
clr rxbuf
in temp, PORTB
.set i, 7
.rept 8
ori temp, (1 << SCK)
bst txbuf, i
bld temp, MOSI
out PORTB, temp
andi temp, ~(1 << SCK)
out PORTB, temp
sbic PINB, MISO
ori rxbuf, (1 << i)
.set i, i-1
.endr
ret
.endЛень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
avreal, спасибо, но я не могу использовать инструкцию out, т.к. другие пины порта B заняты.
Что значит "заняты" ?
В самом начале командойсохраняем текущее состояние выводов (значение на ножке для выходных, включенность pull-up для входных) и оно не меняется в процессе работы процедуры.
Конечно, если состояние PORTB меняется из прерываний, то так делать нельзя.
В самом начале командой
Код: Выделить всё
in temp, PORTBКонечно, если состояние PORTB меняется из прерываний, то так делать нельзя.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Там ШИМ.avreal писал(а):Что значит "заняты" ?
Если ШИМ аппаратный, это не должно мешать. Посмотрите картинки Alternate Port Functions в разделе I/O ports в документации. Если включается аппаратная альтернативная функция, то выход мультиплексором переключается с триггера в PORTx на ту аппаратную функцию.
Кстати, в варианте без использования команд out тоже можно подсократить время для тех контроллеров, у которых есть PORTx toggle by PINx write, т.е., кажется, для всех достаточно новых.
В самом начале в свободный регистр загрузить константу с маской для вывода SCK (1 такт) и установить SCK в начальное состояние командой SBI или CBI с регистром PORTx (2 такта).
А в процессе вывода вместо пары двухтактовых команд SBI/CBI для выдачи ипульса на SCK использовать две однотактовых команды OUT PINx, которыми инвертировать состояние PORTx.
Итого экономия (1+1)*8 - 3 = 13 тактов на процедуре.
Кстати, в варианте без использования команд out тоже можно подсократить время для тех контроллеров, у которых есть PORTx toggle by PINx write, т.е., кажется, для всех достаточно новых.
В самом начале в свободный регистр загрузить константу с маской для вывода SCK (1 такт) и установить SCK в начальное состояние командой SBI или CBI с регистром PORTx (2 такта).
А в процессе вывода вместо пары двухтактовых команд SBI/CBI для выдачи ипульса на SCK использовать две однотактовых команды OUT PINx, которыми инвертировать состояние PORTx.
Итого экономия (1+1)*8 - 3 = 13 тактов на процедуре.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Всю свою сознательную жизнь писал только на си, сейчас вот решил хоть немного освоить асм. Этот асм уже кажется просто ужосом каким-то
Тов. avreal, не могли бы вы свой предыдущий пост выразить в прокомментированном коде?
Я привык, что компилятор всю сложную работу за меня делал, теперь вот пришло время отвыкать...
Я привык, что компилятор всю сложную работу за меня делал, теперь вот пришло время отвыкать...
- Сообщения: 3
- Зарегистрирован: Пн ноя 09, 2009 19:45:54
Всем привет! вот написал код для RC5, не могли бы вы уважаемые коты взглянуть на мой код подсказать где у меня ошибки. В общем код вроде работает но показывает только в comands 2 paзных числа при нажатии пульта ДУ. исходник прилагаю
- Вложения
-
- RC5moy.asm
- (5.14 КБ) 486 скачиваний
Впал в ступор...
Дано:
Студия 4.18 SP2 b.700
Требуется:
запустить Т0 с предделителем 1/8, нормальный режим, прерывание по переполнению
запустить Т1 с тактовой Fo, нормальный режим, прерывание по переполнению
Собс..но код:
Т0 - запускается и тикает, причем и в студии и в железе
Т1 - молчит как "рыба об лед", и там и там.
к чему бы это?
Дано:
Студия 4.18 SP2 b.700
Требуется:
запустить Т0 с предделителем 1/8, нормальный режим, прерывание по переполнению
запустить Т1 с тактовой Fo, нормальный режим, прерывание по переполнению
Собс..но код:
Код: Выделить всё
; настройка таймеров
; T0
clr tmp
out TCCR0A,tmp
ldi tmp,2 ; Fo/8
out TCCR0B,tmp
ldi tmp,1<<TOIE0
out TIMSK0,tmp
; T1
clr tmp
out TCCR1A,tmp
out TCCR1C,tmp
ldi tmp,1
out TCCR1B,tmp
ldi tmp,1<<TOIE1
out TIMSK1,tmp
Т1 - молчит как "рыба об лед", и там и там.
к чему бы это?



