Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.95/60: Рейтинг темы: голосов - 60, средняя оценка - 4.95
Otix
0 / 0 / 0
Регистрация: 01.09.2007
Сообщений: 25
1

sbi, cbi, sbic, sbs в подпрограммах

27.11.2012, 20:56. Просмотров 11161. Ответов 27
Метки нет (Все метки)

Доброго времени суток!

Уважаемые форумчане!

Есть подпрограмма, использующая инструкции sbi, cbi, sbic, sbs.
Я ее хочу применить многократно, но для разных портов и пинов.
Например, при одном вызове она должна работать с РА0 (sbi ddra,0) при другом - с РD7 (sbi ddrd,7) и т.д.
Как это сделать?

С уважением, Otix
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.11.2012, 20:56
Ответы с готовыми решениями:

Сброс бита CBI (Atmel Studio 6.2)
Картинки внизу... Использую Atmel Studio 6.2 для написания программы для Avr Mega. Проэкт...

w2k3 SBS
здравствуйте.. такой вопрос.. Сервер w2k3 SBS, у юзеров комп.класса XP SP3.. Все в рабочей...

Продам Microsoft SBS 2003 Premium
Продам Microsoft SBS 2003 Premium Рус. лицензия. За полцены.

SBS 2011, посадить DHCP на вторичный ip
История (опцианально, можно не читать): Устроился в организацию там стоит Small Buisness Server...

Объявление массивов в подпрограммах
Доброго времени суток! Подскажите пожалуйста как происходит выделение памяти в подпрограммах. Я не...

27
Otix
0 / 0 / 0
Регистрация: 01.09.2007
Сообщений: 25
28.11.2012, 14:04 21
Цитата Сообщение от MoxyMuz79
можно еще изголиться с командой перехода ijmp , там переход происходит по адресу в Z
использование команд ijmp и ветвление по breq\brne подразумевает наличие неких кейсов. И их количество должно быть равно (в общем случае) количеству возможных вариантов выводов, куда нужно цеплять датчик. Что есть экстенсивный путь. ПОКА лучшего варианта, чем с использованием индексных регистров - не вижу.
0
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
28.11.2012, 15:30 22
Цитата Сообщение от Otix
USORT привязан к определенной ноге контроллера. А это резко сужает возможности
Зато нет проблем с задержками , и командами по данной теме , да и число датчиков собственно ограничено только памятью MC.
Уточните у Вас 16А или просто 16
А ну да 16A, жаль , но она не может работать напрямую с командой sbi - это упростило бы дело.
0
С_Ч
0 / 0 / 0
Регистрация: 11.11.2012
Сообщений: 53
28.11.2012, 15:43 23
Цитата Сообщение от Otix
Цитата Сообщение от С_Ч
Цитата Сообщение от omokost
Для ассемблера нет универсального ответа. В подпрограмму можно передать данные через регистры, через область памяти, через стек. Вы сами это выбираете, никаких соглашений компилятора здесь нет. Поэтому найти универсальный вариант не реально. Если вы подробно опишете что именно вам нужно, можно попробовать подобрать подходящий.
Точно так. Еще могу добавить, что я бы сделал по косвенной адресации. Значение бит передаешь подпрограмме маской, а порт его адресом в пространстве памяти. И общаешься с портом как с ячейкой памяти. На AVR так не делал, а на 51 ядре в легкую.
Да, пожалуй, вырисовывается только такой вариант. Хранить в ОЗУ адрес порта, маску с битом. И делать что-то типа:

clr zh ;Старший байт адреса все равно нулевой (1 такт)
lds zl, Address_of_port ;младший байт адреса нужного порта (2 такта)
ld r16, z ;Грузим в рабочий регистр данные из порта (2 такта)

lds r17, Byt_Mask ;Грузим битовую маску (или номер бита, но тогда еще будет 1-2 команды) (2 такта)
or r16, r17 ;Выставляем нужный бит в "1" (1 такт)
st z, r16 ;Отправляем скорректированное значение назад в порт. (2 такта)

В итоге, вместо 2 тактов (sbi) получится 10 тактов. По времени дополнительно потеряем 0,5 мкс (кварц 16 МГц), но значительно увеличиваем гибкость программы.
Byt_Mask можно передать программе снаружи (хотя бы в том же r17). Может потребоваться вторая битовая маска Byt_Mask2 для сброса битов командой omd r17,Byt_Mask2. Если ничего изменять не надо, то грузим пустые битовые маски (Byt_Mask=0, Byt_Mask2=0xFF). Ну пара-тройка команд вхолостую будет крутится, унивесальность она всегда ведет к избыточности.
Вот как-то так.
0
MoxyMuz79
0 / 0 / 0
Регистрация: 25.11.2012
Сообщений: 5
28.11.2012, 15:49 24
Цитата Сообщение от YTYOUT
Цитата Сообщение от Otix
А ну да 16A, жаль , но она не может работать напрямую с командой sbi - это упростило бы дело.
что значит не может работать напрямую с sbi ? а mega16 может ?
0
28.11.2012, 15:49
YTYOUT
0 / 0 / 0
Регистрация: 02.10.2012
Сообщений: 1,946
28.11.2012, 15:58 25
Это значит , что команда sbi не может проинвертировать порты , как во многих других ашках , да и в более раних МС. Тогда бы отпала необходимость cbi sbis sbic.
Хотя очень странно , но ATMEL не обнавлял DS на 16-ки с 2009 года.
Toggling the Pin
Writing a logic one to PINxn toggles the value of PORTxn, independent on the value of DDRxn.
Note that the SBI instruction can be used to toggle one single bit in a port.
Это всё
clr zh ;Старший байт адреса все равно нулевой (1 такт)
lds zl, Address_of_port ;младший байт адреса нужного порта (2 такта)
ld r16, z ;Грузим в рабочий регистр данные из порта (2 такта)
Меняется на in r16,PORT
0
omokost
0 / 0 / 0
Регистрация: 24.12.2011
Сообщений: 2,753
28.11.2012, 16:02 26
Цитата Сообщение от С_Ч
...Byt_Mask можно передать программе снаружи (хотя бы в том же r17). Может потребоваться вторая битовая маска Byt_Mask2 для сброса битов командой omd r17,Byt_Mask2. Если ничего изменять не надо, то грузим пустые битовые маски (Byt_Mask=0, Byt_Mask2=0xFF)...
Вторая битовая маска и команда omd нужны обязательно:
Код
...
lds r17, Byt_Mask1 ;Грузим битовую маску 1
or     r16, Byt_Mask1               ;Выставляем нужный бит в "1"
lds r17, Byt_Mask2 ;Грузим битовую маску 2
omd     r16, Byt_Mask2              ;Выставляем нужный бит в "0"
...
Также команду
lds zl, Address_of_port ;младший байт адреса нужного порта (2 такта)
можно заменить на
pop zl; младший байт адреса нужного порта из стека (2 такта)
если применить передачу параметров через стек.
А вообще надо заранее определиться как вы будете передавать данные в подпрограмму. За исключением передачи через стек, это потребует резервирования или регистров или ячеек памяти. Также нужно знать, может ли эта п/п вызываться из прерывания. Нюансов здесь много, они того стоят?
0
Гарнист
0 / 0 / 0
Регистрация: 22.01.2010
Сообщений: 3,496
29.11.2012, 10:12 27
Есть ещё один вариант - поставить три обычных полевых транзистора, и разбить шину на три сегмента. Активировали сегмент, поработали с термометром - отключили сегмент.Потом можно подключить следующий...
Дёшево и сердито.
0
Otix
0 / 0 / 0
Регистрация: 01.09.2007
Сообщений: 25
29.11.2012, 13:23 28
Цитата Сообщение от omokost
Цитата Сообщение от С_Ч
...Byt_Mask можно передать программе снаружи (хотя бы в том же r17). Может потребоваться вторая битовая маска Byt_Mask2 для сброса битов командой omd r17,Byt_Mask2. Если ничего изменять не надо, то грузим пустые битовые маски (Byt_Mask=0, Byt_Mask2=0xFF)...
Вторая битовая маска и команда omd нужны обязательно:
Код
...
lds r17, Byt_Mask1 ;Грузим битовую маску 1
or     r16, Byt_Mask1               ;Выставляем нужный бит в "1"
lds r17, Byt_Mask2 ;Грузим битовую маску 2
omd     r16, Byt_Mask2              ;Выставляем нужный бит в "0"
...
Также команду
lds zl, Address_of_port ;младший байт адреса нужного порта (2 такта)
можно заменить на
pop zl; младший байт адреса нужного порта из стека (2 такта)
если применить передачу параметров через стек.
А вообще надо заранее определиться как вы будете передавать данные в подпрограмму. За исключением передачи через стек, это потребует резервирования или регистров или ячеек памяти. Также нужно знать, может ли эта п/п вызываться из прерывания. Нюансов здесь много, они того стоят?

Как будут реализовываться маски - дело техническое. Работа с битами - не проблема. Главное - идея. У меня уже есть отшлифованный вариант с sbi\cbi. Через стек или регистры данные передавать в моем варианте реализации слишком сложно. На мой взгляд, наиболее подходящая идея уже подана: индексная адресация + маска. Номер порта и заготовка для маски передается через ОЗУ.

Как по мне, так вопрос уже принципиально решен. Спасибо всем принявшим участие в обсуждении!
0
29.11.2012, 13:23
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
29.11.2012, 13:23

SBS 2011 Не может создать почту для пользователя
При создании нового пользователя, не может создать ему ящик ну и пользователь в SBS не заводится,...

Вычисление значений функций в подпрограммах
программа на языке ассемблера для вычисления значения y. Значения y1 и y2 необходимо вычислять в...

Работа с двумерным массивом в подпрограммах
Дана квадратная действительная матрица. Отсортировать по возрастанию все строки, содержащие нулевые...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
28
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.