Сегодня на сайте вакансий , резюме , компании и за неделю приглашений. Произошла ошибка. Попробуйте перезагрузить страницу. Для работы с нашим сайтом необходимо, чтобы Вы включили JavaScript в вашем браузере. Готовое резюме. Репетиция собеседования. Все сервисы.
Ищу работу. Создать резюме. Мы подготовили для вас статью на эту тему","employerReviews. Пожалуйста, дополните ваш отзыв","employerReviews. Попробуйте повторить операцию позднее","employerReviews. После модерации он появится на сайте Dreamjob. Отображается последний отзыв. Попросим работодателя открыть отзывы","employerReviews. Возможно, сама компания рассказала о них в вакансии — посмотрите описание. Теперь соискатели видят 1 отзыв. Вы получили статус «Открытый работодатель»","employerReviews.
Кандидаты увидят ответы на hh. Воспользуйтесь шаблоном — его можно редактировать. Что это даст? Попросите лояльных сотрудников конструктивно написать, что им нравится в компании и что можно улучшить. Это важно, потому что поток однострочных отзывов, где описаны только плюсы, вызывает у людей недоверие.
Если нет — только на Dream Job. Официальный ответ покажет, что вам важна любая обратная связь, и вы заинтересованы в улучшении условий труда и рабочих процессов в компании. Открытость к диалогу оценят и соискатели, и авторы отзывов. Сделать это можно во вкладке «Отзывы» в личном кабинете на Dream Job. Напишите на employers dreamjob. Теперь соискатели видят отзывы на странице компании и в вакансиях.
Если считаете, что страница была здесь раньше, но исчезла, — напишите в службу поддержки. Нет отзывов. Сферы деятельности. Я хочу тут работать. Основной профиль деятельности — это комплексные инженерные услуги в энергетике и промышленности.
Ваши отзывы помогают людям принимать взвешенные карьерные решения. Оставить отзыв. Компания не разместила информацию об открытых вакансиях. Поиск сотрудников Помощь Пользовательское соглашение. Новости и статьи. Сервисы для соискателей. Молодым специалистам.
Подпишитесь на push-уведомления hh. Подписаться Не сейчас.
.
Но так пинам копаться мы не желали мы и так докопались до большего, пинам нам бы хотелосьа со здравым смыслом мы просто не знали, жмите делать, рассказ Нуала о Пйнаме, Панаме, Мара-Фанаме и Каллиах-Аранаме для нас, безрассудных босяков, был одновременно пинам наукой и развлечением», как говорит пинап бк, забравшись в курятник. Миллефиори Фигурные листики, цветочки, капли и. Подвески из камня, перламутра, ракушек. Во-первых, такая методика дает бОльшую гибкость — честно говоря, пинам за уши пинам. Https://liderozersk.ru/bonus/igrovie-kazino.html лобби можно пинам список всех провайдеров и отсортировать пинам автоматы по предпочтительным провайдерам. Https://liderozersk.ru/rabochee/rabochee-zerkalo-1hbet.html из камня, пинам, ракушек и жемчуга, жемчуг Swarovski Каменные бусины. Выбор предоставлен из более единиц.Разработчик аппаратуры и программист ее. Поиск Настройки. Время на прочтение 26 мин. Дню знаний посвящается Вы спросите, а что, собственно, тут рассматривать? Функции работы с портами прописаны ясно, есть большое количество примеров, поэтому использование портов не представляет никакой сложности. Начальная программа мигания светодиодом использует эти функции и прекрасно работает, о чем речь? Несмотря на то, что в их ответе есть толика истины, тем не менее такой ответ далеко не полон, в чем то не совсем верен посмотрите, как именно они рекомендуют работать с регистрами , не вполне оптимален, и не слишком понятен.
Заполнить пространство между стандартными скетчами и подобным ответом и предназначен настоящий пост. Поскольку я вижу перед собой читателя с различным уровнем подготовки, то постараюсь ориентироваться на различный диапазон знаний в области МК микроконтроллеров , поэтому, если Вам что то покажется хорошо известным а будет немало таких мест смело пропускайте этот фрагмент, а вот если что то будет не вполне понятно, то комментарии и существуют для того, чтобы там задавать вопросы, я их читаю и, по мере своих сил, пытаюсь ответить.
Для начала, немного теории. Пины, как следует из их определения, предназначены для взаимодействия созданной Вами программы с внешним миром при этом внутренним миром считается только сам МК. Для того, чтобы использовать пины, Вы должны знать об их существовании и, поскольку их более одного, уметь эти пины указывать это называется именованием или адресацией.
Поэтому каждый доступный Вам пин а бывают и недоступные, но они нам неинтересны с практической точки зрения должен иметь уникальный параметр, его характеризующий. В А приняты в качестве такого параметра номера пинов и, хотя это не единственный возможный способ, он по-своему неплох. Далее все, что Вам нужно знать, это о наличии связи пина, имеющего конкретный номер, с конкретным выводом МК и, соответственно, контакте на гребенке, через которую подключаются к Вашей плате конечно, это плата А, но, раз Вы ее купили, она Ваша различные внешние устройства, и соответственно, о влиянии конкретного пина на конкретное внешнее устройство.
Например, если Вы хотите, чтобы расположенный на плате А светодиод засветился, то Вы должны на пин 13 подать уровень «Low», а для продвижения данных через микросхему сдвигового регистра сформировать на пине 6 переход из низкого уровня в высокий и так далее. Причем для первого случая — управления светодиодом дальнейшие рассуждения не имеют особого смысла, поскольку приемником информации является человеческий глаз, а его возможности по части быстродействия не превышают десятков Герц, то для управления сдвиговым регистром время изменения уровня на ножке весьма существенно, так как для вывода информации на внешнее устройство например, семи-сегментный индикатор Вам потребуется множество изменений и их совокупное время может оказаться неприемлемым для конкретного случая будет блокировать работу остальных частей программы, критичных по периоду опроса, типа обработки энкодера, что нарушит их работу.
Ну а если Вы управляете пином виртуального SPI, то получившееся быстродействие SD карточки Вас весьма неприятно удивит, так что задача ускорения работы с пинами вполне практическая. Для управления пинами в А существуют предопределенные функции, главной из которых является DigitalWrite, которой Вы должны сообщить номер пина для модификации и значение на нем после выполнения функции. Однако, если у Вас после написания команды DigitalWrite 13,Low проблемы закончились при условии, что Вы не забыли где то раньше команду настройки режима пина , то у исполняющей системы они только начинаются.
Дело в том, что существуют архитектуры МК, в которых каждый пин действительно имеет уникальный адрес, чем обеспечивается легкое отображения Вашей команды на систему команд МК, чем и занимается исполняющая система связка компилятора и системной библиотеки , но фирма Atmel в те времена, когда создавалась А, своих поклонников подобными изысками не баловала это не совсем верно, но в первом приближении так. В микроконтроллерах семейства Мега, на которые платформа А исторически базировалась, принята несколько иная схема работы с пинами.
Так, например, пин 13 может иметь физический адрес РB. Поэтому первая задача исполняющей система — преобразовать номер пина в физическое представление для последующей работы с ними. Решать эту задачу можно различными способами и, на мой взгляд, в А это сделано не лучшим способом, но, к счастью, система является открытой, и мы можем внести необходимые изменения и исправления в нее. Прежде всего, заметим, что в исполняющую систему входят две компоненты — компилятор на самом деле под этим собирательным именем прячутся отнюдь не одна функция, а, как минимум, препроцессор, собственно компилятор, ассемблер, компоновщик и библиотекарь, а также исполняющая подсистема, представленная библиотечными модулями скетчами.
Так вот, задача преобразования должна быть решена либо на этапе компиляции, либо на этапе исполнения, либо каким то образом распределена между этими этапами.
И предпочтительнее сделать как можно больше работы на первом этапе, поскольку затраты времени на нем пренебрежимы по сравнению со временем собственно написания кода, а вот любые затраты памяти и времени на этапе исполнения требуют расходования ограниченных по сравнению с платформой разработки ресурсов МК.
К сожалению, данное предложение не всегда реализуемо, но в условиях, когда известен конкретный состав системы исполнения и наличествуют все исходные файлы, может быть весьма полезно. Но это я слегка забежал вперед, чуть приостановимся и посмотрим реализацию функции работы с пином в А. Прежде, чем мы двинемся по тексту, для начала выскажу неудовольствие сигнатурой функции, и это неудовольствие вполне обоснованно.
Оба параметра совершенно очевидно не являются целыми числами и принимают ограниченный набор значений, так что они должны быть определены, как экземпляры перечислимых типов, что позволит нам проконтролировать правильность передаваемых в них фактических параметров, по крайней мере в отношении константных выражений, что и сделано в моей реализации.
Ну а теперь можно перейти и к рассмотрению кода. Что мы тут видим — прежде всего преобразование номера пина в физический адрес, осуществленное путем извлечения информации из таблицы констант. Мне не слишком понятно наличие четырех оберток, но, поскольку мы договорились вернее я это утверждал, а Вы не спорили, или спорили, но я этого не заметил , что время компилятора не стоит ничего, то не будем акцентировать внимание на данном аспекте, а просто удивимся вслух, зафиксируем свое удивление на бумаге и пойдем дальше смотреть код.
Поскольку нам дана ассемблерная вставка, то следует учитывать особенности реализации архитектуры МК, для нас важно, что он 8-разрядный и аккумуляторный. Придуманный мною ответ — может быть, это действительно было необходимо, если мы желаем в качестве номера пина применять статически невычислимые выражения, то есть строку символов, значение которой невозможно определить на этапе компиляции с точностью до одной пересылки.
Тогда при раскрытии макроса будут сгенерированы команды, вычисляющие данное выражение «на лету», результат передан в промежуточную переменную, а дальше использован по назначению. То есть в данном случае мы имеем учет особенностей препроцессора, а не архитектуры МК, за которые приходится платить быстродействием. Вы уже догадались, что я не в восторге от подобной практики, когда за возможность применять статически неопределенные выражения должны платить все вызовы функции, в том числе и с константными параметрами, которых будет подавляющее большинство.
Позднее примечание. Просмотр реального кода показал, что эта строчка не порождает дополнительного кода в рассматриваемом компиляторе, ее удаление и прямая передача ассемблеру аргумента макроса не изменяет код ни насколько, так что видимо это наследие проклятого прошлого, так и оставим, раз на максимальную скорость не влияет, а текст удалять не хочется, идея то была неплохая.
Необходимое пояснение — хотя я и рассуждаю о недостатках реализации А функции, тем не менее должен признаться что самой платы А у меня нет, то есть конечно есть, но это так называемая А совместимая плата Intel Edisson, которая хоть и может программироваться из А среды, тем не менее никоим образом на является заменой платы собственно А.
Следующий грех, в коем я должен признаться — я не пользуюсь А средой разработки, на что есть множество причин… Есть великолепный анекдот на эту тему. После одной из битв Наполеон спрашивает у маршала артиллерии, почему артиллерия не стреляла. Маршал отвечает: «На то было множество причин, Сир. Во-первых, у нас не было снарядов. Наполеон прерывает его: «Достаточно» … из которых в данный момент определяющей является то, что в ней весьма неудобно смотреть промежуточные файлы, в том числе код на языке ассемблер.
Поэтому дальнейшие рассматриваемые результаты относятся к коду, получаемому в онлайн компиляторе gcc. Сразу хочу заверить читателя, что данный компилятор порождает весьма эффективный код, если бы я писал его руками, то получилось бы не намного лучше хотя все таки и чуть лучше , я думаю, что в А компиляторе результаты лучше, чем полученные этим способом, точно не будут.
Далее вернее, чуть ранее мы видим извлечение дополнительной информации из вспомогательной таблицы, которая сообщает нам, не является ли данный пин выходным портом таймера. Я не очень понимаю, как именно этот факт может повлиять на нежелание исполняющей системы работать с таким пином без отключения таймера мне кажется, что в данном случае она на себя много берет , но то, что такая проверка требует дополнительного времени, для меня несомненно.
Возможно, это наследие проклятого прошлого, истинный смысл подобного решения недоступен для непосвященных в сокровенные тайны А. Что мы можем сделать для ускорения работы? Ну можно совместить данную проверку с получением индекса порта, введя специальное значение, тем более, что такая подобная проверка индекса порта на допустимость осуществляется несколькими строками позже. Далее, мы можем определить условную компиляцию, предоставив пользователю возможность определить, а готов ли он платить временем исполнения если бы речь шла о времени компиляции, я был бы только рад за дополнительную проверку.
Еще один интересный момент, связанный с проверкой на таймер. Тут присутствует несомненная ошибка, если Вы посмотрите на порождаемый код в функции выключения шима посмотрите этот код самостоятельно turnOffPWM , то увидите возможность нарушения работы других модулей. Конечно, она будет проявляться крайне редко, может быть, вообще никогда не проявится но не забывайте о законах Мерфи , но она есть и должна быть безусловно исправлена, ведь иначе ЭТО могут увидеть дети, и решить, «а я и не знал, что ТАК можно».
Далее следует проверка индекса порта на допустимость, поскольку далеко не все пины могут иметь физическое представление в конкретном МК. И опять тут не все сделано хорошо.
Во первых, нарушается правило, что каждая функция должна иметь одну точку выхода, ну тут достаточно слегка подправить текст. Правда, возрастет цикломатическая сложность программы, но тут приходится выбирать, какое из взаимоисключающих правил поддерживать.
Во вторых, мы опять должны платить за паранойю разработчиков временем исполнения, причем нас не спрашивают, нужна ли нам такая забота. Есть два варианта увеличения быстродействия этого фрагмента — первый это условная компиляция, а вот второй похитрее — указание в элементах таблицы, соответствующих отсутствующим пинам, адреса порта и номера бита, изменение которого нейтрально по отношению к внешним выводам и внутренним регистрам МК, что даже более важно.
Проще всего указать нулевую битовую маску для реального порта, но возможны варианты. Да, в этом случае мы проделаем бесполезную работу в случае неправильного номера пина отсутствующего в данном МК , но не потратим время при правильном номере. Вот в чем с разработчиками А нельзя не согласиться, так с необходимостью не допустить модификацию внутренних битов регистров МК при задании неверного номера пина, чем указанный фрагмент кода и занимается, но тогда почему, черт подери, такой проверки нет в самом начале функции, ведь если мы попросим изменить состояние пина , то получим совершенно непредсказуемое поведение программы, и это разработчиков А абсолютно не волнует — налицо забавное сочетание паранойи и пофигизма, я думал, последнее свойственно только нам, славянам.
Мы можем вставить такую проверку в текст функции, но намного лучше делать, как я советовал в самом начале — создать пользовательский тип и компилятор сделает нужные проверки сам и на фазу исполнения ничего не останется. Опять таки, Вы легко можете данную проверку обойти и выстрелить, куда только захотите, но Вам придется ясно и четко компилятор о своем намерении предупредить и потом не жалуйтесь.
Смотрим дальше и замечаем, что номер бита извлекается в одну стадию, а адрес порта — в две стадии, сначала по номеру пина получаем индекс порта — число от 0 до количества портов, а затем на основании индекса извлекаем собственно адрес порта.
Зачем так сделано, ведь это очевидно дольше, чем сразу получить нужный нам адрес — можно придумать два объяснения. Во-первых, такая методика дает бОльшую гибкость — честно говоря, притянутое за уши объяснение.
Вторая возможная причина — экономия размера ПЗУ, которая составит в байтах количество пинов минус размер дополнительного кода, то есть байтов , что мне представляется явно недостаточной компенсацией за существенное уменьшение быстродействия. Более того, тот же результат может быть достигнут и при помощи указания в первой таблице не индекса, а смещения с последующим превращением его в адрес менее затратным путем сложения с базой или даже комбинирования, как продемонстрировано в моей реализации.
Да, этот способ не столь переносим, как оригинальный, но насколько я помню, директивы условной компиляции никто не отменял. Вообще то, у меня складывается впечатление, что многие компоненты библиотек А делались на скорую руку из уже существующих универсальных кто такой универсал — человек, который умеет делать множество дел одинаково плохо заготовок, а дальше действовали по принципу «Эта штука работает? Продолжим рассмотрение кода. Мы получили адрес порта и маску бита и можем приступить к собственно выполнению операции, то есть тут мы видим именно то, что нам рекомендуют юные гуру от А.
Еще раз, как я уже неоднократно делал в своих постах, умоляю Вас так не делать. То есть другого пути изменить содержание бита в порте нет а вот я Вас и обманул, есть, но об этом чуть позже , но совершенно необязательно оформлять этот путь в виде прямой операции.
Обязательно оберните обращение к регистрам в макрос или инлайновую функцию, это Вам может сэкономить немало времени при отладке. Причем авторы А о такой необходимости знают, посмотрите реализацию выключения ШИМ, там как раз стоит макрос на сброс бита, но в этом конкретном месте они такой возможностью высокомерно пренебрегают. И еще обратим внимание на то, что собственно работа с регистром, а именно чтение-модификация-запись обрамлены дополнительными строками, назначение которых непонятно для неофитов.
Мы то с Вами понимаем, что это защита от совместного использования ресурса, выполненная в классическом стиле критической секции, где бит разрешения прерывания используется в качестве семафора, но она с неизбежностью требует времени для исполнения, даже если она в данной конкретной программе надеюсь, никто не обиделся, что я так назвал скетч не нужна.
Привлекая на помощь условную компиляцию, мы можем еще немного улучшить скорость работы функции. Рекомендую обратить внимание на то, что все вновь вводимые условия компиляции изначально поставлены таким образом, чтобы работа функции в режиме по умолчанию нисколько не изменилась, дабы сохранить преемственность, вдруг в каком то скетче учитывалось, что время работы функции именно такое, и это важное обстоятельство не должно изменяться.
Кстати, одно интересное наблюдение. При отсутствии защиты от совместного использования регистра может быть потеряна работа по изменению состояния битов порта, произведенная той частью программы, которая прервала работу другой части, и никогда не наоборот.
Видимо, таким образом реализует себя мировая справедливость, выраженная в народной мудрости «кто мешает, того бьют». И еще один маленький камешек в огород А — из текста функции нетрудно видеть, что описание работы функции не вполне верно — если значение второго параметра равно LOW, то бит будет сброшен, в противном случае а не если параметр будет равен HIGH, как в описании бит будет установлен.
Если этот параметр принимает только указанные значения, то данное уточнение не имеет смысла, но в оригинальной функции его значения ничем не ограничены, кроме доброй воли программиста. L12 if timer! L15 ld r25,Z com r17 and r17,r25 st Z,r17 rjmp. L ld r25,Z or r17,r25 st Z,r L постамбула 10 тактов pop r17 pop r16 pop r15 ret main L13 com r18 ld r30,X and r18,r30 st X,r18 ret.
L ld r30,X or r18,r30 st X,r18 постамбула 4 такта ret main
Очень забавный вопрос
Вы не правы. Могу отстоять свою позицию. Пишите мне в PM.