Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Ответить
akl
Друг Кота
Сообщения: 4474
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Правильнее запоминать в обработчике состояние SREG и, при выходе, восстанавливать. По коду. Довольно объёмный и с ходу не вкуриш. Лучше "съесть слона по частям".

Код: Выделить всё

;----------------------------------------
service_ADCC: ;прерывание от АЦП
 IN R0,SREG

; В даном случае, прерывание от АЦП обрабатывается в фоновом режиме
; по сему - устанавливаем флаг, что АЦП преобразование закончено
; и разрешена фоновая обработка, и выходим 

	sbr r_flag_r25, (1<<int_acp); описание регистра (set_&_def.inc) ; !!!!!!!!!!!!! эта команда трогает флаги

; для отладки - что сдесь заходили - инвертируем пин порта
    sbic pinb,3;  пропустить если пин  = 0
    rjmp m_msh3
    sbi portb,3 ; установить пин в 1
    rjmp m_mshe3
m_msh3:
    cbi portb,3  ;сбросить пин в 0
m_mshe3:
 OUT SREG,R0
    reti

; end --- service_ADCC ----
Реклама
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Пт окт 11, 2013 20:43:07
Откуда: с. Муравлёвка Измаильский р-н.

Сообщение Vaha »

Здравствуйте.
Спасибо всем за участие, проблема решена - не правильная последовательность обращения к регистрам ADCH и ADCL.
Цытата из "Микроконтроллеры AVR семейства Mega. Евстифеев А.В. (2007)" (стр 415, параграф 9.3, третий обзац): -
" Обращение к регистрам ADCH и ADCL для получения результата
преобразования должно выполняться в определенной последовательности:
сначала необходимо прочитать регистр ADCL, а затем ADCH. Это
требование связано с тем, что после обращения к регистру ADCL процессор
блокирует доступ к регистрам данных со стороны АЦП до тех пор, пока не
будет прочитан регистр ADCH. ..."

akl - спасибо, ценное замичание, что команды "CBR" и "SBR" изменяют "SREG".
(и уже раз вылавливал глюки из-за не сохраненного "SREG" - все = мимо ус-шей)

Во влложении - исправленый код (с протеусом).
Вложения
voltmetr_m8_3.rar
(59.74 КБ) 161 скачивание
Реклама
Друг Кота
Аватара пользователя
Сообщения: 15797
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Я R0 и R1 заложил как "для особого случая" - это регистры с "двойным дном" - используются в составе других команд.
Для сверхоперативного стека лучше с R2 начинать (предварительно впихнув его содержимое в обычный стек).
:roll:
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Пт окт 11, 2013 20:43:07
Откуда: с. Муравлёвка Измаильский р-н.

Сообщение Vaha »

BOB51 - Ваша правда, R1 и R0 - подобие аккумулятору, в них записываются результаты умножения, и их стараюсь держать особняком, но как-то так вырвалось... :dont_know: , и вообще (сугубо мое мнение), если есть время и место нужно уходить в "SRAM" :oops: (ОЗУ) - меньше возни с пушами и попами :-) .
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Сообщения: 106
Зарегистрирован: Чт сен 10, 2015 06:59:03
Откуда: Гродно, BY

Сообщение trofim2 »

Команды LDS и STS ни чем не отличаются (по быстродействию) от POP и PUSH. Для экономии времени входа и выхода в/из прерывания логичнее использовать сохранение SREG и используемых регистров верхней половины в зарезервированных r2..r15.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 15797
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Разве что размером в ПЗУ (4 байта против двух)
:wink:
Vaha
Сброс в ОЗУ для SREG это единственно возможный вариант "быстрого сохранения" (то ли командой IN/OUT, то ли через "отображение РСФ на память").
Однако помимо прочего есть еще и куча возможных наложений при достаточно солидной программе.
Посему лучше создать область "теневого стека", которая при необходимости дублируется в штатном стеке.
В тот "теневой стек" можно и иные регистры копипастить, а не только SREG - на то есть две вкусняшки - MOV r,r и MOW r,r .
8)
Последний раз редактировалось BOB51 Пн ноя 05, 2018 08:49:26, всего редактировалось 1 раз.
Реклама
Вымогатель припоя
Сообщения: 615
Зарегистрирован: Вс дек 28, 2014 21:54:05

Сообщение dgrett »

Если сунули в стек, то и вынуть придётся ДО RET, RETI. А если сунули в SRAM или в регистры - вынимайте когда вздумается, можете и вовсе не вынимать.
Я всё-всё узнAю и стану профессором.
Друг Кота
Аватара пользователя
Сообщения: 15797
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

На то и стек - следить за содержимым надо в обязательном порядке.
А пересылку РСФ-регистр-память ОЗУ надо потом также и назад делать.
Что касательно SREG штука весьма избыточная (ибо надо также и указатель адреса хранить - то ли в явном виде как содержимое регистровой пары, то-ли в неявном в составе соответствующих команд).
Подбирается решение под конкретную программу с учетом всех за и против.
8)
Первый раз сказал Мяу!
Сообщения: 21
Зарегистрирован: Пт окт 11, 2013 20:43:07
Откуда: с. Муравлёвка Измаильский р-н.

Сообщение Vaha »

BOB51
Из выше изложенного, я мало чего понял (можно сказать вообще ничего)
1) "Сброс в ОЗУ для SREG это единственно возможный вариант "быстрого сохранения" (то ли командой IN/OUT, то ли через "отображение РСФ на память")" - РСФ это - регистр состояния флагов? != SREG?, и как понять "отображение РСФ на память"?
2) "Посему лучше создать область "теневого стека", которая при необходимости дублируется в штатном стеке" - что такое "теневой стек" - как он реализован?, еще и в штатном стеке?
3) "В тот "теневой стек" можно и иные регистры копипастить, а не только SREG - на то есть две вкусняшки - MOV r,r и MOW r,r" ("MOW r,r" -возможно очепятка?, имелось ввиду "MOVW r,r"?) - если "теневой стек" находится в SRAM-е (ОЗУ) - то каким боком "вкусняшки - mov(w) r,r" - это-же AVR - ?
Друг Кота
Аватара пользователя
Сообщения: 15797
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

РСФ - регистры специальных функций (порты, управление и прочие начиная с адреса 0x20 и до первых ячеек ОЗУ данных).
Они же (область РСФ) доступны также и как пространство ввода-вывода командами in и out.
К регистру управления можно обратится или как к УВВ (командами in и out) или как к области памяти командами работы с памятью LD/ST , но тогда к имени регистра добавляем 0x20 к примеру
in r16,portb = lds r16,(portb+0x20) /исправил :oops:
Как область памяти ОЗУ могут также адресоваться и регистры регистрового банка R0-R31.
Помимо того для регистров R0-R31 предусмотрены специальные скоростные пересылки регистр-регистр (mov r,r) и регистровая пара-регистровая пара (movw rp,rp), что весьма удобно при скоростном копировании блоков рабочих регистров.
Такой вариант - скоростное хранение выборочного количества данных и называется "теневым стеком" - правда само название позаимствовано у ПИКов - там это аппаратный модуль, работающий по прерываниям, но сам принцип ускоренного сохранения критических данных применим и в программной реализации для любого МК.
как пример...
в программе прерывания нужно сменить значение регистров-указателей, а затем восстановить.
Можно и через обычный стек, а можно и по иному (если есть запас "пустующих" регистров в младшей области регистрового файла)
movw r14,zl
movw r12,yl
movw r10,xl
собственно тело подпрограмы
movw xl,r10
movw yl,r12
movw zl,r14
ну и подобные операции в зависимости от расперделения ресурсов программы.
:roll:
Последний раз редактировалось BOB51 Ср ноя 07, 2018 11:47:04, всего редактировалось 1 раз.
akl
Друг Кота
Сообщения: 4474
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

[uquote="BOB51",url="/forum/viewtopic.php?p=3499281#p3499281"]РСФ - регистры специальных функций (порты, управление и прочие начиная с адреса 0x20 и до первых ячеек ОЗУ данных).
Они же (область РСФ) доступны также и как пространство ввода-вывода командами in и out.
К регистру управления можно обратится или как к УВВ (командами in и out) или как к области памяти командами работы с памятью LD/ST , но тогда к имени регистра добавляем 0x20 к примеру
in r16,portb = ld r16,(portb+0x20)[/uquote]
Для команд IN OUT доступны адреса 0...0x3F. Адресное пространство ОЗУ у младшеньких AVR 0x60 или 0x100(0x200), которые постарше

Код: Выделить всё

	LDS r16,(portb+0x20)
;	LD r16,(portb+0x20)	;это ошибка

	LDI	YH,HIGH(PORTB+0x20)
	LDI	YL,LOW(PORTB+0x20)

	LDI	R20,$55	; к примеру
	ST Y,R20		;R20 -> portb

	LDI	YH,HIGH(PINB+0x20)
	LDI	YL,LOW(PINB+0x20)

	LD	R0,Y	;
	STS	RAMEND-32,R0
Родился
Сообщения: 4
Зарегистрирован: Пн дек 10, 2018 20:35:19

Сообщение 9RIK »

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

Код: Выделить всё

Warning	1	Register r26 already defined by the .DEF directive	
Я понимаю что ошибка гласит о том что регистр уже используется в m8def.inc
А именно тут -

Код: Выделить всё

.def	XH	= r27
.def	XL	= r26
.def	YH	= r29
.def	YL	= r28
.def	ZH	= r31
.def	ZL	= r30
Я же просто пытаюсь подвязаться к ресурсам, т.е. вот -

Код: Выделить всё

.def Timer = r27
.def TimeoutPassive = r28
.def TimeoutActive = r29
.def temp = r30
.def BounceCounter = r31
Что я делаю не так?
Встал на лапы
Сообщения: 106
Зарегистрирован: Чт сен 10, 2015 06:59:03
Откуда: Гродно, BY

Сообщение trofim2 »

Можно закоментировать в m8def.inc, а можно применить директиву .undef, но всё это не позволит пользоваться регистрами с XH по ZL.
Корректней использовать для своих целей другие регистры.
akl
Друг Кота
Сообщения: 4474
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Это не ошибка, а предупреждение. Ничего страшного, определяйте как Вам нравится, но пользоваться командами ADIW, SBIW, LD(D), ST(D) ... будет нельзя.
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

А если так?
.def Timer = XH

Добавлено after 3 minutes 55 seconds:
[uquote="akl",url="/forum/viewtopic.php?p=3525038#p3525038"]Это не ошибка, а предупреждение.[/uquote] Это предупреждение с точки зрения синтаксиса, но ошибка с точки зрения программирвания. ИМХО, варнинги нельзя игнорировать, я так когда-то делал и зря :).
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Друг Кота
Аватара пользователя
Сообщения: 15797
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Не получится...
Для регистров только через undef...
:(
Другое дело, ежли регистр как ячейка памяти....
Однако проверять надо, и это несколько иной тип обращения, нежли к регистру должен будет применяться.
:roll:
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Что-то тут не так. 9RIK то не выложил код где он r26 переопределяет и я предположу, что он наверное перепутал местами левый и правый операнды директивы.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18793
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

давненько я ассемблером не маялся... но по-моему тут поможет директива .equ
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 15797
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Сообщение BOB51 »

Не проходит.
8)
Это ж не ячейка памяти, а регистр.
У них несколько иной смысл для дефайна.
Более оптимально заранее подготовить модель регистров и дальше в проекте уже ею руководствоваться.
С присвонеием имен ячейкам ОЗУ значительно проще. Хотя и там могут иметься неприятности.
:roll:
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

Да делов-то... игнорируй это предупреждение. Всё будет хорошо, если ты не пользуешься регистрами X,Y,Z ведь ты можешь ненароком попортить указатели если они где-то используются глобально обращаясь к своим переменным... Лучше, конечно, этого не делать.
Можно убрать или сделать .undef для этих регистров, чтобы не ругалось, но тогда НЕЛЬЗЯ БУДЕТ обращаться к индексным регистрам - вы попортите свои переменные. Если у вас в программе не задействованы индексные регистры глобально - можно убрать соответствующие определения, а если используется временно и только по месту, то перед использованием обязательно сделать PUSH для пары регистров, а по окончанию POP чтобы не портить свои переменные.
Контактная информация:
Ответить

Вернуться в «AVR»