Страница 170 из 400
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб дек 15, 2012 12:22:14
uwrtey
тогда может подскажите ..
в общем есть передатчик ( точнее кодер ) на 20 команд
который сначала опрашивает клавиатуру и записывает данные в ОЗУ, затем читает ОЗУ и если находит хоть одну нажатую кнопку идет на формирование посылки.
проблема в том что передатчик шлет неправильную посылку - а если конкретнее то шлет посылку кода кнопки из следующего столбца
вместо кода кнопки №1 посылается код кнопки №5 и самое интересное вместо кода кнопки №17 посылается код кнопки №1
как будто передача сместилась на 1 байт

но при этом еще и зациклилась!

в монтаже косяков нету....
ЗЫ код очень хорошо комментирован....
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб дек 15, 2012 12:53:59
Alexeyslav
Я сталкивался с подобным эффектом когда разрабатывал одно устройство. Проблема заключалась в том что процессы происходящие в электрической схеме были не так быстры как работает контроллер - он банально успевал считать состояние кнопок до того как напряжение на них нарастет до актуального состояния и поэтому получалось так что контроллер всегда считывал предыдущую строку. введи паузу между установкой напряжения на шине и считыванием состояния кнопок - буквально несколько микросекунд!
Емкость монтажа и входов контроллера, конечное сопротивление диодов делают свое дело - напряжение выбора столбцов несколько запаздывает от сигнала контроллера. Получается что считываем мы вторую линию но напряжение на входах держится еще от первой...
Идеальным вообще было бы избавится от задержек(мало ли пыль налипнет или что еще и увеличит емкость монтажа) переделав алгоритм сканирования - считывать состояние как бы с запаздыванием: вместо того чтобы считывать после установки напряжения на столбце, считывать линию ДО установки напряжения на столбце. Т.е. установили напряжение на первой линии и ждем следующего цикла сканирования, когда наступает очередь второй линии - считываем значение для ПЕРВОЙ линии и только после этого устанавливаем напряжение на второй и так далее. При непрерывном сканировании проблем никаких не должно возникнуть.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб дек 15, 2012 12:59:02
uwrtey
спасибо, попробую!
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб дек 15, 2012 19:10:54
uwrtey
Alexeyslav, спасибо большущее ! помогло!

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Сб дек 15, 2012 19:47:35
Alexeyslav
Для этого есть слева кнопочка с "+".
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс дек 16, 2012 02:08:50
casus
Помогите пожалста разобраться с кодом, хочу скопировать массив в стек.
Симуляцию выполняю на VMLAB, симулятор при вызове говорит
[PC = $A503, Time = 18.10 ms, {GEN}]: Program counter outside the valid space
каким образом A5 03 из массива в PC попало немогу понять
Код: Выделить всё
Array:
.db 9,0x10,0x24,0x15,0x11,0x2F,0x98,0xC7,0x03,0xA5
CopyToRam:
ldi row, 0x01 ;row счетчик
ldi ZH,High(Array*2) ;читаем адрес
ldi ZL, Low(Array*2) ;пишем в Z
lpm
mov col,R0 ;col количество байт в массиве
CRCnt:
mov Tmp0, col ;проверяем все ли передано
ldi Tmp1,0x01
add Tmp0, Tmp1
eor Tmp0, row
breq CREnd
ldi ZH,High(Array*2) ;читаем адрес
ldi ZL, Low(Array*2) ;пишем в Z
ldi Tmp0,0 ;плюсуем смещение
add ZL,row
adc ZH,Tmp0
lpm
push R0 ;ложим R0 в стек
inc row
rjmp CRCnt
CREnd:
ret
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс дек 16, 2012 10:25:36
Engineer_Keen
Вы командой PUSH положили в конец стека то, что считали из Array, как вы думаете, что произойдет при первом же ret? Ага проц из конца стека прочитает адрес возврата, вот вам и результат. Хотите передавать данные через стек, сначала выньте оттуда адрес возврата и перед ret верните его обратно.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс дек 16, 2012 13:38:44
ChipKiller
хочу скопировать массив в стек.
... вопрос для чего? ... посмотрите как С-компиляторы передают локальные параметры
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс дек 16, 2012 13:51:17
casus
Спасибо огромное. Все понял. А как грамотно вынуть адрес возврата?
я так понимаю вынуть слово по адресу SPL:SPH
и закинуть его после переменных?
У меня еще имеется таймер. боюсь что при вызове прерывания он нагадит в стек
P.S.Можете посоветовать литературу для изучения ATMega168?
проблема в том что начал с DataSheet
Пример передачи из даташита
Код: Выделить всё
USART_Transmit:
; Wait for empty transmit buffer
sbis UCSRnA,UDREn
rjmp USART_Transmit
; Put data (r16) into buffer, sends the data
out UDRn,r16
ret
А на самом деле вместо OUT надо использовать STS
SBIS по тойже причине не работает.
т.к. UDR0 - memory mapped
пока понял кучу времени убил. Подскажите где посмотреть рабочие примеры
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс дек 16, 2012 13:56:13
ChipKiller
при возникновении прерывания запись в стек идет "автоматом", а при выходе из него все возвращается к исходному значению......
можно сохранить SPL:SPH например в X или Y и потом через них работать со стеком
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс дек 16, 2012 15:28:26
Alexeyslav
Сама подпрограмма обработки прерывания в обязательном порядке должна позаботится чтобы вернуть все к тому состоянию как было до вызова, иначе крах программы обеспечен.
Ограничения для SBIS только одно - она может обращаться только к одной половине регистров, а OUT может обратится к портам только до адреса $3F. Если нужный порт лежит выше - тогда надо использовать STS.
Регистры коммуникационных портов обычно лежат в пределах досягаемости команды OUT. Может в меге168 все это переиначили? Странно это всё... Вероятно используются не те константы для обращения к портам. Попробуйте сравнить заголовочник для контроллера с константами приведенными в даташите.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс дек 16, 2012 16:00:19
ILYAUL
Сама подпрограмма обработки прерывания в обязательном порядке должна позаботится чтобы вернуть все к тому состоянию как было до вызова
Это Вы погорячились , совсем не обязательно. Вот на всякий случай вернуть флаг
I это да , да и то не обязательно.
Чем отличается команда rcall от прерывания - да ни чем.
можно написать
а можно и
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс дек 16, 2012 16:13:59
Alexeyslav
Флаг I после обработки прерывания будет безусловно УСТАНОВЛЕН. Так работает команда возврата из прерывания. т.к. не может быть такой ситуации когда обработка прерывания начинается при запрещенных прерываниях. Если вызвать обработчик прерывания из программы при помощи CALL - то мы
ССЗБ, после возврата из такого прерывания хотим мы такого или нет но прерывания будут разрешены. И у нас будет всего один такт чтобы запретить их снова(без последствий ли?), если прерывания не должны быть разрешены. Если забыть это сделать - возможны непредсказуемые(но иногда вполне очевидные) последствия.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс дек 16, 2012 16:58:57
BOB51
Если машина ушла в прерывание, а в качестве возврата использовано RET ( а не RETI) флаг I останется в 1...
Программный вызов прерывания совсем необязательно выполнять командой CALL - достаточно с помощью соответствующей серии команд (макрос-заготовки) установить соответствующий флаг прерывания.

Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс дек 16, 2012 17:07:38
zero648
ILYAUL писал(а):Чем отличается команда rcall от прерывания - да ни чем.
Есть небольшая разница, RCALL вызываете в программе когда это вам нужно, а прерывание наступает внезапно для основной программы, и при возврате из прерывания могут испортиться регистры, которые в прерывании используются и флаги, и тогда программа может пойти не так как задумано, хотя всё вроде правильно по алгоритму, вот тогда начинаем чесать репу, что не так,

.... а хез?
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс дек 16, 2012 17:17:40
ILYAUL
Флаг I после обработки прерывания будет безусловно УСТАНОВЛЕН
Опять горячитесь и не будет , если например я этого не захочу.
Как работает аппаратный обработчик прерывания. Помимо запоминания адреса возврата , он сбрасывает и флаг
I т.к. входя в сам обработчик мы уже не ждём заподлянки от других прерываний. Если надо сохранить SREG , что тоже не всегда нужно, только в случае использования в прерывании команд сравнения , что само по себе ОЧЕНЬ плохой тон принаписании обработчиков прерываний, то флага
I там нет- о сброшен.
Возвращает в SREG этот флаг , команда RETI , которая ближайшая родственица команде RET , которая отличается от родствености тем , что флаг не возвращает. Всё остальное она выполняет также как и команда reti/ Так, что Ваше
безусловно УСТАНОВЛЕН
зависит от каманды выхода из прерывания.
Если вызвать обработчик прерывания из программы при помощи RCALL
Вы не разобрались с Выше приведённым мной кодом. Посмотрите ещё раз и внимательно. В момент вызова rjmp или rcall флаг
I уже сброшен.
RCALL вызываете в программе когда это вам нужно, а прерывание наступает внезапно для основной программы

Кто же Вам сказал , что в прерывании мне не нужно вызвать именно эту подпрограмму , которую я независимо от прерывания могу вызвать когда мне угодно, но например с другими входными условиями.
Вообще-то одно и тоже прерывание , может вызывать N-ое количество его обработчиков , причём независимых друг от друга. Тут кто-то очень хорошо сказал про написании програм на asm и С. Вот только забыл в какой теме это было. Но сказано верно. Так , что не загоняйте себя в шоры это возможно , а это нет. ASM позволяет с процем делать многое и не всегда по правилам.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс дек 16, 2012 17:55:26
Alexeyslav
А я и говорю что аппаратный вызов прерывания сбрасывает признак I чем запрещает прерывания на время работы обработчика. последующая команда RETI устанавливает его назад. этот бит I - нигде не запоминается, команда просто устанавливает его и точка. даже если вызовешь при запрещенных прерываних обработчик при помощи конструкции rcall - после выхода из обработчика прерывания неожиданно окажутся разрешенными. Этот поведение остается на совести программиста.
При этом, кстати, если прерывания до вызова были разрешены возникает другая проблема - обработчик прерывания может быть не рассчитан на то что во время его выполнения может возникнуть и быть обработано ДРУГОЕ прерывание, он рассчитывает на тот факт что во время обработки прерывания все остальные прерывания ЗАПРЕЩЕНЫ и обработчик прерван быть не может. Ладно если в прерывании используем лишь парочку инкрементов, а если что-то посложнее и возникновение прерывания посреди обработчика может привести к непредсказуемым последствиям?
Это однозначно плохой подход вызывать прерывание при помощи rcall.
И кстати, когда возникает прерывание то аппаратно происходит rcall и вложенный rcall должен быть подавлен как минимум, иначе при попытке выйти из такого прерывания(rcall вместо rjmp в таблице векторов) управление будет передано на следующую инструкцию, которой будет следующий обработчик по таблице... а не в точку возникновения прерывания. ладно если следующий вектор не определен и на его месте стоит затычка reti - просто прерывание удлинится на 8 тактов, а если нет?
Кто же Вам сказал , что в прерывании мне не нужно вызвать именно эту подпрограмму , которую я независимо от прерывания могу вызвать когда мне угодно, но например с другими входными условиями.
Тогда ваша подпрограмма должна обладать непременным свойством - реентерабельностью.
А так же подпрограмма должна ОООЧЕНЬ аккуратно обходится с переменными основной программы, впрочем это условие будет соблюдено если подпрограмма будет реентерабельной.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс дек 16, 2012 18:11:34
ILYAUL
Программу пишет человек , обработчики , пишет человек. Всё что Вы написали человек и должен предусмотреть. И вызов другог прерывания в обработчике первого не сос тавляет сложностей. Кстати в XMEGA - так и сделано. Сами выбираете , что может прервать процесс обработки прерывания , а что нет. Флаг I вообще не сбрасывается.
Вот Вам код
И это весь обработчик прерывания. При этом начнётся совершенно другая программа работы процессора , с совершенно другими
параметрами и настройками системы. И это же прерывание вернёт начальную программу , если Вы это захотите , если нет найдёт новый путь.
Это однозначно плохой подход вызывать прерывание при помощи rcall.
Вы попробуйте сами , вместо rjmp- rcall и тогда судите
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс дек 16, 2012 18:32:20
Alexeyslav
прервать процесс обработки прерывания можно при помощи RETI, но единственный способ в МЕГАХ (не ХМЕГА) использовать вложенные прерывания - это разрешить прерывания в обработчике прерывания. Вообще со вложенными прерываниями количество возможных проблем и неудобства растет в геометрической прогрессии.
Из описания регистра статуса(ATMEGA168-48-88):
The I-bit is cleared by hardware after an interrupt has occurred, and is set by
the RETI instruction to enable subsequent interrupts.
Никаких неоднозначностей здесь нет.
Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Вс дек 16, 2012 20:21:51
casus
Подскажите, как можно организовать динамический массив в озу?
Например под буфер приемника, для послед. обработки, если количество данных неизвестно, но к примеру ограниченно 255ю.
Плюс ко всему мне нужно передвигаться по массиву, в моем случае
озу 0x0200-0x04FF, тоесть 1.5Kb памяти, используя смещение.
Каким образом смещать регистр адрессации массива, если STS и LDS восьмибитные?