Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Узнал новое о GPIO портах AVR
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
demiurg_spb
Цитата из даташита на atmega1281
Цитата
13.2.2 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.

Забавно, но в достаточно свежих мегах эта фича есть, а в старых мегах типа mega16,64,128 не было, поэтому не обращал внимания.
А так получается за один такт можно атомарно инвертировать несколько бит в порту например так PINA = (1<<7)|(1<<0);
Может кому-нибудь пригодится..
kovigor
Цитата(demiurg_spb @ Oct 16 2012, 08:49) *
А так получается за один такт можно атомарно инвертировать несколько бит в порту например так PINA = (1<<7)|(1<<0);
Может кому-нибудь пригодится..

Интересно. Пока не вижу, где это можно использовать (зачем переключать в противоположное состояние пины, настроенные на ввод ?), но все равно спасибо ...
demiurg_spb
Цитата(kovigor @ Oct 16 2012, 11:31) *
зачем переключать в противоположное состояние пины, настроенные на ввод ?
Вы немного не поняли... Это касается не только пинов настроенных на ввод, но и на вывод тоже (независимо от состояния DDRx).

PORTx = 0xf0;
PINx = 0xff;
после этого PORTx станет 0x0f.
SasaVitebsk
lol.gif Ну вы и даёте. Это было уже в меге88 лет 6 назад.
demiurg_spb
Цитата(SasaVitebsk @ Oct 16 2012, 11:47) *
Так я и не говорю что это новая фича, просто не обращал на неё внимания ибо пользуюсь макросами Аскольда и всё меня устраивает.
А тут оказалось что произошли незамеченные мной изменения, которые могут быть использованы в благих целях.
Подумал что я не одинок в этом незнании (думал что нет смысла перечитывать даташиты в их базовых частях).
_Pasha
Цитата(kovigor @ Oct 16 2012, 10:31) *
Пока не вижу, где это можно использовать

Инвертирование одного пина за 2 такта вместо 3-х и группы пинов за 1 такт вместо 3-х. И всё это атомарно.
demiurg_spb
Цитата(_Pasha @ Oct 16 2012, 12:04) *
Верное замечание.
ILYAUL
Помоему они нашли свой баг и решили сделать из него себе большой ПЛЮС
V_G
В xmega-х изначально есть регистры OUTTGL и DIRTGL для переключения выходов и направления соответственно
Genadi Zawidowski
Ну в тех кусках, которые "ногодрыганием" должны сформировать за минимальное время строб (например, формирование клока 9-го бита SPI при использовании совместно с аппаратным или всех вместо аппаратного) - может пригодиться.
LexaK
Цитата
Подумал что я не одинок в этом незнании (думал что нет смысла перечитывать даташиты в их базовых частях).
Верно. С каждым новым релизом даташиты раздуваются и увидеть в них пару новых строчек не всегда удается. Глянул даташит на Attiny2313 - там тоже такая фича есть. А я по-старинке использовал PORTx ^= 0x**
ReAl
Вот в этом pin_macros.h я стараюсь поддерживать список PORT_TOGGLE_BY_PIN_WRITE актуальным.
В старом варианте я ещё не думал, что они подсунут mega8A и подобные, которые пойдут новым define-ом. И выделял список старых, которые не поддерживают, считая, что новые уже будут все поддерживать.
На случай mega8B :-) сразу перевёл на выделение поддерживающих, так как несвоевременное добавление нового поддерживающего в этом случае приведет к росту кода, но не к потере работоспособности.

Да, хть это и не в эту тему, но в тех портах scmRTOS можно писать
Код
    {
    #ifndef PIN_TOGGLE_BY_PORT_WRITE
        TCritSect cs;
    #endif
        CPL(SOME_PIN);
    }
так как инверися через PIN атомарна.
demiurg_spb
Цитата(ReAl @ Oct 21 2012, 15:50) *
я стараюсь поддерживать список PORT_TOGGLE_BY_PIN_WRITE актуальным
Неблагодарная работа. Поддержкой этого дефайна должен avr-libc заниматься. ИМХО.

А Вы правы, так оптимальнее выходит
Код
# define PM_CPL(port,bit,val)      (PIN##port |= (1 << (bit)))
нежели
Код
# define PM_CPL(port,bit,val)      (PIN##port = (1 << (bit)))
sbi PINx,n будет получше чем
ldi R, (1<<n)
out PINx,R
Остаётся подумать над тем, что всегда-ли PINx лежит в области применимости инструкции sbi,
а то можно немного доработать макросы и проверять этот момент чтобы не хватануть вариант с lds ori sts...
ReAl
Цитата(demiurg_spb @ Oct 22 2012, 08:26) *
Неблагодарная работа. Поддержкой этого дефайна должен avr-libc заниматься.
Ну это надо выйти с предложением, аргументировать, ... Добиваться, короче :-)
Я вот на друге никак не решусь — большинство h-файлов несвоместимы с компиляцией в режиме ассемблера. Через avr/io.h можно получить все SFR и вектора, а вот константы для WDT, Sleep mode, прескалера такта ядра, ... — или вообще enum, или даже если define, то в этом файле не охвачено #ifndef __ASSEMBLER__ -ом всякие inline-функции и т.п.
А я иногда на асме пишу :-)
Надо как-то по мере необходимости для себя править файлы, а потом предложить патч.

Цитата(demiurg_spb @ Oct 22 2012, 08:26) *
Остаётся подумать над тем, что всегда-ли PINx лежит в области применимости инструкции sbi,

Пока всегда.
Даже у mega64/mega128 для порта F -- это пока единственный порт, у которого PIN/PORT/DDR находятся не рядом, да еще и PORT/DDR сидят как раз под LDS/STS -- PINF внизу, по адресу 0.
Тяжкое наследие mega103.
Но для m64/m128 обсуждаемая фича все равно не работает.
ILYAUL
Код
sbi PINx,n будет получше чем
ldi R, (1<<n)
out PINx,R

а sbi PORTX,N чем плох?
Сергей Борщ
QUOTE (ReAl @ Oct 22 2012, 18:41) *
Надо как-то по мере необходимости для себя править файлы, а потом предложить патч.
Не возьмут. Аргументируют это тем, что эти заголовочники они генерят скриптом из каких-то атмеловских файлов студии (xml?). Т.е. надо либо патч к их скрипту делать, либо патч в атмел посылать.
demiurg_spb
Цитата(ILYAUL @ Oct 22 2012, 21:50) *
а sbi PORTX,N чем плох?
Ничем не плох, но он только устанавливает, а мы говорим об инвертировании...
Цитата(Сергей Борщ @ Oct 22 2012, 23:05) *
Не возьмут. Аргументируют это тем, что эти заголовочники они генерят скриптом из каких-то атмеловских файлов студии (xml?). Т.е. надо либо патч к их скрипту делать, либо патч в атмел посылать.
Поговорить можно с Dean Camera он теперь ведь на Атмел работает. Он очень адекватный малый и думаю, что если ему донести сию мысль, то возможно он её продвинет.
ILYAUL
Цитата(demiurg_spb @ Oct 23 2012, 09:18) *
Ничем не плох, но он только устанавливает, а мы говорим об инвертировании...

cli PORT,N
А вертирование через PIN - только себя в итоге запутать
ae_
Цитата(ILYAUL @ Oct 24 2012, 21:00) *
cli PORT,N ;А вертирование через PIN - только себя в итоге запутать

cli - опечатка, cbi
А вот практический пример использования
Код
sbi PINB, BEEPER

вместо
Код
;генерация звука
    sbic    PORTB, BEEPER
    rjmp    beep_off
;beep_on
    sbi    PORTB, BEEPER
    rjmp    beep_quit
beep_off:
    cbi    PORTB, BEEPER
beep_quit:

;или используя 2 временных регистра

    in    temp1, PORTB
    ldi    temp2, 1<<BEEPER
    eor    temp1, temp2
    out    PORTB, temp1
demiurg_spb
Цитата(ILYAUL @ Oct 24 2012, 16:00) *
cli PORT,N
Почитайте наконец уже доку на avrasm...

Цитата(ILYAUL @ Oct 24 2012, 16:00) *
через PIN - только себя в итоге запутать
Чтобы не путать никого
Код
#define CPLPORTx PINx
CPLPORTx |= (1<<n);
ILYAUL
Цитата
cli - опечатка, cbi
Конечно.
Цитата
вместо ...

Ну для ногодрыганья , то да. Ну уговорили sm.gif , хотя честно говоря не прикину где сие можно применить. В бипере уже точно нет - там всё делает таймер. 1-wire не предлогать- там USART . Выключение включение чего-то -но там всегда условия.
SasaVitebsk
Цитата(ILYAUL @ Oct 16 2012, 12:40) *
Помоему они нашли свой баг и решили сделать из него себе большой ПЛЮС

Вы неправы. Появилось это в atmega88, вместе со второй фичей. Её здесь не обсуждают.
Обе без пыли и шума.
Вторая это:
Цитата
The ATmega48/88/168 contains three General Purpose I/O Registers. These registers
can be used for storing any information, and they are particularly useful for storing global
variables and Status Flags. General Purpose I/O Registers within the address range
0x00 - 0x1F are directly bit-accessible using the SBI, CBI, SBIS, and SBIC instructions.

То есть опять же для атомарного доступа.
И то и другое достаточно удобно.
Правда почти не работаю уже с atmel
ILYAUL
Цитата(SasaVitebsk @ Oct 26 2012, 13:47) *
..... General Purpose I/O Registers

Ну это уже обсуждалось и по-моему не раз
Кстати пасибо , что напомнили , вот они тут же и пригодились. a14.gif Забываешь, что они где-то , но всё таки есть
ReAl
Мало того, что атомарный доступ, еще и флаги при этом не трогаются. Иногда очень приятно.
SasaVitebsk
А где используется? ... biggrin.gif
Я делал bootloader для atmega8. Цель шифрование, нормальный протокол, малый объём.
Написал - ну никак не влазит. Переписал шифрование, CRC на ASMе + определённым образом распределил регистры - вошло и 2 байта лишних осталось. )) Только на версии IAR 5.11. На других - не влезает ... ))
Перенёс на 88. Ну а там ведь доступ к некоторым портам более длинный. Короче пару байт не хватило. )) Ну а светодиодом дёргаю при загрузке ... )) Применил новые фичи - влезло ... ))))) Приятно ... ))
Ну ещё где-то применял ... Хотя не очень актуально.
General Purpose I/O Registers более актуальная вещь, но учитывая что реализовано не везде, то тоже проблематично ...
Должен быть единообразный подход к кристалам ... Так сказать общая политика предприятия ...
Из всех существующих я наблюдаю это только в STM. NXP мне нравятся больше, но их разброд просто убивает ... Недаром количество постов по применению stm растёт регулярно ...
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.