Вопрос по SPI на asm
Re: Вопрос по SPI на asm
Всем спасибо, за участие... много интересного узнал... следующий этап - реализация в железе, но это другая история...
- Реклама
-
Alkul
- Держит паяльник хвостом
- Сообщения: 933
- Зарегистрирован: Ср апр 13, 2011 11:09:20
- Откуда: Екатеринбург
Re: Вопрос по SPI на asm
То есть, если у Вас 10 одинаковых датчиков, Вы линейно 10 раз повторите код опроса датчика, код обработки данных и код передачи по SPI?roman.com писал(а): -измерил датчик 1
-обработал данные
-закинул в SPI... SPI автоматом передает. А я измеряю следующие датчики...
...
-измерил датчик N
-обработал данные
-закинул в SPI... SPI автоматом передает. А я измеряю следующие датчики...
Вопросов больше не имею...
Re: Вопрос по SPI на asm
Нет, в цикле.
N++; // где N - номер датчика.
Хотя... кому как больше нравится))
-
Alkul
- Держит паяльник хвостом
- Сообщения: 933
- Зарегистрирован: Ср апр 13, 2011 11:09:20
- Откуда: Екатеринбург
Re: Вопрос по SPI на asm
Тогда у Вас проблемы с терминологией.Alkul писал(а):То есть, если у Вас 10 одинаковых датчиков, Вы линейно 10 раз повторите кодroman.com писал(а):Нет, в цикле.
Вы сами написали:
По определению, линейный алгоритм - это алгоритм, не содержащий циклов и ветвлений.roman.com писал(а):Ну и нафига эта мне головная боль с подпрограммами при линейном алгоритме?
Re: Вопрос по SPI на asm
Видимо меня не так поняли... ))
Я показал на примере линейного алгоритма как понять когда собирать данный со слейва.
Затем Вы меня спросили
А Вы, как я понял, для того что бы измерить 10 датчиков и отправить 10 байт на индикатор, предлагаете использовать подпрограмму ?))
У меня нет проблем с терминологией. Я попытался ответить на вопрос vit007Alkul писал(а):Тогда у Вас проблемы с терминологией.
vit007 писал(а):Значит аппаратный SPI работает параллельно программе, может поэтому и надо ждать появления флаг, а то как понять когда собирать данный со слейва...
Я показал на примере линейного алгоритма как понять когда собирать данный со слейва.
Затем Вы меня спросили
Т.е. я так понял Вы меня спросили: буду ли я использовать в своей программе линейный алгоритм? Я Вам ответил - нет. Если мне нужно будет измерить 10 датчиков и отправить 10 байт на индикатор, то я для этого использую цикл.Alkul писал(а):То есть, если у Вас 10 одинаковых датчиков, Вы линейно 10 раз повторите код опроса датчика, код обработки данных и код передачи по SPI?
А Вы, как я понял, для того что бы измерить 10 датчиков и отправить 10 байт на индикатор, предлагаете использовать подпрограмму ?))
- Реклама
-
Alkul
- Держит паяльник хвостом
- Сообщения: 933
- Зарегистрирован: Ср апр 13, 2011 11:09:20
- Откуда: Екатеринбург
Re: Вопрос по SPI на asm
Хм-м... Перечитайте еще раз свое сообщениеroman.com писал(а):Т.е. я так понял Вы меня спросили: буду ли я использовать в своей программе линейный алгоритм? Я Вам ответил - нет. Если мне нужно будет измерить 10 датчиков и отправить 10 байт на индикатор, то я для этого использую цикл.
Вы сказали:
То есть, у вас опрос "кучи датчиков" делается в линейном алгоритме? Я читаю, как написано. Если и есть проблемы, то это не у меня с пониманием, а у Вас с изложением.roman.com писал(а):А если у меня простой линейный алгоритм? Например есть куча датчиков, их надо вывести на экран...
Именно так. Подпрограмма опроса датчика, подпрограмма отправки данных на индикатор. Если участок кода используется в программе более одного раза, имеет смысл выделить его в подпрограмму.roman.com писал(а):А Вы, как я понял, для того что бы измерить 10 датчиков и отправить 10 байт на индикатор, предлагаете использовать подпрограмму ?))
Надо уметь видеть в программе главное и вспомогательное. Главное - это общий алгоритм. Если Вы загромождаете второстепенными действиями основную часть алгоритма, Вы, во-первых, делаете его менее читаемым. То есть, усложняете себе же программирование. Во-вторых, очень удобно делать отладку кода, двигаясь от простого к сложному. Когда простейшая подпрограмма отлажена, ничто не мешает включить её в более сложную.
Вы сказали
так, как будто для этого нужно письменный запрос в Atmel подавать. Уверяю Вас, использование команд CALL/RCALL - RET совершенно бесплатное. И механизм подпрограмм более гибок, чем механизм циклов.предлагаете использовать подпрограмму ?
Под спойлером пример работы с датчиком DS18S20. В моей программе это работает так - в нужный момент датчику посылается команда начать измерения. Таймер по прерываниям отсчитывает 2-ух миллисекундные квантили времени. Когда с момента посылки команды начать измерения проходит время, необходимое датчику на выполнение преобразования, в обработчике прерывания таймера устанавливается бит, означающий необходимость выполнить чтение результата измерения. В основной программе циклически проверяется этот бит, и если он установлен, то вызывается подпрограмма TERMO_READ. Посмотрите код, он гораздо читабельней, чем если бы все свалить в одну кучу.
Спойлер
Код: Выделить всё
;Подпрограмма, выполняющая однократный опрос термодатчика и занесение полученных значений температуры
;в память (переменные DS1L:DS1H)
TERMO_READ:
rcall DS1RESET ;Сброс термодатчика
brtc TERMO_R1 ;Если бит T сброшен (нет ошибки датчика), то перейти на TERMO_R1
rjmp TERMOERR ;Ошибка термодатчика, индицировать символы ошибки и отключить нагрев
TERMO_R1:
ldi BYTEDS,$CC ;Код команды обращения к датчику без указания его 64-битного адреса
rcall DS1WRITE ;Занести команду в термодатчик
ldi BYTEDS,$BE ;Код команды чтения 9 байт из памяти датчика
rcall DS1WRITE ;Занести команду в термодатчик
clr R16 ;Обнулить ячейку, хранящую значение CRC
sts CRC8,R16 ;перед расчетом CRC для принятого пакета байт
rcall DS1READ ;Прочитать нулевой байт из памяти термодатчика (Temperature LSB)
rcall CRC_8 ;Вычислить CRC для нулевого байта
sts DS1L,BYTEDS ;Занести прочитанный младший байт температуры в ячейку DS1L
rcall DS1READ ;Прочитать первый байт из памяти термодатчика (Temperature MSB)
rcall CRC_8 ;Вычислить CRC для первого байта
sts DS1H,BYTEDS ;Занести прочитанный старший байт температуры в ячейку DS1H
ldi R16,0x07 ;Организовать цикл для чтения оставшихся семи байт памяти термодатчика
mov R14,R16 ;
TERMO_R2: rcall DS1READ ;Прочитать байт из памяти термодатчика
rcall CRC_8 ;Вычислить CRC для прочитанного байта
dec R14 ;Декремент счетчика прочитанных байт
brne TERMO_R2 ;Если прочитаны не все байты, вернуться на метку TERMO_R2
mov R16,STAT2 ;Загрузить в рег.R16 значение байта STAT2
andi R16,~((1<<TIMEDS)|(1<<DSCONV)|(1<<DSREAD)) ;Так как опрос термодатчика выполнен,
;сбросить все биты, относящиеся к измерению температуры
mov STAT2,R16 ;Сохранить в памяти новое значение байта STAT2
lds R16,CRC8 ;Занести в рег.R16 рассчитанную для 9-ти байтного пакета CRC
tst R16 ;Если пакет принят корректно, то расчет CRC для байта CRC должен дать нуль
brne TERMOERR ;Если результат расчета не нуль, то пакет принят с ошибкой, перейти на метку TERMOERR
rcall TEMPSYMB ;Иначе пакет принят корректно, вызвать подпрограмму, проверяющую необходимость
;включения нагреватели и подготавливающую значения для индикации температуры
ret ;
;Подпрограмма формирования RESET для интерфейса 1-Wire и чтения ответа датчика PRESENCE PULSE
;Если термодатчик не ответил, подпрограмма установит бит T
DS1RESET: cli ;Запретить прерывания для неразрывности формирования RESET
sbi DSDDR,DS1 ;Перевод вывода на передачу
cbi DSPORT,DS1 ;Сброс выхода в ноль, формирование Trstl
rcall DEL05MS ;Задержка 500 мкс
cbi DSDDR,DS1 ;Перевод вывода на прием
sbi DSPORT,DS1 ;и ожидание ответа датчика "Presence pulse"
rcall DEL10MK ;Задержка 10 мк
rcall DEL10MK ;Задержка 10 мк
ldi R24,$A0 ;Цикл для непрерывного чтения данных в течение 100 мкс
;если ответа нет, то ошибка
DS1RES_L: dec R24 ;
breq DS1RES_ERR ;Если цикл непрерывного чтения завершен, то ошибка
sbic DSPIN,DS1 ;Проверка состояния на шине данных от термодатчика
rjmp DS1RES_L ;если 1, то ответа датчика пока нет, возврат на ожидание
clt ;Иначе на линии 0, ответ датчика получен, сбросить бит Т
rcall DEL05MS ;Задержка 500 мкс
bld STATUS,DSFAIL_ST ;Сбросить бит DSFAIL_STв байте STATUS, т.к. термодатчик исправен
DS1RES_1: sei ;Неразрывный процесс окончен, разрешить прерывания
ret ;
DS1RES_ERR:
set ;Термодатчик не ответил, установить бит Т
bld STATUS,DSFAIL_ST ;Установить бит DSFAIL_STв байте STATUS, т.к. термодатчик неисправен
rjmp DS1RES_1 ;Переход для разрешения прерываний и завершения подпрограммы
;Подпрограмма чтения одного байта данных для интерфейса 1-Wire, результат возвращается в регистре BYTEDS
DS1READ: cli ;Запретить прерывания для неразрывности цикла чтения байта
ldi R24,8 ;В рег.R24 счетчик принятых бит
DS1READ2: cbi DSPORT,DS1 ;Сброс выхода в 0, формирование Trdv
sbi DSDDR,DS1 ;Переключение вывода на передачу
rcall DEL2MK7 ;Задержка 2,7мкс
cbi DSDDR,DS1 ;Переключение вывода на приём
sbi DSPORT,DS1 ;Резистор подтяжки линии к питанию включен
rcall DEL10MK ;Задержка 10мкс
clc ;Сбросить бит С перед проверкой состояния линии
sbic DSPIN,DS1 ;Если на линии лог.0, то пропустить следующую команду
DS1BIN: sec ;Иначе на линии лог.1, установить бит С
ror BYTEDS ;Сдвинуть бит С в регистр результата
DS1DELAY: rcall DEL60MK ;Задержка 60мкс
dec R24 ;Декремент счетчика принятых бит
brne DS1READ2 ;Если счетчик принятых бит не равен 0, то возврат для приёма следующего бита
rjmp DS1RES_1 ;Иначе байт принят, переход для разрешения прерываний и завершения подпрограммы
;Подпрограмма записи одного байта данных для интерфейса 1-Wire, байт для отправки должен находится в BYTEDS
DS1WRITE: cli ;Запретить прерывания для неразрывности цикла записи байта
ldi R24,8 ;В рег.R24 счетчик отправленных бит
DS1COMP: cbi DSPORT,DS1 ;Сброс выхода в ноль, формирование Tlow1
sbi DSDDR,DS1 ;Переключение выхода на передачу
rcall DEL2MK7 ;Задержка 2,7мкс
ror BYTEDS ;Отправка байта происходит младшим битом вперед
brcc DS1WR0 ;Проверка бита С на 0. Если бит С равен нулю, отправляемый бит - нуль,
;переход на DS1WR0
sbi DSPORT,DS1 ;Иначе отправляемый бит - единица
DS1WR0: rcall DEL60MK ;Задержка 60мкс
sbi DSPORT,DS1 ;Установка строгой "1" на 2 мкс
rcall DEL2MK7 ;Задержка 2,7мкс
dec R24 ;Декремент счетчика отправленных бит
brne DS1COMP ;Если отправлены не все биты, вернуться на DS1COMP
cbi DSDDR,DS1 ;Иначе все биты переданы,линию данных - в состояние входа, резистор подтяжки
;обеспечит лог.1 на линии данных
rjmp DS1RES_1 ;Переход для разрешения прерываний и завершения подпрограммыRe: Вопрос по SPI на asm
Всё что Вы тут написали, именно так я и делаю. И так делают все.)) У меня куча подпрограмм под разные аппаратные/программные интерфейсы.. индикаторы.. датчики... фильтры... контрольные суммы CRC-8/16/32... и т.д. и т.п... Я так же как и все копирую отлаженные мной подпрограммы в новый проект. В основной программе вызываю нужную мне подпрограмму... можно по таймеру (в обработчике прерывания таймера что-то делаю)... можно по событию (ввод/вывод МК)... и т.д. и т.п. У меня всё как у всех))
)) Вообщето изначально был вопрос про SPI интерфейс. Человек не может разобраться как работает SPI интерфейс...
)) Вообщето изначально был вопрос про SPI интерфейс. Человек не может разобраться как работает SPI интерфейс...
vit007 писал(а):Значит аппаратный SPI работает параллельно программе?
А Вы, вместо того чтобы "на пальцах" объснить человеку как работает SPI интерфейс, начали рассказывать про оптимизацию алгоритма)) vit007 надо было просто почитать даташит и в протеусе поиграться с настройками и просто разобраться с SPI интерфейсом))vit007 писал(а):это правда, что предмет плохо знаю...
Пожалуйста)) Вообщем с SPI интерфейсом разобрались... переходим на следующий этап))vit007 писал(а):Всем спасибо, за участие... много интересного узнал... следующий этап - реализация в железе, но это другая история...
Re: Вопрос по SPI на asm
Эмулирую работу SPI в Proteus.
SPI-debugger работает в режиме монитора и корректно отслеживает передаваемые по линии SPI данные.
Но не пойму, что за знаки вопросов я вижу в окне дебаггера? (обведены зелёным).

Чё за импульзы я вижу на осциллограмме на линии MOSI перед передачей данных? (обведены зелёным)

Передаю вот таким стандартным кодом на ассемблере для AVR.
SPI-debugger работает в режиме монитора и корректно отслеживает передаваемые по линии SPI данные.
Но не пойму, что за знаки вопросов я вижу в окне дебаггера? (обведены зелёным).
Чё за импульзы я вижу на осциллограмме на линии MOSI перед передачей данных? (обведены зелёным)
Передаю вот таким стандартным кодом на ассемблере для AVR.
Код: Выделить всё
;загоняем биты в 74hc595
out SPDR, ShiftRegister4 ; передаём байт для 4-го 74hc595
Wait_SPI_Tranfer4: ;ожидание передачи байта
in temp, SPSR
sbrs temp, SPIF ;если флаг завершения передачи установлен,
rjmp Wait_SPI_Tranfer4 ;то пропускаем эту команду
out SPDR, ShiftRegister3 ; передаём байт для 3-го 74hc595
Wait_SPI_Tranfer3: ;ожидание передачи байта
in temp, SPSR
sbrs temp, SPIF ;если флаг завершения передачи установлен,
rjmp Wait_SPI_Tranfer3 ;то пропускаем эту команду
out SPDR, ShiftRegister2 ; передаём байт для 2-го 74hc595
Wait_SPI_Tranfer2: ;ожидание передачи байта
in temp, SPSR
sbrs temp, SPIF ;если флаг завершения передачи установлен,
rjmp Wait_SPI_Tranfer2 ;то пропускаем эту команду
out SPDR, ShiftRegister1 ; передаём байт для 1-го 74hc595
Wait_SPI_Tranfer1: ;ожидание передачи байта
in temp, SPSR
sbrs temp, SPIF ;если флаг завершения передачи установлен,
rjmp Wait_SPI_Tranfer1 ;то пропускаем эту командуRe: Вопрос по SPI на asm
Сдрасти уважаемые 
У кого нибудь удалось завести этот дисплей на аппаратном SPI? Я давно завёл его с помощью ногодрыга по 10 бит а вот аппаратный SPI пока не хочет, передаю ему по 16 бит где требуется 10. Кстати да, дисплей не требует таких диких задержек как HD4478.
У кого нибудь удалось завести этот дисплей на аппаратном SPI? Я давно завёл его с помощью ногодрыга по 10 бит а вот аппаратный SPI пока не хочет, передаю ему по 16 бит где требуется 10. Кстати да, дисплей не требует таких диких задержек как HD4478.


