WinAvr в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Ответить
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18675
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Alexeyslav писал(а):есть - пишется как "|| <маска битов>"
ни в коем случае! пишется так "| <маска битов>"
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18675
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

FreshMan писал(а):#define SetBit(reg, bit0, bit1, bit2) reg |= (1<<(bit0)|(1<<(bit1)|(1<<(bit2))
во-первых, снова непонятное увлечение макросами - для установки сразу 4 бит сделаете еще один макрос, для двух - еще, для пяти - тоже?! чем ваш макрос лучше обычной записи?!

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

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

попался мне на глаз один и тот же макрос но по разному записанный
#define SetBit(reg, bit) reg |= (1<<(bit))
#define BM_SetBit(var, bit) do{(var) |= (1<<(bit));}while(0)

равнозначны ли они по правильности ?

почему этими макросами пользоватся не рекомендуется ?
#define sbi(port, bit) (port) |= (1 << (bit))
#define cbi(port, bit) (port) &= ~(1 << (bit))
Последний раз редактировалось FreshMan Вс май 11, 2014 09:31:55, всего редактировалось 1 раз.
Tell Me The Truth
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич

Сообщение Alexeyslav »

правильность - понятие субъективное. По сути, если ОНО работает - оно правильно.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

почему этими макросами пользоватся не рекомендуется ?
#define sbi(port, bit) (port) |= (1 << (bit))
#define cbi(port, bit) (port) &= ~(1 << (bit))
Скорее всего, из-за схожести с ассемблерными командами.

И еще они могут привести к ошибкам тех, у кого мало опыта в программировании. При их использовании нужно четко понимать, что они делают, а не абстрактно представлять, типа "сбрасывают нужный нам бит и не трогают остальные"
Я не так давно нарвался на такую ошибку. Думал баг какой-то у контроллера нашел. Но один очень внимательный человек на форуме меня образумил (причем, при всем его большом опыте тоже не сразу нашел).

Взять, например, регистр настройки и управления АЦП. В нем часть битов включают те или иные функции (в том числе сам АЦП), и есть 1 бит флага, который сбрасывается записью 1 (именно комбинация флагов с обычными битами в одном регистре и дает ошибки). А теперь подумайте, что будет, если Вы сбрасываете или устанавливаете какой-то управляющий бит одной из этих макрокоманд и при этом у Вас на тот момент установлен флаг прерывания? Правильно, флаг сбросится. Т.е. можно даже сбрасывать флаги вот таким способом: ADCSRA = ADCSRA

Другой момент. Регистр UDR интерфейса UART. при чтении он извлекает данные из буфера ПРИЕМНИКА, а при записи он посылает данные в буфер ПЕРЕДАТЧИКА. Естественно такой способ записи в него не канает. Кстати, ассемблерные команды SBI и CBI к данному регистру также применять не рекомендуется, поскольку они также делают чтение-модификацию-запись.

P.S. Пользоваться можно всем. Только необходимы соотвествующие знания и умения.
Реклама
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

FreshMan писал(а):равнозначны ли они по правильности ?
Да, равнозначны. Второй вариант позволяет более гибко им (макросом) пользоваться.
http://www.opennet.ru/docs/RUS/cpp/cpp-5.html (см. раздел "Использование точки с запятой")
FreshMan писал(а):почему этими макросами пользоватся не рекомендуется ?
Отчего же, ИС-пытатель правильно написал - главное чётко понимать что делается.
А то может получиться как вот в этой теме, например.
ИС-пытатель подтвердит. :)
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

Вот, вот этот человек, подозрительной наружности, который нашел мою ошибку! :)))
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18675
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

ИС-пытатель писал(а):Т.е. можно даже сбрасывать флаги вот таким способом: ADCSRA = ADCSRA
хотя при этом флаги и сбросятся, но в целом гарантировать предсказуемый результат при этом нельзя.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

В смысле?
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18675
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

ARV, race condition?
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18675
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

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

Сообщение ARV »

должно или не должно - это можно гадать, факт в том, что МОЖЕТ такое быть. и рано или поздно такое может произойти.

поясняю:
пусть идет преобразование АЦП, т.е. бит ADSC установлен.
начинает выполняться оператор ADCSRA = ADCSRA;
считывается во внутренний регистр содержимое ADCSRA, и тут возникает прерывание, хоть бы и от таймера. пока прерывание отрабатывает - завершается преобразование АЦП и бит ADSC обнуляется. после отработки прерывания вы записываете в ADCSRA содержимое временного регистра, а там ADSC установлен - вуаля! происходит несанкционированный старт преобразования.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск

Сообщение WiseLord »

Тут ещё вопрос, не выбросит ли при оптимизации компилятор такую инструкцию вообще, как бессмысленную (с его точки зрения).
Контактная информация:
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

ARV, race condition !!!
В чистом виде race condition!

Race conditions [рэйс кондишэнс]. Это ошибки связанные с последовательностью выполнения операций. Это термин из параллельного программирования, но тут он тоже применим. Перевод на русский , на мой взгляд, обычно некорректен, так как не отражает смысла. Я бы сказал, что это можно назвать "условия выполнения" или "ошибки последовательности выполнения". А смысл в том, что последовательность выполнения операций может быть не такая, которую представлял себе автор кода. Это могут быть вариации по типу случая как выше описал уважаемый ARV. А могут быть и совсем замороченные варианты.
Одно радует, что в простых МК таких вариантов не слишком много. Это модификация регистров периферии и модификация много байтовых volatile переменных (программы с прерываниями). И то и другое можно избежать при хорошем знании МК, проработке алгоритма и использованием атомарных регионов (где требуется). Может кто-нибудь добавит ещё что?
СпойлерРус. - http://ru.wikipedia.org/wiki/%D1%EE%F1% ... E%ED%EA%E8
Англ. - http://en.wikipedia.org/wiki/Race_condition
Кстати, вариант описанный ARV может произойти и без прерывания. Если "удачно" сложиться ситуация, когда прочитается состояние в последний такт перед сбросом флага...
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Вымогатель припоя
Аватара пользователя
Сообщения: 577
Зарегистрирован: Ср июн 19, 2013 08:10:48
Откуда: Москва, СПб, Липецк, Рязань

Сообщение ИС-пытатель »

WiseLord писал(а):Тут ещё вопрос, не выбросит ли при оптимизации компилятор такую инструкцию вообще, как бессмысленную (с его точки зрения).
Не выбросит. Все регистры по умолчанию объявлены как volatile
Если "удачно" сложиться ситуация, когда прочитается состояние в последний такт перед сбросом флага...
О, мля.. А вот об этом я как-то не подумал.. )) Спасибо, буду знать. ) С прерываниями-то понятно, их всегда в голове держишь..

А с другой стороны, рассматривая в этом же ключе, чем ADCSRA = ADCSRA отличается от ADCSRA |= (1<<ADIF) ?? Также можно случайно запустить новое преобразование.

Кстати, еще интересен такой вопрос: если во время преобразования попытаться сбросить флаг ADSC (старт преобразования и его текущий статус, идет/не идет), то преобразование остановится? или же его можно остановить только выключением всего АЦП?
Мудрый кот
Аватара пользователя
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

Сообщение Kavka »

Да, можно и таким способом ненароком запустить новое преобразование. Не забывай про "хорошее знание МК и проработку алгоритма".
Ответ на второй вопрос тоже лежит в области знания МК - внимательно читай спецификацию.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18675
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

ИС-пытатель писал(а):А с другой стороны, рассматривая в этом же ключе, чем ADCSRA = ADCSRA отличается от ADCSRA |= (1<<ADIF) ??
ничем не отличается, поэтому ручное сбрасывание флагов запросов прерываний делать надо с особой осторожностью. лично мне никогда и в голову не приходило использовать ADIF для определения окончания преобразования без прерываний - ADSC для этой цели куда логичнее (и безопаснее) использовать.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 6296
Зарегистрирован: Пн ноя 22, 2010 00:57:15
Откуда: Ukraine

Сообщение FreshMan »

ARV писал(а):ADSC для этой цели куда логичнее (и безопаснее) использовать.
но тогда надо будет коротать время в цикле, ожидая пока ADSC не станет равен нулю
а если мне надо запустить преобразование и идти дальше по своим делам, как тут быть ?
насколько я понимаю, без проверки ADIF тут не обойтись
Tell Me The Truth
Ответить

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