Pull to refresh

Comments 27

Для начального изучения все-таки рекомендетсяю MPLAB IDE (бесплатна) и микрочиповский C-компилятор (триал 2 месяца, потом отключается оптимизация кода). Еще есть MikroE, простой, с кучей переферийных библиотек, но платный.
А в чем существенные различия?
Какая разница, где учиться выставлять конфигурационные биты?
Какая разница на каком языке писать одни и теже команды?

Если кому-то удобнее писать INTCONbits.GIEH = 1 вместо INTCON_GIE = 1 или LATBbits.LATB0 = 1 вместо pin_B0 = 1 — я же не против — про компилирование простого мигания светодиодом в MPLAB здесь уже писали.
От выбора компилятора возможности микроконтроллера не зависят.

При использовании старших пиков про JAL придется забыть, но для восьмибитных мне он понравился на порядок больше из-за своей простоты.
Ну лучше наверное сразу привыкать к хорошему :)

Например для многих начинающих, элементарная конструкция типа PORTB &= ~(1 << 5 ); вызывает затруднения. Что бы к этому привыкнуть необходимо время. А по поводу INTCONbits.GIEH = 1 или INTCON_GIE = 1, то правильнее писать вообще INTCON |= ( 1 << GIEH );
Правильнее писать на выбранном языке, или правильнее писать команду микроконтроллеру?

Почему просто не написать pin_B5 = 0?
Если результат один и тот же, зачем заведомо усложнять читабельность кода?
Если речь идет о радиолюбительском творчестве, то это одно, но в ходе проф. деятельности вам придется иметь дело с работами других людей, работать в команде, использовать чужой код, и чем быстрее вы «въедете» в общие стандарты написания кода, темы быстрее начнете эффективнее работать… Я привел пример того как компиляторно-зависимую фичу сделать вполне стандартной. При вашем «pin_B5 = 0» вы обречены изобретать велосипед с каждой сменой компилятора или микроконтроллера.
Вот открыл я первый попавшийся пример проекта MPLAB от самого микрочипа — cdc usb. И что я там вижу в файле io_cfg.h?
#define mLED_1 LATBbits.LATB1
#define mLED_2 LATBbits.LATB0


#define mLED_1_On() mLED_1 = 1;
#define mLED_2_On() mLED_2 = 1;


#define mLED_1_Off() mLED_1 = 0;
#define mLED_2_Off() mLED_2 = 0;
...


Они тоже дураки, что для смены состояния одного бита в байте используют не тройное преобразование (которое убьется компилятором) а переменную, для этого предназначенную?

По вашему выходит что правильнее всего писать на ассемблере, там точно только универсальные команды используются.
Нет, они как раз не дураки, они просто привязывают вас к их компилятору с набором их дефайнов. На счет тройного преобразования я вообще не понял, чего должен убить компилятор. И если уж на то пошло, то LATBbits.LATB1 это не отдельная переменная, а битовое поле структуры скорее всего запиханное в union. У меня нет под рукой вашего компилятора, но скорее всего оно именно так. Так вот обращение к таким битовым полям компилятор все равно преобразует в вид LATB |= (1 << LATB) и LATB &= ~(1 << LATB) если только в процессоре нет битовой адресации, а в PIC'ах её на сколько я помню нет.
Данный спор бесполезен.
Нравится городить нечитабельный, но профессиональный огород — никто вам не мешает.
Моя задача — микроконтроллер использовать, а не вылизывать код.
Про преобразование — компилятор сам посчитает маску, а не оставит данную задачу микроконтроллеру.

Ваш вид записи хорош только в одном месте — в библиотеках, где все эти команды скрываются и выдаются под видом функций и процедур. Мне не нужно знать что из себя представляет переменная LATBbits.LATB1. В JAL, к примеру, pin_Bx — это псевдопеременная, читающая PORTB, а записывающая в LATB (при наличии этого регистра, конечно).
Или библиотеки тоже для дураков, а их использование — верх непрофессионализма?
Ни один опытный программист МК не скажет, что LATB &= ~(1 << LATB1) нечитабельная конструкция, потому что это вполне стандартная, уже привычная глазу С'ишная конструкция. А при таком подходе как у вас, вам любой код будет казаться нечитабельным. А использование специальных библиотек для работы с портами, я вообще не знаю как назвать, даже не профессионализмом это не назовешь :)
Вы считаете, что данная статья для опытных программистов МК?
Факт в том, что для программирования МК не требуется учить ассемблер или опускаться до приведенных вами контсрукций.
Написав INTCON = 0x20; T0CON = 0x82; придется писать комментарий на под страницы о системах счисления, о переводе чисел, в двоичную систему, о назначении каждого включенного бита.

Для меня такие конструкции понятны. Но разбирая такой код мне приходится каждый раз разбирать что имелось ввиду при написании команды SSPCR0 = 0x707 и высчитывать, что мне требуется изменить это на 0x72F.

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

P.S.
Ради интереса, вы поняли что я изменил действием во втором абзаце? А догадались, что изменится, поменяй я 0 на 1 в переменной из третьего?
Ну во-первых я не знаю о каком контроллере вы говорите, но если речь идет об ARM'ах то изменили вы SSPCR0 поправив 0x707 на 0x72F размер данных при обмене и формат фрейма. А вот попробуйте взять указатель на свою SSP_SLAVE… Очень часто это необходимо для универсализации кода. Например когда пишется драйвер для n-го кол-во устройств отличающихся друг от друга только адресами регистров управления.

Хоть и магические числа типа INTCON = 0x20; T0CON = 0x82; хорошим тоном не являются, но раз уж вы беретесь чего-то править, значит вы уже почитали даташит и заглянуть в него же выяснить зачем нужен тот или иной бит вам труда не составит. Самый правильный способ что-то типа этого:

/* Reset all EMAC internal modules. */
MAC_MAC1 = MAC1_RES_TX
| MAC1_RES_MCS_TX
| MAC1_RES_RX
| MAC1_RES_MCS_RX
| MAC1_SIM_RES
| MAC1_SOFT_RES;
По названию регистра вы определили что там можно изменить, но не каждый без взгляда в даташит сразу поймет что на что там изменилось. Для меня гораздо выгоднее сократить время на этом, чем на какой-то кросскомпиляторной универсальности. Для меня бОльшую универсальность представляют готовые библиотеки.

Драйвера? Серии устройств?
Тем, кто этим хочет на хлеб зарабатывать нужно читать литературу не такого уровня, как эта статья. И уж тем более не по таким микроконтроллерам.

Ардунио, наверное, тоже дураки придумали, сделав увлечение программированием МК ближе к простому народу.

Статья не для опытных, да. Но вот с чем сам столкнулся при освоении недавнем — подавляющее большинство примеров и советов на форумах даны под ассемблер и/или язык C, чаще под микрочиповские компиляторы.
В результате я лично бросил компилятор CCS PICC — который изначально для меня, начинающего показался более удобным и наглядным, именно из-за отсутствия примеров и советов — по факту оказалась эта простота кажущаяся. Библиотеки скрывали за собой понимание как именно работает контроллер, а необходимость преобразования примеров и советов из форумов совершенно в другой вид сделала бессмысленным применение «более удобного» компилятора.
Никому не навязываю свой выбор. Лично для меня простота JAL сыграла немалую роль в освоении мк.

Если б небыло готовых примеров — и не посмотрел бы в данную сторону. Но в комплекте идут все необходимые для работы библиотеки и примеры для каждого мк и для каждого модуля.
Достаточно подключить нужные модули и вызвать функции, упомянутые в комментариях к модулю — и все работает.

Выбирал недавно IDE для ARM: целый день угробил на попытку скомпилировать мигание светодиодом в самой известной среде. А все потому, что там небыло нормальных примеров, требующих нажатия только одной кнопки — скомпилировать.
Только через усиленное гугление я нашел информацию, что требуется скомпилированный файл прогонять через 2(!!!) программы, дабы прошивку можно было использовать. Другую среду разработки вообще не удалось связать с компилятором.
Впрочем, нашелся один компилятор, требующий трех шагов для старта: скачать, установить, скомпилировать пример. Но многие профи говорят, что это нечто ужасное. Хотя на вид это все та же стандартная IDE с нормальным стандартным синтакисом и стандартным, общеиспользуемым, компилятором.
Интересно, что это за IDE которую вы выбрали для ARM'а? Ну и я ни чего не понял, что за две программы через которые надо прогнать прошивку.

Для ARM есть GNU gcc с прикрученными к нему IDE типа Eclipse, Code:Blocks. Я в случае с gcc вообще IDE не пользую, блокнотик рулит. Ну и еще есть Keil, и IAR со своими компиляторами. При чем к Keil можно прикрутить и GCC.

PS. Не надо смешивать понятия IDE и компилятор :).
Первая — Kail. Сама она бинарники не лепит, нужно перекодировать эльфом. Полученный бинарник при этом не содержит контрольной суммы, потому его нужно прогонять через вторую прогу.
Вторая иде — CodeLight, которую мне так и не удалось подружить с gcc.
Рабочая из коробки — обрубок екслипса — lpcexpresso.

А понятия я не смешиваю, просто мне не требуется одно без другого.
Зачем мне IDE, из которой нельзя сразу скомпилировать прошивку? Для этого и блокнот подойдет.
Keil лепит hex. hex шьется любым программатором. FlashMagic'ом например по RS232-ому. (то есть даже программатор и не нужен)
А мне hex не нужен, мне бинарник нужен. У меня нет программатора и нет желания шить через уарт. Когда в МК содержится усб бутлоадер — нужен только бинарник.
Ну вообщем ясно, проблема как всегда из разрада хочу попроще… ну получайте попроще :)

А отлаживать с USB вы как собирались без JTAG и программатора?
Да нет никаких проблем =) Просто интересы не из разряда «для начинающих», вот и приходится тратить кучу времени не на само программирование, а на конфигурацию софта и пр.
Флешмагик мне тоже пригодится — для устройств без usb. А когда он есть — почему не шить через него?

Отладка? Да не нужна мне она! Побаловался я с swd отладчиком того же lpcexpresso — ничего полезного для себя не нашел. Тратить тысячи рублей на нормальный отладчик? Да зачем?

Вот объясните мне, пожалуста: для чего нужен отладчик? Для каких целей вы его используете? Я просто не понимаю какую полезную информацию я не могу без него получить.
Ну в идеальном случае отладчик не нужен, прикидываемся процессором и понимаем, что делает наш код. Многие сложные баги в много поточных средах вылавливаются только путем анализа в мозгах того, что происходит. JTAG мало полезен при наличии линукса на отлаживаемом процессоре. Но.
Во-первых, часто находятся баги железа, до которых нельзя дойти банальным умозаключением.
Во-вторых, если код работает не так, то с помощью отладчика можно увидеть полный статус устройства. Все его внутренние регистры (доступны в том числе и для записи прям с отладчика). Код можно прошагать прям по шагам, анализируя, что делает программа на каждом шаге. Это все если говорить о JTAG. Отладка по RS232-ому, это просто ручной вывод на печать значения переменных и анализ этих значений.
Ну, наверное потому мне отладчик и не понадобился.
Искать причину бага во всем проекте мне не приходится — проверяю каждый блок кода сразу. За все время мне пока не понадобилось серьезно копаться в мозгах МК.
P.S.
SWD — не RS-232. А почти JTAG.
Да и на этих копеечных мк нет JTAG, только SWD.
с Протеусом знаком. на нем выполняли лабораторные работы в университете. не понравилась одна интересная особенность (хотя это в целом объяснимо), то, что схемы, созданные в старшей версии программы, напрочь отказывались открываться в программе младшей версии. И ладно, если речь шла бы о мажорной версии, но различия есть и между минорными версиями. В свое время этот факт доставил множество проблем.
Про ШИМ мне кажется еще нужно сказать что он часто используется для переферии, например для сервоприводов, не в качестве питания но в качестве управляющего сигнала, передающего определенные параметры (направление и скорость вращения сервы) глубиной скважности.
Да, добавил пару строк.
Если быть точнее, для обычных серво задается только конечное требуемое положение, к которому он будет стремиться каждый полученный импульс (но вы же это знаете? =) ). Вот только скважность при обычных 50 Hz составит от 3.5% до 11%, потому проще будет воспользоваться режимом сравнения, а не шим.
/me изрядно благодарен за ясные объяснения абсолютно новых вещей.

гениально!

Sign up to leave a comment.

Articles