Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: bit set
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
i.dmitry
Правильно ли я понял:
1)
Код
TIMSK = (1 << OCIE2);

2)
Код
TIMSK |= (1 << OCIE2);

----------
В первом случае установится только бит OCIE2, остальные будут нулями.
Во втором случае все биты кроме OCIE2 останотся неизменными, а этот бит станет единицей.
----------
Правильно?

-dmitry.
alux
Совершенно верно.
В апноте avr035 все подробно описано.

http://www.gaw.ru/html.cgi/txt/app/micros/avr/AVR035.htm
даже русским языком написано.
ReAl
Цитата(i.dmitry @ Jul 22 2007, 12:14) *
Во втором случае все биты кроме OCIE2 останотся неизменными, а этот бит станет единицей.
Если строго, то не "останутся неизменными", а "в них запишется то, что из них прочиталось".
Обычно это одно и то же. Но в регистрах, где есть биты, сбрасываемые записью "1", при такой операции эти биты будут сброшены.
_artem_
в iar mожно еще так :

PORTA_Bit4 = 1;
AndreyKeil
Все станет ясно, если посмотреть дизассемблер.
zltigo
Цитата(_artem_ @ Jul 22 2007, 22:03) *
в iar mожно еще так :
PORTA_Bit4 = 1;

Не стоит пользоваться. Крайне сомнительное расширение sad.gif, ибо:
1. Не переносима;
2. Неявное чтение может либо просто быть лишним, либо даже вредным, если из регистра не читается записанное значение, либо регистр содержит зарезервированные биты, либо операция чтения имеет побочные эффекты.
rezident
Вообще говоря результат действия 1 << OCIE2 зависит от того, какое число сопоставлено символьному имени OCIE2. Выражение вида "1<<x" означает "сдвинуть число 1 на x разрядов влево", т.е. в сторону старших разрядов. Справа (в младший разряд) при таком сдвиге дописывается нуль.
Насколько я понимаю OCIE2 это седьмой (если счет от нуля) бит в регистре TIMSK. Если имени OCIE2 сопоставлено число 7
Код
#define OCIE2 7

то результат операции
Код
TIMSK |= (1<<OCIE2);

что эквивалентно
Код
TIMSK = TIMSK |(1<<OCIE2);

а макроподстановка даст выражение
Код
TIMSK = TIMSK|(1<<7);

будет верным - в регистре TIMSK будет установлен седьмой бит (счет от нуля).
Если же символьному имени OCIE2 сопоставлена битовая маска регистра TIMSK (что чаще всего и используют в хидерах компиляторов)
Код
#define OCIE2 0x80

то результат будет неадекватным. Т.к. в результате макроподставноки получится выражение
Код
TIMSK = TIMSK|(1<<128);

которое будет означать "совершить операцию побитного сложения содержимого регистра TIMSK с числом 1, сдвинутым влево на 128 бит (0x80=128), и записать результат в TIMSK".
Так что i.dmitry перед использованием символьного обозначения убедитесь в его значении!
SasaVitebsk
Цитата(ReAl @ Jul 22 2007, 21:40) *
Если строго, то не "останутся неизменными", а "в них запишется то, что из них прочиталось".
Обычно это одно и то же. Но в регистрах, где есть биты, сбрасываемые записью "1", при такой операции эти биты будут сброшены.


Если хотите говорить строго, то или будьте точны или не будьте так категоричны. smile.gif
Сказанное Вами правильно при работе с регистрами на которые не распространяются команды SBI, CBI (в частности регистра TIMSK). И возможно, это справедливо для некоторых компиляторов. Скажем команда
PORTA |= (1<<5);
компилятором IAR компильнётся в
SBI PORTA,5
что, очевидно, не затронет остальные биты.
=GM=
Цитата(SasaVitebsk @ Jul 22 2007, 20:17) *
Сказанное Вами правильно при работе с регистрами на которые не распространяются команды SBI, CBI (в частности регистра TIMSK). И возможно, это справедливо для некоторых компиляторов. Скажем команда PORTA |= (1<<5); компилятором IAR компильнётся в SBI PORTA,5 что, очевидно, не затронет остальные биты.

Известно, что для аврок нового поколения команда sbi pinb,1 изменяет состояние пина на противоположное.

Отсюда вопрос, как сказать такое си компилятору? Должно быть что-то типа PINB |= (1<<1); или я не прав?
defunct
Цитата(=GM= @ Jul 23 2007, 00:30) *
Известно, что для аврок нового поколения команда sbi pinb,1 изменяет состояние пина на противоположное.

Что за AVRки нового поколения? укажите хотя бы модель мк, в котором вы такое видели.

PINB это входной порт вообще-то..
команда SBI - сокращение от Set Bit IO (она по идее не может делать CLR, она только SET)
ReAl
Цитата(SasaVitebsk @ Jul 22 2007, 22:17) *
Если хотите говорить строго, то или будьте точны или не будьте так категоричны. smile.gif
Давайте договоримся: прежде, чем указывать мне на то, что я должен быть точен - как минимум сами делайте то, что делаю я - проверяйте достоверность своих утверждений.

Цитата(SasaVitebsk @ Jul 22 2007, 22:17) *
Сказанное Вами правильно при работе с регистрами на которые не распространяются команды SBI, CBI (в частности регистра TIMSK). И возможно, это справедливо для некоторых компиляторов. Скажем команда
PORTA |= (1<<5);
компилятором IAR компильнётся в
SBI PORTA,5
что, очевидно, не затронет остальные биты.
Блажен, кто верует. Продолжайте дальше в том же духе, только не тащите в свою веру остальных.
Не "не затронет", а "запишет в них то, что в них было". Для PORTA эти два утверждения эквивалентны, а вот для ACSR...

Пишем маленькую функцию (тут atmega64, но на atmega8515 это тоже проверялось в железе):
Код
#define AC_MINUS E,3,L
void sbi_test(void)
{
    dbg_putstr_P(dbg_always, PSTR("SBI RMW behavior test\n"));
    DRIVER(AC_MINUS,OUT);
    OFF(AC_MINUS);
    ACSR = _BV(ACBG);
    _delay_us(100); // let bandgup on
    ACSR |= _BV(ACI); // clr interrupt flag
    dbg_printf_P(dbg_always, PSTR("Initial ACSR = 0x%02X\n"), ACSR);
    ON(AC_MINUS);
    _delay_us(2); // AC propagation delay
    dbg_printf_P(dbg_always, PSTR("AC- toggled, ACSR = 0x%02X\n"), ACSR);
    ACSR |= _BV(ACIE);
    dbg_printf_P(dbg_always, PSTR("ACSR |= _BV(ACIE),  ACSR = 0x%02X\n"), ACSR);
}

Вот что нагенерил avr-gcc, прошу обратить внимение на на строку для ACSR |= _BV(ACIE), она там старательно выделена.
CODE
00002804 <sbi_test>:
#define AC_MINUS E,3,L
void sbi_test(void)
{
2804: 60 ed ldi r22, 0xD0 ; 208
2806: 72 e0 ldi r23, 0x02 ; 2
2808: 80 e0 ldi r24, 0x00 ; 0
280a: 0e 94 6d 2a call 0x54da ; 0x54da <dbg_putstr_P>
dbg_putstr_P(dbg_always, PSTR("SBI RMW behavior test\n"));
DRIVER(AC_MINUS,OUT);
280e: 13 9a sbi 0x02, 3 ; 2
OFF(AC_MINUS);
2810: 1b 9a sbi 0x03, 3 ; 3
ACSR = _BV(ACBG);
2812: 80 e4 ldi r24, 0x40 ; 64
2814: 88 b9 out 0x08, r24 ; 8
void
_delay_loop_1(uint8_t __count)
{
__asm__ volatile (
2816: 85 ef ldi r24, 0xF5 ; 245
2818: 8a 95 dec r24
281a: f1 f7 brne .-4 ; 0x2818 <sbi_test+0x14>
_delay_us(100); // let bandgup on
ACSR |= _BV(ACI); // clr interrupt flag
281c: 44 9a sbi 0x08, 4 ; 8
dbg_printf_P(dbg_always, PSTR("Initial ACSR = 0x%02X\n"), ACSR);
281e: 88 b1 in r24, 0x08 ; 8
2820: 99 27 eor r25, r25
2822: 9f 93 push r25
2824: 8f 93 push r24
2826: 89 eb ldi r24, 0xB9 ; 185
2828: 92 e0 ldi r25, 0x02 ; 2
282a: 9f 93 push r25
282c: 8f 93 push r24
282e: 1f 92 push r1
2830: 0e 94 d9 29 call 0x53b2 ; 0x53b2 <dbg_printf_P>
ON(AC_MINUS);
2834: 1b 98 cbi 0x03, 3 ; 3
void
_delay_loop_1(uint8_t __count)
{
__asm__ volatile (
2836: 84 e0 ldi r24, 0x04 ; 4
2838: 8a 95 dec r24
283a: f1 f7 brne .-4 ; 0x2838 <sbi_test+0x34>
_delay_us(2); // AC propagation delay
dbg_printf_P(dbg_always, PSTR("AC- toggled, ACSR = 0x%02X\n"), ACSR);
283c: 88 b1 in r24, 0x08 ; 8
283e: 99 27 eor r25, r25
2840: 9f 93 push r25
2842: 8f 93 push r24
2844: 8d e9 ldi r24, 0x9D ; 157
2846: 92 e0 ldi r25, 0x02 ; 2
2848: 9f 93 push r25
284a: 8f 93 push r24
284c: 1f 92 push r1
284e: 0e 94 d9 29 call 0x53b2 ; 0x53b2 <dbg_printf_P>
ACSR |= _BV(ACIE);


2852: 43 9a sbi 0x08, 3 ; 8 <<<================================== SBI !!!


dbg_printf_P(dbg_always, PSTR("ACSR |= _BV(ACIE), ACSR = 0x%02X\n"), ACSR);
2854: 88 b1 in r24, 0x08 ; 8
2856: 99 27 eor r25, r25
2858: 9f 93 push r25
285a: 8f 93 push r24
285c: 8a e7 ldi r24, 0x7A ; 122
285e: 92 e0 ldi r25, 0x02 ; 2
2860: 9f 93 push r25
2862: 8f 93 push r24
2864: 1f 92 push r1
2866: 0e 94 d9 29 call 0x53b2 ; 0x53b2 <dbg_printf_P>
286a: 8d b7 in r24, 0x3d ; 61
286c: 9e b7 in r25, 0x3e ; 62
286e: 0f 96 adiw r24, 0x0f ; 15
2870: 0f b6 in r0, 0x3f ; 63
2872: f8 94 cli
2874: 9e bf out 0x3e, r25 ; 62
2876: 0f be out 0x3f, r0 ; 63
2878: 8d bf out 0x3d, r24 ; 61
287a: 08 95 ret

А вот что получено на терминалке.
Цитата
SBI RMW behavior test
Initial ACSR = 0x40
AC- toggled, ACSR = 0x70
ACSR |= _BV(ACIE), ACSR = 0x68
Т.е. команда SBI не только установила бит 3 (ACIE), но и сбросила бит 4 (ACI).
Если же вместо
ACSR |= _BV(ACIE);
написать
ACSR = (ACSR & ~_BV(ACI)) | _BV(ACIE);
то бит ACIE взводится, но бит ACI не сбрасывается.

Так кто из нас неоправданно категоричен?


Цитата(defunct @ Jul 22 2007, 23:45) *
Что за AVRки нового поколения? укажите хотя бы модель мк, в котором вы такое видели.

PINB это входной порт вообще-то..
команда SBI - сокращение от Set Bit IO (она по идее не может делать CLR, она только SET)
Ой, да для многих уже. Хоть бы atmega48/88/168. Посмотрите для них картинку 10.2 - структуру порта, там триггер в PORT через инвертор может получить своё состояние себе на вход при записи "1" в PIN (элемент И на управление мультиплексором и стробом записи).

=GM=, а вот в свете RMW (Read-Modify-Write) сути команды sbi, см. мой ответ SasaVitebsk, я бы её не использовал с такой целью. Лучше запись PINB = (1 << 1) - так Вы гарантированно запишете 1-ку только в один триггер (а если захотите - то инвертируете группу ног).
Кстати, интересно - проверьте (мне лень макетку с мегой48 доставать). Если SBI и на PIN* себя ведёт так же, как и на ACSR (странно будет, если по-другому) то после SBI PINB,... на порту B переключится на противоположное состояние PULL-UP-ов на тех входах, на которых в этот момент была 1-ка.
Ой как долго можно такой глюк ловить smile.gif
CD_Eater
Цитата из ДШ мега48
Some of the Status Flags are cleared by writing a logical one to them. Note that, unlike most other AVRs, the CBI and SBI instructions will only operate on the specified bit, and can therefore be used on registers containing such Status Flags. The CBI and SBI instructions work with registers 0x00 to 0x1F only.
И такое поведение команд CBI и SBI свойственно для всех АВРок, начиная с тини13, то есть, все выпущенные за последние 3 года модели. Неужели некоторые уже 3 года не читали даташитов? А вера здесь не при чём.

А атмегу64 и 8515 выбросьте, пожалуйста. Им не место на столе эмбеддера.

Цитата
Посмотрите для них картинку 10.2 - структуру порта, там триггер в PORT через инвертор может получить своё состояние себе на вход при записи "1" в PIN (элемент И на управление мультиплексором и стробом записи).

Цитата
Кстати, интересно - проверьте (мне лень макетку с мегой48 доставать). Если SBI и на PIN* себя ведёт так же, как и на ACSR (странно будет, если по-другому) то после SBI PINB,... на порту B переключится на противоположное состояние PULL-UP-ов на тех входах, на которых в этот момент была 1-ка.
Выход триггера PORT соединён с ножкой микросхемы через повторитель (см. ту самую схему), поэтому внешний потенциал на ножке никак не может повлиять на операции с этим триггером.
В случае, когда ножка работает как вход, то запись 1 в PINB приведёт к инверсии соответствующего бита PORTB. Разница лишь в том, что в режиме выхода этот порт определяет уровень на ножке выхода, а в режиме входа - подтяжку. Поэтому в режиме входа запись единички в PINB будет инвертировать пул-апы. Ничего удивительного. Собственно, это следует из ДШ. Никакого глюка тут нет.
ReAl
Цитата(CD_Eater @ Jul 23 2007, 01:43) *
Неужели некоторые уже 3 года не читали даташитов?
Да легко. Некоторые вон плохо себе представляют, как и где в С автоматические переменные создаются и что они не есть угрозой для реентрабельности - и ничего, живут и часто их интересно послушать.

Цитата
А атмегу64 и 8515 выбросьте, пожалуйста. Им не место на столе эмбеддера.

Ну с с выбросом меги8515 действительно можно согласиться, пусть даже она самим атмелом в устаревшие не записана, а что с мегой162 будем делать? Ей-то замены пока нет, хоть ей и больше 3 лет.
А почему меге64/128 не место - я не пойму. Личная неприязнь?

Цитата
Поэтому в режиме входа запись единички в PINB будет инвертировать пул-апы. Ничего удивительного. Собственно, это следует из ДШ. Никакого глюка тут нет.
Тут нет, я ещё не настолько туп.
Глюк был бы, если бы SBI для этого кристалла было RMW с байтом. К счастью, этого нет в новых кристаллах. Тем лучше.
add
Цитата
Ну с с выбросом меги8515 действительно можно согласиться,

Цитата
Им не место на столе эмбеддера

Выступлю в защиту м8515! Что вам там в ней не нравится? Нормальный кристал! Ног дофига. Цена приличная для серийки. Ну нету АЦП, не во всех задачах он и нужен!
_artem_
Цитата(zltigo @ Jul 22 2007, 22:45) *
Не стоит пользоваться. Крайне сомнительное расширение sad.gif , ибо:
1. Не переносима;
2. Неявное чтение может либо просто быть лишним, либо даже вредным, если из регистра не читается записанное значение, либо регистр содержит зарезервированные биты, либо операция чтения имеет побочные эффекты.


Согласен, но я эту форму только для gpio использую наверно эту форму iar сделал специально для явной генерации опкода по битустановке.
при работе с регистрами иногда нужно бывает записать какое то значение в бит не зная его заранее.

подытоживая три варианта которые я применяю для GPIO:

Код
if(val == 0)
    PORTA &= (~(1<<PA4));
else
    PORTA |= (1<<PA4);


или

PORTA = (PORTA & (~(1<<PA4))) | ((val == 0? 0:1) << PA4 )

или

PORTA_Bit4 = (val == 0? 0:1);
=GM=
Цитата(ReAl @ Jul 23 2007, 03:32) *
=GM=, а вот в свете RMW (Read-Modify-Write) сути команды sbi, см. мой ответ SasaVitebsk, я бы её не использовал с такой целью. Лучше запись PINB = (1 << 1) - так Вы гарантированно запишете 1-ку только в один триггер (а если захотите - то инвертируете группу ног)

Понял, спасибо, учту при случае...

Цитата(ReAl @ Jul 23 2007, 03:32) *
Глюк был бы, если бы SBI для этого кристалла было RMW с байтом. К счастью, этого нет в новых кристаллах. Тем лучше

Так что, для новых кристаллов команда SBI перестала быть Read-Modify-Write? Для каких конкретно?
SasaVitebsk
Цитата(ReAl @ Jul 23 2007, 01:07) *
Так кто из нас неоправданно категоричен?


Вроде как получается оба. smile.gif Я больше. smile.gif

Честно говоря я редко по опросу работаю и на такие грабли как-то ни разу не наступал. А может наступал да не заметил. 07.gif Короче надо внимательно за этим следить. Мегу 64 до этого не пользовал. А вот сейчас, по иронии судьбы, - начал. smile.gif м8515 использовал, но как то пронесло.
CD_Eater
Цитата
Глюк был бы, если бы SBI для этого кристалла было RMW с байтом. К счастью, этого нет в новых кристаллах. Тем лучше.

Атмельцы тоже не так глупы, как Вы пытаетесь их выставить. Эти две фичи (инвертирование бита PORTB и особенность инструкции SBI) сильно взаимозависимы и появились в АВРках ОДНОВРЕМЕННО. А именно, в тини13.


Цитата
Выступлю в защиту м8515! Что вам там в ней не нравится? Нормальный кристал! Ног дофига. Цена приличная для серийки. Ну нету АЦП, не во всех задачах он и нужен!

мега88 дешевле и мощнее (SRAM*2). Ну разве только по параметру "удельная стоимость одной ножки" м8515 лучше smile.gif


Цитата
Так что, для новых кристаллов команда SBI перестала быть Read-Modify-Write? Для каких конкретно?

GM, в этой ветке их уже называли как минимум в двух постах. Повторю ещё раз: для всех новых чипов, начиная с тини13.
ReAl
Цитата(add @ Jul 23 2007, 08:52) *
Выступлю в защиту м8515! Что вам там в ней не нравится? Нормальный кристал! Ног дофига. Цена приличная для серийки. Ну нету АЦП, не во всех задачах он и нужен!
Вот именно поэтому ("нет, но не во всех и нужен") м8515 нельзя сравнивать с м88, у м8515 есть то, чего нет у м88 - внешняя шина. Но она есть у более мощного кристалла м162, поэтому я согласился с тем, что м8515 "уходит". м8535 - тем более, её можно заменить на целый выводок более мощных кристаллов.
А вот м162 заменить пока не на что. У меня в прошлом году был проектик, в котором стоят м162, epm240t100 и 32кбайт ОЗУ. Ставить туда что-то 64-ногое с внешней шиной вообще неинтересно было - и так пару ног свободных осталось, только более мощную ПЛИС и всё - тоже невыгодно. По ОЗУ что м8515, что м162 - всё равно не проходили, так что в этом смысле можно было и м8515 поставить, но какого-то смысла это не имело. Кажется, цена равна была, а доп UART на терминалку для отладки не помешал.




Цитата(SasaVitebsk @ Jul 23 2007, 15:04) *
Вроде как получается оба. smile.gif Я больше. smile.gif
Ну если считать по числу серийно выпускаемых типов кристаллов, то таки я. А если считать, что неиспользование исправления "некрасивости" в команде, приводящее к незначительному увеличению объёма кода и времени исполнения при работе с некоторыми регистрами - не так плохо, как незнание того, что не всегда так было и ещё бегают кристаллы, где это глюкоопасно - то тогда надо ещё подумать smile.gif

Кстати, а мега32 тоже уже на выброс? Да, я понимаю, мега324 и всё такое, но по цене 32-ая пока выигрывает, кажется.

Цитата
Честно говоря я редко по опросу работаю и на такие грабли как-то ни разу не наступал. А может наступал да не заметил. 07.gif Короче надо внимательно за этим следить. Мегу 64 до этого не пользовал. А вот сейчас, по иронии судьбы, - начал. smile.gif
Дело не только в работе по опросу. В примерах scmRTOS аналоговый компаратор используется для программной генерации прерывания, но иногда надо на некоторое время это прерывание блокировать. Естетсвенно, сбросом/установкой ACIE. Но если не отследить, то прерывание может оказаться потерянным из-за сброса ACI из-за RMW-шности.
Естественно, в scmRTOS это отслежено :-)




Цитата(CD_Eater @ Jul 23 2007, 16:21) *
Атмельцы тоже не так глупы, как Вы пытаетесь их выставить. Эти две фичи (инвертирование бита PORTB и особенность инструкции SBI) сильно взаимозависимы и появились в АВРках ОДНОВРЕМЕННО.
ГДЕ? Где в этой теме я "пытаюсь их выставить"? И, кстати, когда появились ACSR, ADCSR, для которых SBI/CBI могут привести к "неожиданным эффектам" на вполне ещё серийных кристаллах?

Есть определённое поведение команды, есть нюансы её употребления, которые могут привести к глюкам. Я обратил на это внимание.

Вот где Атмел явно "поторопился", так это в распределении SFR на битово адресуемые и не адресуемые, несложно было бы запрещать прерывания на один такт при обращении к двухбайтовым SFR в соответствии со специфицированым порядком, ..., но это обсуждалось много раз.

Кстати, продолжая старый разговор - ну уж после того, как SBI/CBI стали "не-RMW" - их двухцикловость выглядит несколько странной, у них теперь не больше работы, чем у OUT.

Цитата
мега88 дешевле и мощнее (SRAM*2). Ну разве только по параметру "удельная стоимость одной ножки" м8515 лучше smile.gif
По этому параметру AT89S51 всё равно не переплюнуть smile.gif
А m88 - слишком другой кристалл, см. выше. Хотя автора "защиты" этот вопрос, кажется, не волнует.
add
Цитата
А m88 - слишком другой кристалл, см. выше. Хотя автора "защиты" этот вопрос, кажется, не волнует.

:-) очень волнует... Да ставте любой кристал куда вздумается..яж не с флагом вышел типа " даЁшь М8515 каждому крестьянину". Новое поколение кристалов естественно сменяет старое.. кто ж с этим спорит..Но зачем, к примеру, применять более "мощный" чип? разве что по ценнику...или код ну не лезет то понятно..а так вопрос спорный. 8515 раньше появился на свет, а м88 это "сыночек"...ну чуток по продвинутее или что типа того..А так одного поля ягода..Хорошо что Вы не утверждаете что 8-биткам ужо не место на столах эмбедеров.:-)
CD_Eater
Цитата
Есть определённое поведение команды, есть нюансы её употребления, которые могут привести к глюкам. Я обратил на это внимание.

Эти нюансы уже ушли в прошлое, не цепляйтесь за чипы 5-летней давности. Кстати, даже в глубоком прошлом эти "глюки" были описаны в даташите, этому специально уделено внимание как распространённым ошибкам у начинающих пользователей. Вы, мне кажется, всё пытаетесь обвинить Атмел в потенциальной глючности АВРок. Только, пожалуйста, приводите факты, а не домыслы. Как показывает практика, 99% глюков оказываются следствием невнимательного чтения даташитов.

В принципе, если вместо слова "глюк" в Вашем предложении, которое я процитировал, стояло бы слово "ошибки из-за незнания ДШ", я бы с Вами согласился, такое напоминание об "узких" местах использования АВРок только на пользу. Но это не глюк.
ReAl
Цитата(CD_Eater @ Jul 23 2007, 21:20) *
Эти нюансы уже ушли в прошлое, не цепляйтесь за чипы 5-летней давности.
Вы хотите сказать, что надо всем быстро отказаться от применения м162, м32, м64/м128 ?
Но ПОЧЕМУ? Только потому, что давно разработаны?

Цитата
Вы, мне кажется, всё пытаетесь обвинить Атмел в потенциальной глючности АВРок.
Извините, бред.
Кажется. Причём не могу понять - откуда это взялось. То, что я иногда говорю "лучше бы" или даже "плохо, что" этого не означает. Это говорят многие про многое, причём чаще всего про то, что более-менее активно используют, "понимание приходит во время еды". Считал бы АВР потенциально глючными - не использовал бы их.
Или я должен подпрыгивать с транспарантом "лучше нету АВР-ок, Атмел-чемпион", чтобы никому не казалось, что я обвиняю Атмел?

Цитата
Только, пожалуйста, приводите факты, а не домыслы. Как показывает практика, 99% глюков оказываются следствием невнимательного чтения даташитов.

В принципе, если вместо слова "глюк" в Вашем предложении, которое я процитировал, стояло бы слово "ошибки из-за незнания ДШ", я бы с Вами согласился, такое напоминание об "узких" местах использования АВРок только на пользу. Но это не глюк.
Я позволил себе выделить. Итого статистичиески в 99% случаев допустимо применять слово "глюк" вместо длинного словосочетания.
Глюк программы - это когда она временами ведёт себя странно. Если не учесть "нюансы" - вероятность этого увеличится.
Я говорил о глюках программы, а не кристалла. Причём с самого начала говорил о том, что надо учитываеть имеющееся поведение, а не о том, что имеющееся поведение глючное (т.е. есть глюк кристалла).
SasaVitebsk
smile.gif
Спасибо обоим. ReAlу за уточнение нюансов, а CD_Eaterу за введение в курс сегодняшнего состояния кристаллов.

Честно говоря не секрет, что даташиты читаются плохо. По разным причинам. Конечно немаловажная причина - недостаточное знание языка оригиналов. Непростительная причина - банальная лень. Но ещё хуже обстоит дело с перечитыванием этих даташитов. Мельком взгляд бросаешь - да всё то же, - ан нет есть нюанс мелким подчерком.

Вы меня жутко заинтриговали ReAl. smile.gif У Вас не бывало иногда такого состояния когда Вы смотрите на свою программу и вродебы нашли хомут дичайший. "Боже! Как оно вообще могло работать! 07.gif Блин, но ведь работало лет пять без проблем." Ну а потом выясняется что было всё правильно, а вы разбирая свою же прогу не усмотрели какой нибудь мелочи.
Вот так Вы сегодня меня в ступор ввели. Ну и я бросился некоторые свои исходники пересматривать. Оказывается в большинстве проектов флаги вообще не сбрасываются. Обхожусь аппаратным сбросом по прерываниям и т.п. Но в двух местах обнаружил. И что же -- сброшено правильно.

Видимо всётаки когда-то наступал на эти грабли, но забыл. Старость не радость. Склероз. biggrin.gif
defunct
Цитата(add @ Jul 23 2007, 22:07) *
А вот м162 заменить пока не на что.

в m162 - все хорошо.. вот только JTAG выведен "по-козьи".
Сплошное мучение с отладкой в 4k..
Цитата(add @ Jul 23 2007, 22:07) *
яж не с флагом вышел типа " даЁшь М8515 каждому крестьянину".

А его таки в прямом смысле слова "дают каждому крестьянину" в придачу с STK500..
CD_Eater
2 ReAl
Хорошо, про "глюк программы" нет возражений smile.gif

Кстати, насчёт возможной однотактовости SBI. Представьте, что это всё же сделали бы. Тогда единая на все АВРки таблица "AVR instruction set" перестала бы быть универсальной, появились бы трудно отслеживаемые различия в количестве тактов на разных чипах. Многие проекты полагаются на растактовку инструкций, и при переносе старого проекта на новый чип потребовалось бы ПЕРЕСЧИТЫВАТЬ такты участков, использующих SBI/CBI. Это намного сложнее, чем, например, заменить идентификаторы портов или их битовых полей. Обычно при переводе проекта на более новый чип требуется подкорректировать работу с периферией, это сделать нетрудно т.к. просмотром исходника легко выделить те места, в которых эта периферия используется. А попробуйте просмотром исходника (не Вашего) понять, зависит ли корректная работа программы от длительности исполнения найденной инструкции. Короче, проблем бы это добавило и Атмельцам (перелопачивать ядро), и разработчикам (переносить проекты). А так какая красота: таблица инструкций общая на всё семейство, ядро совместимо снизу вверх! Лепота!
ReAl
Цитата(SasaVitebsk @ Jul 23 2007, 23:01) *
У Вас не бывало иногда такого состояния когда Вы смотрите на свою программу и вродебы нашли хомут дичайший. "Боже! Как оно вообще могло работать! 07.gif Блин, но ведь работало лет пять без проблем." Ну а потом выясняется что было всё правильно, а вы разбирая свою же прогу не усмотрели какой нибудь мелочи.
Бывало и не раз :-), часто в ситуации "а как я это тогда сделал, сейчас опять надо". В этих случаях я иду на нарушение правила "не редактировать старые исходники в архиве" и дописываю комментарий (если его не было, если же был - то ступор и не возникает).

Цитата(CD_Eater @ Jul 23 2007, 23:12) *
Кстати, насчёт возможной однотактовости SBI. Представьте, что это всё же сделали бы.
...
Короче, проблем бы это добавило и Атмельцам (перелопачивать ядро), и разработчикам (переносить проекты).
Да прекрасно представляю, что такое сохранять совместимость со старыми "особенностями" sad.gif
Потому и сказал "будет выглядеть странно" (например, для того, кто не знает, что раньше оно было RMW), а не "и чего они не сделали однотактовой".
Лучше бы wink.gif они сразу так сделали


Наоффтопили мы тут... Придёт лесник и всех разгонит...
=GM=
Цитата(CD_Eater @ Jul 23 2007, 13:21) *
Цитата(=GM= @ Jul 23 2007, 10:04) *
Так что, для новых кристаллов команда SBI перестала быть Read-Modify-Write?

GM, в этой ветке их уже называли как минимум в двух постах. Повторю ещё раз: для всех новых чипов, начиная с тини13

Видимо вы не совсем правы, вот в документе на тайни говорится: "Do not use Read-Modify-Write instructions (SBI and CBI)..."(с.132, 133), т.е. явно указывается, что это всё-таки Read-Modify-Write инструкции.

С другой стороны там говорится "Note that, unlike most other AVRs, the CBI and SBI instructions will only operate on the specified bit, and can therefore be used on registers containing such status flags" (с.23, 216)

Выходит поведение CBI/SBI зависит от того, присутствуют там подобные флаги или нет. Кто-нибудь может прояснить ситуацию?

Вообще, интересно бы узнать, как атмельцы сделали, что неудобные флаги не сбрасываются.
IgorKossak
Цитата(ReAl @ Jul 24 2007, 15:10) *
Наоффтопили мы тут... Придёт лесник и всех разгонит...

А лесник никуда и не уходил.
Если автору уже всё ясно, пора бы и закончить.
i.dmitry
Спасибо всем. Все понял.
CD_Eater
Цитата
Видимо вы не совсем правы, вот в документе на тайни говорится: "Do not use Read-Modify-Write instructions (SBI and CBI)..."(с.132, 133), т.е. явно указывается, что это всё-таки Read-Modify-Write инструкции.

С другой стороны там говорится "Note that, unlike most other AVRs, the CBI and SBI instructions will only operate on the specified bit, and can therefore be used on registers containing such status flags" (с.23, 216)

Всё просто - часть даташита подредактировали, другую часть забыли. Такое бывает нередко. В одной из будущих ревизий где надо подправят smile.gif

А Вы подумали, что действие SBI зависит от номера порта???
=GM=
Цитата(CD_Eater @ Jul 24 2007, 21:43) *
Всё просто - часть даташита подредактировали, другую часть забыли. Такое бывает нередко. В одной из будущих ревизий где надо подправят smile.gif

Будем ждать(:-). Ради интереса посмотрел описание AT90CAN128, там с MPCM и TXC битами уже разобрались, осталось им разобраться с битом ADIF, когда используются SBI/CBI инструкции для записи в ADCSR.
Цитата(CD_Eater @ Jul 24 2007, 21:43) *
А Вы подумали, что действие SBI зависит от номера порта???

Ну так! Оно и сейчас зависит, только не для MPCM, а для ADIF. Замечу, что здесь думать не надо, есть описание, там всё чётко и ясно прописано, надо ему следовать, но не бездумно(:-). Я привык доверять документам.
CD_Eater
Уверяю Вас - если SBI не трогает немодифицируемые биты, то она так поступает независимо от номера порта. Ибо для ядра все порты равны, т.к. схема подачи сигнала записи в порт одна и та же для всех портов, а какая периферия стоит по ту сторону порта - ядру всё равно.
=GM=
Цитата(CD_Eater @ Jul 25 2007, 14:12) *
Уверяю Вас - если SBI не трогает немодифицируемые биты, то она так поступает независимо от номера порта. Ибо для ядра все порты равны, т.к. схема подачи сигнала записи в порт одна и та же для всех портов, а какая периферия стоит по ту сторону порта - ядру всё равно

Да я бы сам был рад увериться, но вот цитата (отн. новый док. 4250h, с.287)

• Bit 4 – ADIF: ADC Interrupt Flag
This bit is set when an ADC conversion completes and the Data Registers are updated. The
ADC Conversion Complete Interrupt is executed if the ADIE bit and the I-bit in SREG are set.
ADIF is cleared by hardware when executing the corresponding interrupt handling vector. Alternatively,
ADIF is cleared by writing a logical one to the flag. Beware that if doing a Read-Modify-
Write on ADCSRA, a pending interrupt can be disabled. This also applies if the SBI and CBI
instructions are used.

Которая явно противоречит с вашими уверениями. Грубо говоря, хочу с помощью команды SBI установить бит 6 (ADC Start Conversion), чтобы запустить начало преобразования, но при этом может сброситься бит ADIF от предыдущего преобразования, хотя SBI, по вашим уверениям, не должна влиять. Что интересно, в других местах адресного пространства атмел убрал влияние SBI/CBI на такие биты, соответственно, из документа исчезло описание багов.
CD_Eater
Вы зря беспокоитесь. Это недоподправленный даташит. Копируют кусками из старых даташитов, не все детали замечают.
=GM=
Цитата(CD_Eater @ Jul 26 2007, 22:14) *
Вы зря беспокоитесь. Это недоподправленный даташит. Копируют кусками из старых даташитов, не все детали замечают

Ох, вашими бы устами...да мёд пить(:-) И не беспокоюсь совсем, подумаешь ADIF, да на этот ацп со слезами не взглянешь(:-).

Расскажите лучше, как они реализовали SBI/CBI без чтения-модификации-записи?
ReAl
Цитата(=GM= @ Jul 27 2007, 13:36) *
Расскажите лучше, как они реализовали SBI/CBI без чтения-модификации-записи?
Да хотя бы так - от каждого триггера порта линия EN идёт отдельно (а не все 8 соединяются, как было бы можно для RMW), по команде SBI на шину данных блока портов выставляется 0xFF (по CBI - 0x00), а на линии EN активный уровень только на выбранный дешифратором 3-на-8. По OUT же на шину EN выставляются активные уровни на все 8 линий, на данных - из команды. Добавляется небольшой дешифратор и, что может оказаться больнее, шина из 8 персональных EN для каждого бита плюс элемент 2И на входе EN каждого триггера. Убавляется ветвь в автомате для отработки команд, которая производила чтение порта, прогон через АЛУ с формированием нужной команды (OR/AND) и формирователь нужного байта данных для операции (по сути - тот же мелкий дешифратор, только на шину данных, а не шину EN), запись результата назад.
Соответственно, команды SBI/CBI в таком виде легко могут быть однотактовыми, у них тот же путь исполнения, что и у OUT. Но, как правильно отметил CD_eater, это может "развалить" времянки у существующих программ. Хотя я предпочёл бы ускорение :-)
=GM=
Цитата(ReAl @ Jul 27 2007, 11:55) *
Да хотя бы так - от каждого триггера порта линия EN идёт отдельно (а не все 8 соединяются, как было бы можно для RMW), по команде SBI на шину данных блока портов выставляется 0xFF (по CBI - 0x00), а на линии EN активный уровень только на выбранный дешифратором 3-на-8. По OUT же на шину EN выставляются активные уровни на все 8 линий, на данных - из команды. Добавляется небольшой дешифратор и, что может оказаться больнее, шина из 8 персональных EN для каждого бита плюс элемент 2И на входе EN каждого триггера. Убавляется ветвь в автомате для отработки команд, которая производила чтение порта, прогон через АЛУ с формированием нужной команды (OR/AND) и формирователь нужного байта данных для операции (по сути - тот же мелкий дешифратор, только на шину данных, а не шину EN), запись результата назад.
Соответственно, команды SBI/CBI в таком виде легко могут быть однотактовыми, у них тот же путь исполнения, что и у OUT. Но, как правильно отметил CD_eater, это может "развалить" времянки у существующих программ. Хотя я предпочёл бы ускорение :-)

Сложно у вас как-то...и сомнительно мне(:-)

Вот смотрю я на рис.10-2 документа 4250, и не вижу никаких линий EN. Зато вижу два триггера и три линии WPx, WDx и WRx, ведущие на вход С. Атмельцы манипулируют, скорее всего, с сигналами синхронизации, а не с мифическими сигналами EN. Да и это тоже накладно, для 4 портов понадобится 64 линии связи, а для 32 портов - не менее 288 (!).
ReAl
Опять оффтопим...

Цитата(=GM= @ Jul 27 2007, 15:42) *
Вот смотрю я на рис.10-2 документа 4250, и не вижу никаких линий EN. Зато вижу два триггера и три линии WPx, WDx и WRx, ведущие на вход С.
Атмельцы манипулируют, скорее всего, с сигналами синхронизации, а не с мифическими сигналами EN. Да и это тоже накладно, для 4 портов понадобится 64 линии связи, а для 32 портов - не менее 288 (!).
Ну попробуйте нарисовать схему, которая может персонально записывать в 32*8 триггеров (порты*разрядность) без 128 управляющих линий. А куда они идут - на "мифические" EN или через те же логические элементы (но спрятанные от Вас за пределами поясняющего фрагмента схемы) напрямую на тактовый вход - разницы никакой. В любом случае - для независимой записи - независимые сигналы.

По картинке из даташита невозможно записать отдельный бит, гляньте на примечание под ней.
Теперь берём и разводим с дешифратора 3-на-8 восемь линий - по одной на каждый бит, линия одна на одноимённые биты всех портов. Теперь возле каждого WPx (которые "are common to all pins within the same port") поставим логику и замешаем для каждого бита "его" линию битовой выборки с признаком команды SBI и со стробом записи для данного регистра (тех же ACR/ACSR, не только для портов это сделано). Получим персональный сигнал. А для записи по OUT надо замешать бит шины данных, а не дешифрованный номер бита, но эта линия уже показана на том рисунке. Получается "жирная" логика на пути стробирующего сигнала - это всегда плохо, если Вы работали с ПЛИС, Вы, думаю, с этим согласны.

Можно строб записи WR объединить c сигналом выборки (ENABLE) регистра Px в логическом элементи за пределами показанного в даташите рисунка и получить строб WPx. Можно этот логический элемент в несколько другой форме поместить внутрь триггера и на строб записи подать напрямую WR, а на получившийся вход EN подать сигнал выборки Px. Если логика простая - то почти всё равно. Если логика усложняется, то с точки зрения быстродействия и отсутсвия всяких иголок может оказаться лучше на вход стробирования триггера подать "чистый" сигнал WR, а все независимые (порождаемые разными командами) разрешения свести по "ИЛИ" на входе EN. Смотрите - в той схеме, что в даташите, сигналы WPx и WRx получены каждый объединением по "И" процессорного сигнала WR, а потом они опять идут в логику. Можно наоборот - сначала всю логику разрешений записи по разным поводам свести в один сигнал "пишем" и результат комбинировать со стробом записи, тогда тот сигнал "пишем" и есть EN. На уровне жонглирования булевыми выражениями результат тот же, в кремнии реализуют тот, который окажется компактнее или быстрее, на картинке в даташите нарисуют тот, который нагляднее.
=GM=
Опять как-то неоправданно сложно у вас, а ведь еще надо оставить обычный доступ к портам. Я бы сделал следующим образом, используя алгоритм чтение-модификация запись.

1) Читаем один из 32 портов.

2) Обнуляем те спецбиты порта, которые сбрасываются записью логической единицы. Т.е. логическое И содержимого порта и выхода таблицы (по числу портов), в которой прописаны спецбиты.

3) Устанавливаем бит, заданный командой SBI/CBI.

4) Записываем результат обратно в порт.

Вот как-то так. Ну а если таблица для нового чипа не подправлена, то будет баг, что мы и наблюдаем.
singlskv
Цитата(=GM= @ Jul 28 2007, 01:20) *
1) Читаем один из 32 портов.
.....................
4) Записываем результат обратно в порт.

вот таким образом, мы и получаем 2 такта на команду
ReAl
Цитата(=GM= @ Jul 27 2007, 23:20) *
Опять как-то неоправданно сложно у вас, а ведь еще надо оставить обычный доступ к портам.
Да останется он.

Цитата
Т.е. логическое И содержимого порта и выхода таблицы (по числу портов), в которой прописаны спецбиты.
А таблица места не жрёт?
Фактически, я предложил для команды OUT подавать сигнал WPx на все 8 бит байта (один дешифратор на все порты, занимающий гораздо меньше места на кристалле, чем дешифратор той таблички), а для команд SBI/CBI - только на выбранный бит.

Это уже совсем оффтоп, но выглядит так (bitnum - поле команд sbi/cbi):

EN[7..0] = out_cmd or (sbi_cmd or cbi_cmd) and dc3to8(bitnum);
DATA[7..0] = cpu_data[7..0] and !cbi_cmd or sbi_cmd;

EN - единые для всех портов, это 8 сигналов. Причём этот дешифратор уже есть, это его выходы замешиваются в прочитанный байт в RMW-цикле, т.е. он уже был ещё в старых версиях отработки этих команд.
Да, теперь возле каждого триггера их надо подмешать к управляющим сигналам, грубо, ещё 32*8=128 элементов. Но Ваша табличка из 32*8=128 бит сама по себе плюс логика для своего считывания врядли намного меньше потребует. В виде не именно "таблички", а скомпилированной/соптимизированной логической функции - наверняка меньше, так как довольно много портов "без этих глупостей".
Но RMW для порта потребует ещё отдельнeю ветвь в автомате процессора, а в таком виде отрабатывать будут те же части, что и для OUT, просто по дороге кое-что замаскируется.
Поэтому кардинального различия в объёмах и сложности я не вижу, +- такая мелкая разница, что слово "неоправданно сложно" не подходит.

Только не надо говорить, что "ну уж они-то думали" :-) Раз смогли запихать EEADDR/EEDR в нижнюю, а TIMSK в верхнюю область IO, то могли и тут пропустить :-)

Пора этот фрагмент обсуждения выбрасывать куда-то в раздел по построению цифровых схем :-)
Завязываю.
=GM=
Цитата(singlskv @ Jul 27 2007, 23:03) *
вот таким образом, мы и получаем 2 такта на команду

Не мы, а они(:-)!

Ну а раз это есть на практике, значит 75%, что они используют довесок к R-M-W автомату...Было бы интересно, конечно, узнать, как сделано на самом деле, но уже надоело, я тоже заканчиваю тему.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.