Первая видеовстреча сайта

3 января мы проводили видеовстречу, несколько людей согласились принять участие и поделиться своими знаниями. У нас было 17 зрителей трансляции, а запись уже посмотрело более 250 человек.

Темы обсуждений:

  1. Структуры в Си
  2. Стандарты оформления C кода и MISRA C
  3. UART и преобразователи USB-UART
  4. USB/HID в микроконтроллерах STM32
  5. Настройка таймеров в STM32
  6. Измерение среднеквадратичного значения тока
  7. Указатели в C, форматирование кода, шаблоны

Стенограмма встречи

Вступительное слово

(2:50) Николай: Добрый вечер, друзья, добрый вечер. Я всех вас рад видеть. У нас первая видеовстреча сайта, это очень круто. Я очень рад что столько людей подключилось. У нас много лекторов, каждый — спец в своей области, это замечательно. Как вы знаете, я очень люблю STM32, электронику вообще, я выступаю за популяризацию этого дела и я думаю всё будет очень круто здесь. Ну что же, давайте начнём, первая наша лекция это структуры в языке СИ, тем временем я думаю люди ещё подключатся.

Николай Горбунов, структуры в Си

1

(3:45) Николай: Так вот, структуры. Я уверен что многие из вас знают что такое структуры в Си, это очень удобная вещь: вы можете положить в одну область памяти, в одну сущность сразу несколько разных значений, несколько переменных, несколько строк, булевских переменных и так далее. Ну то есть, я просто начну для тех кто не знает, для тех кто может быть что-то слышал, кто-то может быть не видел, не знает что такое структуры.

Всё очень просто. Ключевое слово Struct обозначает что мы объявляем структуру, и в фигурных скобках перечисляем: int i, массив из десяти char (char s[10]), и допустим bool, некое состояние on (bool on). Так (struct) мы объявили тип структуры, а так (param) мы объявим экземпляр, это будет некий параметр params. Я уверен что здесь всё понятно: объявляем переменную типа int, переменную char — десять char`ов, булевская переменная: это такая структура, и объявляем экземпляр структуры params. Я убеждён что вы все это знаете, это всё очень просто, но я хотел рассказать про другое, о том как эта структура хранится в памяти. Она хранится довольно просто: в памяти заводится соответствующее количество ячеек, начали со стартового адреса, идёт и переменная int: 4 байта. Потом в память складывается char, 10 байт (нарисую 3, этого достаточно будет), и булевская переменная, которая займёт один байт, и всё. Именно так в памяти лежит эта структура.

Самое интересное в этом то, что мы можем просто взять, скопировать память начиная из начала и заканчивая конечным адресом и просто скопировать эту память в любое место. то есть структура это не что-то волшебное, не некий специальный тип данных, это просто некая размеченная область памяти. просто байты, идущие подряд в памяти, которые компилятор си некий образом разметил, и мы можем работать с этим как посредством удобных ячеек (начиная отсюда прочитать int, начиная отсюда прочитать char, или отсюда прочитать bool), но мы можем точно так же обратиться к этому как к массиву байт. мы можем сделать sizeof params, он будет равен в нашем случае 4+10+1=15. можем прочитать 15 байт — и это будет просто массив байт.
И мы можем эти байты сложить в массив операцией memcpy, которая примет аргумент «массив», «источник, указатель на params» и 15 байт, которые занимает структура. В этом массиве байт (его нужно будет заранее объяснить, например char *byte) мы теперь можем передать по GSM в хост, на комп или в другое устройство, таким образом мы получаем переброс данных с одного девайса на другой, это очень удобно потому что мы получаем простейший канал передачи данных, сразу на одном девайсе мы можем получить копию состояния другого девайса.

Это то, что в интернете называется RESTful, то есть полное репрезентативное состояние, и таким образом, допустим: есть у нас девайс, GSM-трекер или что-то такое. У него может содержаться некий номер в Int, название, включен он или выключен, и параллельно переменные типа float, обозначающие положение и ещё что-нибудь. Эту структуру мы можем полностью скопировать и передать на хост.

Это очень удобно, мы можем на хосте сделать точно такую же си-программу, которая хранит массив структур, и просто запихнуть новую структуру в массив, точно так же приняв массив байт и взглянув на него как на структуру. То есть, даже не нужен массив, мы можем просто сразу работать с этого места (со старта) как с массивом байт. На мой взгляд это крайне удобно, более того на текущей моей работе мы используем именно такой механизм для обмена данными сервер-клиент. Конечно, это всё можно завернуть в JSON, но и такой метод очень удобен. И я ещё немного коснусь этого метода в следующей лекции про USB-HID, где он будет очень удобен. Последнее что я хотел бы сказать — что мы действительно можем просто использовать одно и то же место в памяти как структура (память просто размечена компилятором на некие куски), и точно так же мы можем с этого же места читать как массив байт, и нам даже не нужен будет дополнительный массив.

Это, пожалуй, всё что я хотел сказать. Извините, ещё: чтобы здесь не возникало зазоров (некоторые компилеры здесь могут вставить зазор, сделать так что длина этого int будет 8 байт, это называется выравнивание, и тогда вместо такой красивой картинки получится большой зазор, и только после него начнётся строчка). Это выравнивание по границе 8 байт, и это удобно для процессора, но неудобно для нас, потому что занимает много памяти. Чтобы это отключит, применяется директива #pragma align, которая просто вы можете настроить границу чтобы она стала равной 4 байтам или 1 байту, чтобы он выровнял по такой границе, и строчка начнётся уже здесь (сразу после int). Это, пожалуй, всё.

Андрей Дердемьянский, стандарты оформления кода и MISRA C

2

(14:55) Андрей: Я сегодня расскажу про стандарты оформления кода и немного про оптимизацию кода. Первые две части будут по стандартам оформления, почему это нужно, какие есть варианты, где это взять и посмотреть. Вторая часть будет про оптимизацию кода, но это будет очень поверхностно, некоторые основные моменты которые стоит учитывать в своей работе. Первая часть — это MISRA С, это стандарт оформления кода, как следует писать на языке С, для МК и вообще для встраиваемых систем, но в принципе это годится и для компьютерных приложений.

Cам я в работе очень часто использую это и на компьютерных приложениях потому что это достаточно важно, но также это очень актуально и для встраиваемых систем. существует два варианта стандарта, 98 года и 2004. Они разнятся по количеству правил, там их порядка 120-140 правил в зависимости от стандарта, и они могут разделяться по степени важности, как очень важные, не очень важные и такие, которые нужно смотреть по ситуации. Соответственно, исходя из практики, для компьютерной сферы можно выбрать только самое важное правило, а неважное отбросить использовать по своему усмотрению. Для встраиваемых систем лучше конечно использовать максимум правил. (16:20)

Итак, что это за правила. В первую очередь устранение неоднозначности численности кода, для того, чтобы код был понятен всем программистам, которые его смотрят. Потому, что проекты смотрятся не только вами, но и другими людьми, если вы выкладываете код куда-нибудь в интернет. И вторая задача этого, чтобы код был переносим между разными компиляторами. Допустим, вы написали для тех же МК одну часть в IAR`е либо в CooCox`е. А потом решили перенести в другое место. В тот же CodeVision.

Итак один из важных нюансов по оформлению кода это устранение неоднозначности кода как в плане понимания программистов, как и в плане понимания своего компилятора. Сюда очень часто можно включить инкременты, декременты. Очень часто народ встраивает какую-нибудь операцию так, что это может трактоваться неоднозначно например где-нибудь в if-ах. (17:27) Получается, что мы будем ждать одного результата, а получается совсем другое.

Более подробно советую почитать про MISRA, по этому поводу в интернете очень много ссылок. Можно скачать оригинальный документ от верхних на английском языке. Думаю, это не проблема. Можно также найти на русском языке описание важнейших элементов. В принципе ищется без проблем: «MISRA С», и выбираете стандарт MISRA С 98 и описание и получается выдастся ссылка с описанием того, что нам надо.

Из личного опыта могу сказать, что большую часть этих правил крайне желательно использовать. Это например по поводу макрофункций. Там есть подробное и хорошее описание почему и как нужно оформлять эти вещи. Описание инкрементов, декрементов. Описание как раз использования структур (18:15) и многие другие моменты, которые часто вызывают ошибки в работе программ. Это достаточно важно. Из личного опыта, что могу сказать. Это то, что код стоит писать так, чтобы комментарии были практически не нужны. Т.е. давать осмысленные имена переменным, давать осмысленные имена функциям, лаконичные и четкие. И писать код так чтобы он выглядел похожим на английский язык, чем на какую-то абракадабру. В этом плане будут помогать как раз макропостановки функций с помощью define. (18:45) Здесь есть нюанс, который как раз в MISRA учитывается. Не стоит ими увлекаться, потому что это может повлечь за собой череду ошибок которые будут трудно обновляться

Что такое define в языке Си? Это просто макроподстановка. Просто компилятор находит где-то у нас имя define`овское, определенное. И берет из определения и подставляет в нужном месте кода то, что мы там указали. Очень часто это можно увидеть когда мы подставляем константу ПИ. Она определена в файле math.h просто как define и как 3.14 и остальные знаки.

Как это происходит? Мы в коде пишем M-PI делить на 2, а компилятор в этом случае этого значения просто берет и подставляет в исходный наш файл. Это не какая-то переменная это просто подстановка компилятором. Поэтому когда мы подставляем таким образом функции стоит учитывать нюанс скобок, нюанс переноса строки и прочие другие вещи. (19:49) Это очень удобная вещь!

Из таких ярких промеров define, например в эмбеддерской сфере очень часто надо использовать какой-нибудь вид подставлять. Например стоит бит «второй», и бит «третий». Как это делается? Обычно с помощью битовых сдвигов. В скобочках указываем один битовый сдвиг влево и количество сдвигов: 0,1,2,3,4. Писать каждый раз это не удобно. Поэтому лучше написать define bit Х и дальше указать то, что нужно. Я могу потом в комментариях это видео выложить. Но это не суть важно. Это любой ищет сам. Это один из таких ярких примеров удобочитаемости. Кстати такая вещь по поводу бит Х очень часто называется «синтаксический сахар» (20:35), потому что повышает удобочитаемость кода. А вместо непонятных циферок и прочего у нас есть лаконичное словесное определение того, что у нас происходит.

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

Как это можно разрулить? (21:22) Сделать функцию inline подставляемой. Есть такая функция «директива»: пишем вместо void написать inline void. Есть один нюанс: inline означает, что функция будет именно подставляться. То есть, если эта функция используется достаточно часто вами, то в исходном коде это будет не так заметно. А вот в компилированном файле это может достаточно серьезно повлиять на его размер. Если функция достаточно большая, то рост весьма значительный. Здесь просто стоит учитывать нужна ли вам здесь оптимизация по скорости. Если функция вызывается достаточно редко, то это вообще не нужно в принципе. Если функция вызывается часто, то просто стоит учитывать нюанс того что идет просто разворачивание кода. Поэтому в ограниченных размерах стоит это учитывать.

Второй момент по поводу оптимизации кода что я хотел бы сказать это не писать «лапша-код» Это функция очень длинная, очень не понятная и программист сам часто в них запутывается. Поэтому желательно сам код разбивать на какие-то подалгоритмы и просто делать реализуемые функции. Как-то вот так. Если будут какие-нибудь вопросы я потом на них отвечу. Спасибо за внимание.

(22:37) Николай: Отлично! Спасибо тебе большое. Классная лекция. Теперь Вадим.

Вадим Каплунов, UART и преобразователи USB-UART

3

(22:47) Вадим: Да, друзья, я снова с вами. Сегодня речь пойдёт о USB-UART`ах. Давайте сразу объяснимся, для чего это нужно. Это нужно для того, что когда вы не можете использовать в устройстве HID, или прочие STM`овские фишки, с помощью которых вы можете подключить вашу замечательную плату на STM`е к компу — вы можете подцепить её к компу. Практически во всех микроконтроллерах STM Есть такая штука как UART, это последовательный интерфейс. Но поскольку большинство производителей направлены на решения 5-вольтовых микроконтроллеров, то возникает ряд проблем с тем, чтобы законтачить по UART вашу STM-ку с компом, с внешним миром.

Решение есть, сейчас я покажу. Протокол данный называется RS-232, на самом деле он древний как вся аналоговая техника, но он очень популярен. Почему, потому что он очень простой, там нужно всего два провода и земля, чтобы что-то законтачить, но опять же скажу что не все поддерживают 3.3 вольта. Конечно, часть из вас скажут что где-то порог открытия 5-вольтовой логики начинается на 3.3 вольта, но например у меня лежит дискавери, у неё питание 3 вольта, и её вы уже законтачить на 5-вольтовую логику вы просто не сможете, потому что у неё логическая шина будет чуть ниже 3 вольт. Соответственно, я здесь выписал несколько микросхем которые вообще я юзал для того чтобы законтачить с STM.

Самая дешёвая из них это первый вариант, CP2102. Стоит сейчас, с нашим курсом, что-то около 50 рублей. Это такая маленькая микросхема в QFN-28, который крайне неудобно паять, и большинству начинающих радиолюбителей крайне не рекомендую, потому что развести и сделать плату, допустим дома, под 0.2мм дорожки довольно проблематично. Но зато она применима в продвинутых приложениях, например сейчас мы разрабатываем устройство, оно будет на STM32F030, у него всего 20 выходов, и USB встроенного там нет. Соответственно те же проблемы с тем чтобы законтачить это с компом, решили с помощью этой микросхемы. Микросхема стабильная, рассчитана сразу на 3.3-вольтовую логику, минимальное что я к ней подцеплял — это было 2,5 вольта на STMб она работала от 2.5 вольт, а CP2102 работала на 3.3.

Далее самое культовое решение, это FT232. Я не знаю ни одного радиолюбителя и электронщика, который с ней не сталкивался, потому что компания FTDI, которая производит данные микросхемы, по-моему, начала их впихивать всюду и её удобный SOP-28 корпус, который позволяет вам разводить дорожки под 0.3мм, в принципе позволяет вам воткнуть её в любое устройство. Единственное, у неё ряд проблем, она в основном рассчитана на 5-вольтовую логику, а 3.3-вольтовая логика у неё один из режимов, и мы на неё остановимся. FT2232 — ещё одно предложение от FTDI. Собственно, это две 232 микросхемы. На нём делается обычный JTAG, но по частотным характеристикам она лучше чем 232, соответственно если вы хотите резко поднять скорость передачи данных, вам 232 не хватает — берите 2232 или 4232. 4232 — там соответственно четыре COM-порта, что вам позволит подключить в принципе до 4 STM. (27:23)

Дальше микросхема PL2303, я её юзал, честно признаюсь, один раз и остался крайне ей недоволен. Почему — потому что она требует, во-первых, большого количества элементов обвязки, во-вторых вы обязаны ей воткнуть кварц. Это сильным оказалось неприятным моментом, потому что предыдущие микросхемы не требуют делать дырки в плате вообще, а PL2303 почем-то захотела кварц.

Последнее решение это TUSB, это пожалуй самое олдскульное и культовое решение, это вообще одна из первых микросхем, которая позволила эмулировать COM-порт, это пожалуй наверное такое вот. Если вы хотите сделать плату а-ля стим-панк или прочее — то пожалуйста, её юзайте, но я её сейчас не смог найти в открытой продаже, поэтому я с ней не очень люблю работать.

Вообще, любая микросхема, здесь приведена CP2102, она содержит следующее: у вас есть входы прямые и входы USB (D-, D+) и питание. В принципе, современные микросхемы позволяют подключать USB-коннектор прямо без ограничивающих ток сопротивлений и без стабилитронов на каждую из линий. Это отличная вещь, потому что 90% начинающих электронщиков это забывают сделать, из-за чего у вас начинаются на больших скоростях огрехи, и это приводит к некоторым проблемам. На выходе у неё собственно всё стандартно: биты RX/TX и остальные биты RS-232. (29:22) В плане фильтрующих конденсаторов я скажу следующее: она не очень привередлива, на самом деле у меня она потребовала одного конденсатора в 1000 пФ и одного конденсатора в 0.01 мкФ, и ей было достаточно, мы её гоняли даже на больших скоростях.

В чём ещё её плюс — у неё есть 3.3В регулятор, и если у вас периферия потребляет не очень много тока, то вы можете взять просто и запитать её с CP2102. Таких выходов я пару видел в промышленных устройствах, но как-то сам я не рискнул, потому что там выход то-ли 10, то-ли 20мА, в принципе для питания STM достаточно, но если у вас есть какая-то ещё обвязка, то бойтесь, потому что как только она чувствует что линия просела ниже чем 3.2В, она отключается, и после этого вы её просто уже не запустите.

12

(30:33) Вот собственно одно из решений, которое я сделал на данной микросхеме, вот чёрный квадрат на плате — это как раз QFN28, крайне неприятная вещь в пайке. Следует ещё заметить что есть одно такое ещё очень культовое решение — это запихивать RS-232, содержащий 3 линии, в аудио-джек. Решение такое присутствует на многих коммерческих, промышленных платах, почему это удобно — потому что аудио-разъёмы 3.5мм продаются везде, и найти кабель который нужен нам чтобы это соединить с компом, можно просто везде. Данное устройство я вообще рекомендую собрать любому пользователю: оно содержит USB, два джампера, которые в случае чего перекинут вам линии RX/TX местами, и аудио-джек. Собирается это всё дело буквально за полчаса, но потом вы можете использовать это в любом своём устройстве в качестве подключения к компу, например для наладки устройств.

(31:54) Вот собственно, культовое решение на FT232, оно содержит джампер, его надо перекинуть на линию 3.3В, тогда там микросхема будет работать на 3.3В логики. С этой микросхемы я начинал работу, сегодня будет некоторая демонстрация, которую я покажу. Там как раз реализована данная схема, поэтому если вы вдруг захотите перейти с AVR на STM, не выкидывайте свои FT232, вы их можете заюзать например для USB-UART. Вот собственно PL2303, это USB-UART. Здесь я сразу скажу что здесь дофига обвязки висело, и это жутко неприятно, и она очень чувствительна к обвязке, если вы вдруг неожиданно чего-то нарушите, она вам это не простит.

Обрабатываются обычно эти вещи в написанных программах, либо если вы начинающий электронщик, вам поможет такая штука как Terminal. Я пользуюсь версией 1.9, это такая культовая штука, она позволяет вам регулировать скорость приёма, количество бит, проверку чётности, стоповые биты и наличие остальных линий. Вообще говоря, в компьютерной технике интерфейс 232 был сделан как COM-порт, в нём логические линии были +3..+12 вольт. Сейчас таких разъёмов в ноутбуках я видел мало, поэтому для того чтобы преобразовать к старым устройствам, обычно используют какую-нибудь FT232, и микросхему из серии 232, их громадное множество, чуть ли не каждая фирма их выпустила, здесь приведена MAX232 от Texas Instruments, она генерирует нужные +-10 вольт и создаёт две линии, тут два TTL-входа, два TTL-выхода и два выхода на высоковольтную часть.

(34:30) Теперь давайте я вам покажу небольшую игрушку, игрушка у меня находится на столе. <…> (35:05) Это дискавери, здесь у меня небольшая плата, в ней воткнута FT232 и на АЦП изменяется цвет светодиода и шлётся это в UART. Потом мы открываем Terminal, нажимаем кнопку Connect (заранее выбран COM3, которым у нас определилась данная микросхема), и видим что непрерывно шлёт данные. Здесь, по-моему, 9600 скорость. Видим что если мы крутим резистор — изменяется значение на АЦП, соответственно изменяются посылаемые данные. Крутим резистор, одновременно изменяются данные, я показывать не буду. Если хотите — можете такую штуку собрать сами, это не так сложно.

Давайте сразу скажем что есть большое количество людей, которые скажут что есть есть USB-HID, и зачем мучаться с USB-UART, и вообще зачем это. Допустим, вы собираете устройство, вы всё на нём продумали, но вам нужно быстро и просто настроить работу. Пользоваться дебагом можно, но он будет несколько останавливать работу вашего устройства. В некоторых моментах это хорошо, но в некоторых моментах вы делаете тысячи измерений, вам нужно понять что происходит в конце этой тысячи измерений без остановки основного цикла, вам эта вещь очень сильно поможет. Особенно, я повторюсь, если у вас есть USB-джек и есть универсальное средство чтобы подключиться к данной аппаратуре. На этом у меня всё, теперь я передаю слово Николаю с USB-HID, надеюсь он меня сейчас не совсем в прах разнесёт, потому что я тоже очень люблю USB-HID, где можно его втыкаю, но иногда просто не получается.

Материалы: Презентация

Николай Горбунов, USB-HID в STM32

4

(37:45) Николай: Отлично, спасибо, Вадим. Да, действительно, теперь мой рассказ про USB-HID. На самом деле это тема в которой я сильно разобрался буквально недавно, раньше я его юзал, ну знаете, по примерам. Теперь я его знаю полностью досконально и хочу рассказать про него вам. вы знаете что USB — это последовательная шина с возможностью подключения разных устройств в том числе нескольких одновременно. Вадим сказал про FT232 и подобные микросхемы, да, действительно, обычно так и делается, но можно всё-таки сделать передачу данных без прослойки, потому что есть настоящий USB-контроллер в STM, и этот интерфейс проще, чем он может показаться.

Принцип работы USB довольно прост: хост, то есть компьютер, постоянно опрашивает все девайсы, каждую миллисекунду (это можно настроить) он подключаетсяк каждому из настроенных девайсов, посылает ему сигнал «старт фрейма» и предоставляет ему небольшое время (это время называется таймфрейм), в течение этого времени девайс может отправить хосту или получить с хоста до 64 байт данных, и после окончания таймфрема (окна передачи) хост отправляет сигнал «End of Frame», то есть конец фрейма и переходит к следующему девайсу. Нам из этого нужно запомнить только то что каждый девайс связывается с компом где-то раз в миллисекунду, т.е. тысячу раз в секунду, и максимальная скорость передачи таким образом составляет 64 кбайт/сек.

Нужно помнить что в одном реальном девайсе (физическом) находится несколько виртуальных. Эти девайсы называются эндпойнты, конечные точки, и каждая такая точка может делать что-то своё, они никак друг с другом не связаны. вы можете в одном кристалле STM32 воплотить мышку, виртуальный ком-порт, флешку и миди-девайс, если вам это всё нужно одновременно. Не думаю на самом деле, что вам всё это нужно одновременно, на такая возможность есть.

Кстати, виртуальный ком-порт, по-моему, устроен как три эндпойнта: один управляющий низкоскоростной, по нему передаётся скорость подключения и другие настройки — те самые которые показывал Вадим в программе Terminal, вот эти все настройки: скорость, чётность и прочие штуки, и ещё два канала: один канал на передачу из девайса в комп, и другой канал на приём из комп в девайс. Такие три эндпойнта действительно используются в одной функции вирт ком-порта.

На старте девайс отправляет компу свои параметры: VID, PID и серийный номер. Эти номера: Vendor ID, Product ID и серийный номер девайса. По этим номерам девайс однозначно идентифицируется, они являются ключом доступа. вы можете на компе просто обратиться по этим трём номерам и сразу найти этот HID девайс и подключиться к нему. Также отправляются название компании-производителя, требуемое питание: там заморочки с тем что вы можете назначить получать от компа 500ма питания или можете вообще не получать питания, сказать что у вас есть батарейки. Если превысить заказанные настройки, то вас просто отключат. Сам хост это делает автоматом.

И самое главное — это тип и количество конечных точек. Это самое интересное, потому что каждая конечная точка описывается как структура, как я рассказывал на первой лекции. Обмен данных происходит не символами (посимвольно как в UART), а пакетно: не нужно разбирать начало и конец сообщения, проверять контрольную сумму и прочие штуки. Знаете, вот у меня на работе мы общаемся с игровыми автоматами по COM-порту, и это на самом деле мучение. Там ещё особенный протокол, 9 бит в уарте со стартовым битом, что-то такое, ужасно вообще. Особенно если ты включился не в промежутке между посылками, а где-то в середине — тебе ещё нужно понятоь что это середина, и как-то это всё просппустиь, в общем сложно.

Тут всё гораздо проще: пакетный режим передачи, и если структура пришла, пакет пришёл — значит он пришёл полностью и корректно, уже не нужно как-то проверять его, проверять контрольную сумму, целостность ли что-то ещё такое, вы можете сразу с ним работать. И да, здесь очень хорошо ложится принцип из первой моей лекции, «перекидывание структурами»: вы просто копируете структуру, начиная со стартового её байта, заканчивая количеством байт в структуре. Кстати да, на старте вы ещё говорите, что собственно у вас будут за структуры, и их размер. Потом уже нельзя выйти на эти начальные настройки, но хорошо что можно очень много сразу этих настроек послать.

Так вот, HID это действительно самый простой протокол в USB, Human Interface Device, устройство взаимодействия с человеком. Он применяется для мышек, клавиатур, джойстиков, но несмотря на название он не ограничивается общением с человеком. по сути, это относительно низкоскоростной протокол с маленькими частыми посылками. то есть каждую миллисекунду вы можете иметь у себя в памяти структуру, посланную с компьютера и точно так же отправить свою структуру на компьютер. К демонстрациям! у меня есть небольшая демка, которую я хотел бы вам показать. <…>

(46:18) Сейчас видно программку на фоне схемы? Программка, которая подключается к девайсу на STM-ке, она прочитала VID, PID, прочитала серийный номер. Собственно вот сама плата — обычная stm32f3discovery, ничего необычного, я использовал только то что, есть в ней, я подключился по USB к USB девайсу, тут выход USB device. Подключился и написал там программу, назначил VID, PID и серийный номер, назначил обработчики конечных точек (у каждой конечной точки есть обработчики входа и выхода), и написал на компьютере программу, которая с этим всем общается. Вот эта программа: она уже подключилась, прочитала VID, PID и серийный номер. Точнее, VID, PID у меня были записаны в программе, она подключилась по этому адресу и прочитала номер, то есть она реально подключилась к девайсу. Есть кнопки: led ON и led OFF.

Давайте я тогда возьму камеру. Видно программку и видно девайс. Я нажимаю LED OFF — светодиоды погасли. Нажимаю LED ON — они включились. И параллельно здесь же у программы ещё обратная связь, она знает текущее состояние светодиодов, включены они или погашены. То есть здесь реально, настоящая передача по USB, и мне кажется этот пример хороший, он просто даёт старт. Точно так же вы можете написать обработчик эндпойнта, допустим, который будет посылать состояние АЦП, измеренное значение АЦП, прочитав его например с резистора, или точно так же на компе сделать крутилку, которая будет изменять ШИМ свечение светодиода на STM-ке. И кстати да, мой знакомый который нас сейчас смотрит, он делает управление шим мощным двигателем, точнее генератором, и программа для управления, то есть алгоритм, у него в матлабе. И именно так, я думаю, мы с ним сделаем передачу данных из матлаба в STM-ку и обратную связь.

(50:15) Вадим: Можно вас немножко прервать? А смысл, если есть некоторое приложение для матлаба, которое тебе позволяет…

Николай: да, которое делает прошивку прямо для STM. Но мне этот друг тоже говорил про это приложение, но ты знаешь — я скачал матлаб, открыл это приложение и в ужасе закрыл.

Вадим: я его скачал, открыл, даже что-то написал и было всё более-менее. При всём при этом я просто не понимаю, зачем тебе писать клиент на комп и общаться.

Николай: не знаю, может действительно сделать так, посмотрим. Но просто это один из вариантов решения, да. Это всё что я хотел сказать про USB, дальше у нас Тимур с таймерами.

Тимур Хасаншин, настройка таймеров в STM32

5

(51:15) Тимур: всем привет. Я буду рассматривать такую типичную ситуацию, когда нужно рассчитывать точный интервал времени через таймер в STM. В STM очень много таймеров, и у них очень много настроек, а я пока разберу просто как сделать раз в секунду, потому что это очень частая задача. (Открыл STM32Cube) У меня тут выбран кварц как источник тактирования, 8 МГц. Мы видим что внутри STM`ки очень развитая система тактирования — тут умножители, делители, тут PLL. Это STM32F407, у них похожи эти структуры. Справа расположены шины тактирования, видим шины специально для таймеров: APB1 и APB2, APB2 навороченный. У нас подводится 8 МГц кварц, эти делители мы можем изменять. Если вы не используете Cube, то их надо менять в файле system_stm32.

Нам понадобится калькулятор. Эта частота делится на 4, получается 2 МГц, умножается на 192, потом делится на 4, идёт сюда (SYSCLK), у нас получается 96. Тут делится на 1 (HCLK) и я в проекте буду использовать третий таймер (TIM3), он подключен к шине APB1. Получается, 96 делится на 4, а потом умножаем на 2, получается 48 МГц. Теперь мы знаем, с какой частотой тактируется наш таймер. Надо переходить в кейл. Я использую кейл как среду программирования. У меня тут программка накидана, сейчас у меня возможности продемонстрировать это на железе нет, потому что моя дискавери не приехала со мной. Здесь идёт стандартная инициализация таймера, нам нужны значения делителя и периода, они равны FFF и FFF.

Мы должны теперь сделать вот что: разделить частоту тактирования. FFF — это 16*16*16 = 4096 — 1, идёт прибавление единицы к этим значениям, поэтому если бы они были равны нулю — он бы просто ничего не разделил. 48000000/4096/4096=2.861 — значение в секундах с которым будет срабатывать прерывание. Как cделать из этого секунду — нужно пойти задом наперёд. У нас 1 секунда, мы умножаем её на 48 МГц, делим. Нужно менять предделитель либо период, допустим мы зададим период 4800, а период 10000, тогда при перемножении это сойдётся и мы получим срабатывание прерываний в 1 секунду.

Но период мигания будет 2 секунды, потому что у меня в прерывании сделано так, чтобы при в заходе в прерывание он изменял состояние светодиода на противоположное, поэтому одну секунду он будет гореть, а другую секунду будет не гореть, поэтому чтобы сделать период 1 секунду — нужно какое-то из этих значений уменьшить в два раза. В общем-то про таймеры я всё.

13

(59:04) Вадим: Можно вставку сделать? Мне недавно подсунули вот такую штуку (девайс с лампами ИВ-8), я думаю никого не смутит что здесь 103 камешек стоит внутри, я тоже столкнулся с этой проблемой. В итоге всё решилось гораздо проще: у него есть такая штука, как OSC_32: это клок. К сожалению, или к счастью, можно его запустить и без кварца. У него есть внутренний генератор, по-моему на 1 мегагерц ровно, с помощью которого вы можете прескейлером (по-моему 1000 я использовал) и просто взять чтобы он каждую секунду увеличивал значение одного из регистров BKP памяти на единицу.

Соответственно вы берёте, просто крутите какой-то цикл на дикой, сумасшедшей скорости и в нём вы просто ждёте, пока значение изменится на следующее, и соответственно под него вы всё и измеряете. Это получится значительно точнее и проще, почему — потому что. Я признаюсь, я криворук, я хреново развожу ТВЧ платы, но при всём при том у меня ошибка в тактировании (которая периодически возникает на прошаренных платах), у меня на дискавери ошибка тактирования составляет 1% на сто циклов, то есть раз в сто циклов она у меня гуляет по частоте на 1%.

Соответственно, выгоняя это внешним прерыванием от общего кварца, вы не погасите, у вас ошибка будет квадратично расти. А используя OSC_32, вы заюзаете, у вас ошибка будет по крайней мере линейной. То есть у вас часы будут убегать медленнее. К слову, это вообще интересный вопрос, когда я столкнулся с этой проблемой, я долго мучался — мне было непонятно, почему частота используется 32768. Потом мне один (?) рассказал, что это просто перемножение всех нужных частот для старых будильников. Если кто-то из подписчиков знает, почему — отпишите в комментариях, жутко интересно.

(1:01:45) Тимур: Я думаю, это не просто перемножение всех частот, потому что это как-никак степень двойки. В этом что-то есть.

Вадим: Возможно.

Тимур: Наверное, потому что у Int размер 32768, его можно тупо инкрементировать чтобы как раз укладывалось. Я так думаю.

Вадим: Ну возможно.

Тимур: Дальше по списку идёт Сергей.

Сергей Орлянский, измерение среднеквадратичного значения переменного тока

7

(01:02:20) Сергей: Меня слышно? Я хочу рассказать про измерение среднеквадратичного значения напряжения контроллером STM32. Собственно говоря я хочу это сделать на конкретном примере. У меня платка с контроллером. Тут стоит параллельный 14-разрядный АЦП еще немного обвязки сверху в него добавил и плата STM32 и контроллер 372-ой стоит. (Показывает плату) Сейчас переключусь на рабочий стол (на экране изображение) Для измерения в матлабе сначала промоделировал как именно будет все происходить, т.е. частота дискретизации у меня в данном случае была 1 кГц. Это половинчатая дискретизация, это значение. Линия показывает значение среднеквадратичное напряжения. А эти точки показывают отклонение. Т.е. мы видим, что у нас вблизи нуля будет серьезная ошибка. И видим, что у нас на половине частоты дискретизации и вблизи её полный провал. Мериться будет совершенно не точно (1:04:08) Чтобы избежать ошибки вблизи нуля я в данном проекте применил окно Хэмминга. Эта ошибка обусловлена тем, что когда мы меряем синусоиду у нас не попадает четное количество полупериодов и возникает эта ошибка Это как раз из-за совпадения с частотой Найквиста. (1:04:45)

СКЗ_график

Этого можно избежать Для этого можно изменить частоту дискретизации в процессе измерения и перейти на другой участок. Идеально она находилась посередине вот в этой точке (показывает Точку на графике в левой части графика) Тогда у нас будет идеальное значение (1:05:09) Если мы измеряем какое-то фиксированное напряжение с фиксированное частотой нам можно эти манипуляции: (1:05:24) рассчитать заранее фильтр низких частот и проблема будет решена. В данном случае я покажу код (показывает на экране часть кода) Изначально я сделал так, чтобы АЦП мерил значение из прерывания. Из этого у меня ничего хорошего не получилось. Потому, что чтобы перейти к прерыванию контроллер затрачивал примерно 700 наносекунд. Что очень долго и частота дискретизации получалась примерно 300 килосемплов в секунду, что очень мало. Поэтому после этого я сделал реализацию на DMA и желаемая 800кГц частота была получена.

Что у нас получается? У нас есть буфер, и мы измеряем вначале первую половину цикла и записываем значение в первую часть буфера. После этого мы работаем со второй частью буфера (показывает на экране часть кода) Вот как раз обработчики DMA (показывает на экране часть кода) Внутри них мы как раз и обрабатываем значения. Они периодически вызываются. Сначала один обработчик DMA обрабатывает первую половину значения. Потом вызывается второй обработчик DMA он делает тоже самое только со второй половиной значения. И у нас получается непрерывно идет преобразование. Формула, по которой считается, это обыкновенная формула среднеквадратичного значения (показывает статью из википедии).

СКЗ_плата

В процессе мы просто домножаем на окно Хэмминга, чтобы вблизи нуля убрать погрешность (1:07:48). Если не стоит глобальных задач, тут точность получилась достаточно хорошая: сотая процента. Это для диапазона частот до мегагерц там переключается значение. А если это не нужно, если частоты нужны слишком маленькие до килогерц, то более разумно использовать соответствующие микросхемы. У Analog Device есть достаточно хорошая микросхема которая эту сотую долю процента до килогерца нам дает. До 30 кГц там уже 1% погрешности. Вот в общем-то и все, что хотел рассказать – рассказал. (1:08:43)

Николай: Да отлично. Спасибо. Очень интересно. Теперь у нас Тимур.

Материалы: Исходный код

Тимур Хасаншин: указатели, шаблоны и ускорение работы

8

(1:08:55) Тимур: Да-да-да. Теперь я буду рассказывать про пустые указатели, по другому void указатели, потом как можно использовать (это наверно все знают) комбинации клавиш, или быстрые клавиши для того чтобы быстро инициализировать периферию вроде привязки АЦП нажал и все.

Так, первое: void указатели. Я сейчас покажу код. Видно? Что такое void указатели? Указатель это такое место памяти, в котором записан адрес другого места памяти. Фактически когда мы попадаем туда, потом перепрыгиваем на то место, которое там записано. Чем отличаются void указатели от других? Его можно связать с любой областью памяти и не известно пока к чему мы его применим. Вот здесь у меня сделана такая простенькая программа, где есть четыре функции, каждая из которых зажигает свой светодиод на Discovery четвертый. Т.е. красный, зеленый, синий и оранжевый. Функция их памяти имеет свою точку кода, которая находится по определенному адресу. И когда мы объявляем указатель, то мы можем помещать в него адреса начала этих функций. Я создал массив указателей, чтобы он содержал адреса всех этих функций. Я немного забыл. Заминка у меня вышла.
Николай: П, квадратные скобки номер и скобки круглые. Я думаю так.
Тимур: Да-да. Точно. Так я вызвал функцию зажигания красного светодиода. Чем это помогает? Допустим у меня есть какой-то цикл С меньше четырех (1:13:04)
Плюс. (Пишет на экране)

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

Есть один такой плюс, если мы объявим (Пишет на экране)
То разницы между этим и вот этим вообще никакой (1:15:10)
Это немного ненатурально выглядит. Да?
Николай: Да Я не знал такого.
Тимур: На самом деле это операция доступа к элементу массива. Она является сложением адреса начала массива и величины на которую нужно отступить от начала массива, чтобы попасть к нужному элементу. В данном случае нам нужно отступить 6 Int-ов.

11

Вадим: Это к теме первой рассказа, что нужно форматировать свой код и делать его максимально понятным

Николай: Я на это смотрю и не очень понимаю как это работает

Тимур: Идет сложение указателей. Я даже попробую скомпилировать

Вадим: И тут такой взрыв компа! (1:16:33) Общий смех.

Тимур: Ошибки нет.

Николай: Надо разобраться. Действительно прикольно!

Тимур: На самом деле я нашел один форум там очень много таких фишек. Но мне это просто запомнилось

Андрей: (1:17:01) Одну секунду. Тема не очень раскрыта поэтому после сообщения я немного подробнее об этом расскажу с позволения автора

Тимур: Да-да, конечно Сейчас?

Андрей: Нет. Сначала весь доклад пройдет. А потом я расскажу .

Тимур: Дальше я расскажу про одну удобную вещь, как снизить (1:17:39)

Николай: Да

Тимур: Если перейти сюда. Думаю в IAR тоже это есть. Я его как-то не использую. Мы можем очень легко вот это взять и скопировать, и создать Template.

Николай: Вообще не видно, что ты делаешь

Тимур: Там вылезло новое окно и поэтому? Да?

Николай: Да

Тимур: Ладно сейчас. Вот этого (лишнего) окна нет. Короче нужно открыть Templates

Голоса: Видно

Тимур: Они вместе не выделяются. Берем так просто и загоняем код. Видно?

Николай: Да

Тимур: Теперь просто, чтобы не писать вот это много раз. Вот так берем и пишем

(20:35:58) (пишет)

Николай: эта фишка только Keil`а?

Тимур: эта фишка Keil`а. И всех построенных на Eclipse 1:19:40

Николай: Понятно

Тимур: Насчет IAR`а не знаю.

Николай: В IAR`е нету.

Тимур: Тут еще можно поместить вот такой символ, вертикальная черта. Он будет являться местом куда встанет ваш курсор когда вы поместите его. Что у меня там дальше идет? Ну вот эту штуку я стараюсь часто использовать. Единственно у меня сейчас Keil установлен не на моем компьютере. Потому, что я сейчас в другом городе. И там все эти файлы получаются.

Их можно двойным кликом помещать. Это очень удобно.

Вадим: А не приводит ли это к ошибкам?

Тимур: К ошибкам? Смотря как использовать. Вот например в эти сниппеты не надо сохранять такие, для конкретного проекта какие-то настройки, а только общую инициализацию. Чтоб ты потом её заполнял. И еще там есть, что если ты выделил какое-то слово, а потом нажал на Snippet двойным кликом, то это слово подставится везде, где есть эта вертикальная черта. Т.е. ты можешь написать … Init, потом его выделил, нажал на Snippet и он поставит везде … Init. Получается, инициализация … Init . также можно сюда написав разрешение тактирования внутри. Насчет ошибок? Какие тут могут быть ошибки. Я вот просто смотрю. Просто мне многократное набирание одинакового кода надоедает.

Николай: Да. Согласен.

Тимур: Можно еще сделать про прерывание Snippet. Понятно?

Николай: Да, понятно. Отличная фича! Круто!

Тимур: Вот собственно все. Я могу еще немного порекламить Keil. Просто тут офигенский просто дебаггер, симулятор есть. И там есть даже некое подобие логического анализатора, котороеый позволяет отслеживать значение переменных в реальном времени. Нажал пока он еще не вышел. Поэтому мне нравится Keil. И в тех местах где я имел небольшой опыт работы там прямо мне говорили, что пересаживайся. Вот я и пересел.

Николай: Ну понятно. У меня, на моем месте работы юзали IAR изначально. И я пришел такой со знанием IAR. Так что видимо везде по-разному. Только я все равно люблю больше. Мне Keil кажется таким разноцветным :)

(Смех)

Тимур: Там туда добавили еще какой-то конструктор библиотек. Галочку поставил и оно уже там появилось.

Николай: Прикольно

Тимур: Я не очень использую, потому, что это немного подглючивает. И еще сейчас я, это наверно к теме не относится. Просто это важно и про это надо рассказать. Просто я испытывал от этого неудобство и два дня потратил работы. Давно это уже было. Есть такое значение как… Сейчас я найду его… Keil виден всем?

Николай: Да.

Тимур: HSE_STARTUP_TIMEOUT — это значение до которого считает в цикле Counter. Чтобы дождаться включения системы тактирования кварца. Когда я работал с отладочной платой, которая была у одной фирмы, они свою отладочную плату используют. У них была не то чтобы неправильная разводка. Наверно все-таки неправильная и из-за этого значение оказывалось слишком мало. Там была F103-я и там было значение 500.

Николай: Он на режим не выходил?

Тимур: Да. Он System_Init не запускал.

Николай: Понятно. Вот-вот-вот. Да у меня было такое.

Тимур: Я очень долго провозился. Думал, что такое? Я уже его вручную запускать начал. Не в ассемблере этом. Потом я понял, что нужно повысить это значение

Николай: Классно! Все? Андрей, ты собирался рассказать что-то. Прокомментировать.

Обсуждение

9

Андрей: Просто у меня часто связь отваливается. Поэтому могу внезапно прерваться. По поводу указателей. Это такая C-шная абстракция. На самом деле указатели это системозависимый тип. (1:25:48)

Например Windows если 32-битная система, то указатель это 32-битная int переменная.

если 64-битная система, и приложение скомпилировано как 64-битное, то указатель будет представляться как это 64-битная int целая. Что есть указатель? Это просто беззнаковое число которое показывает на какую-то ячейку памяти. В принципе, как показывает система указатель на функцию, или указатель на какую-то переменную, или

указатель на структуру. Это вообще одно и то же. Потому что они все хранят число, которое указывает на какую-то ячейку памяти. По сути это число. (1:26:25)

Поэтому void тип это канонический указатель. Это указатель, который не имеет типа. Это просто ссылка на какую-то ячейку памяти. Поэтому void указатель можно делать в хуке. Например у нас есть какая-то int переменная 32-битная. Она представляется как 4 байта.

И можно с помощью void указателя, и вообще с помощью преобразования представить эту int переменную представить как массив из четырех char`овских символов. Такая вот вещь. Но дело в том, что эта штука не очевидная. Во-первых C — слабо типизированный язык. У него типа есть ошибки при приведении типаб возникают, но в рамках этого void Такие грязные трюки которые крайне редко стоит применять. Кстати по поводу MISRA. Один из разделов очень рекомендует не применять в эмбеддерских случаях динамическое распределение пула, т.е. кучи. Не использовать malloc, calloc и прочее, чтобы все данные были у нас заранее жёстко заданы. Если у нас есть какой-то буфер, то чтобы этот буфер имел фиксированную длину, и не выделялся он изначально.

И второй момент по поводу очевидности. Да конечно можно сделать массив из указательной функции и вызывать потом в цикле просто индексируя их. Но это не очень хорошо. Во первых это усложняет понимание кода. во-вторых это может привести к неочевидным ошибкам. Если где-то ошибиться с итератором. Допустим у нас есть четыре функции. их определить в массив и дальше проходить. Ошибимся на один символ и у нас программа может скакануть в неадекватный участок кода. Это очень плохо и жрет нервы.
Николай: Андрей, извини. А на этот случай есть enum. В enum ты просто задаешь названия красивые и проходишь по ним. И там вряд ли ошибешься. Просто я думаю, что такая штука очень удобна. У меня на работе требуется работать разными способами в зависимости от чего-то. Типа одни и те же функции? но они по-разному работают и мне кажется очень круто. Отличная мысль так сделать!
Андрей: Как сказать можно во-первых эту штуку определить define`ами, это первое. Тогда оно будет макроподстановками подставляться в нужные функции. define`ами очень любят те же майкрософт если посмотреть на WinAPI там очень часто некоторые функции просто заводят через WinAPI, например ZeroMemory через define делается все это дело. Вводятся некоторые указатели не использовать. Где раельно это стоит использовать при передаче данных. Например тот же malloc и calloc который выделяет нам память они что делают? Они возвращают нам void указатель. Мы задаем количество байт, которое мы хотим увидеть и эта функция возвращает нам void указатель на этот участок памяти . А дальше мы уже сами приводим его к нужному типу и распределяем как нужно. Это еще может влиять при передаче данных по каким-то интерфейсам. Тот же USB или UART и так далее. Просто мы приводим к void указателю. Можно написать стандартную какую-то функцию которую принимает какой-то блок памяти и дальше с ним работаем. Но как на входе функции я не думаю, что это хорошая идея использовать.
Тимур: Во многих библиотеках как раз так и сделано.
Андрей: Просто в работе возникали случаи когда void указатели занимали немало времени на отладку. Т.е. в предыдущий программист что-то намутил с void указателями, комментариев не оставил, а другому программисту пришлось работать не один час отлавливая ошибки с этим связанные. Использовать можно, но очень осторожно.
Вадим: Разве позволяют оставлять память и захламлять память общими функциями? Все проекты котрые я вел они позволяли до 210 кБ памяти. Больше проектов я не видел. А при особенно больших проектах, когда используется большое количество человеческого ресурса в плане написания программы. Разве функционал не пишется разово для одного устройства, а пишется он какими-то порциями по временным сдачам или что-то вроде этого.
Андрей: Как сказать? Если у нас есть какие-то задачи, то мы их разбиваем на подзадачи. Например один человек может заниматься проектированием передачи данных по интерфейсам, другой человек может заниматься обработки данных и тому подобное. Это будет использоваться на одном и том же кристалле. Это пишут два разных человека. Это уже другие дела. Именно что. Во-первых не было рассказано как подставляются указатели памяти. Это важный момент. Мне допустим было не понятно. А второй момент, что void указатели, бывает, приводят к неочевидному поведению программ. Это особенно касается приведению типов. Если мы передаем какие-то данные из одного блока памяти (программы) в другой блок, то void нужен только в тех задачах где нас вообще не важен тип. Например передача по интерфейсу UART. У нас есть программа в которой вы сформировали какую-то структуру. Чтобы не заморачиваться с написанием функции под конкретную структуру то принимает указатель типа void и количество байт. И таким образом мы передаем указатель на функцию указатель на структуру и size of этой структуры. (1:32:14)
В коде применяют. В принципе в данном случае void позволяет сократить ресурсы. В том числе человеческие. Я наверно в комментариях к Youtube напишу пример такой C-шный.

Николай: Да, отлично, спасибо. Обязательно напиши. Действительно это интересно. И у меня только один наверно последний вопрос к Сергею. Девайс реально очень классный! Мне вообще прями очень.. Я вообще увидел реально… У меня прямо челюсть отвисла! Это классно! А что собственно этот девайс делает? В смысле где он берет эти данные? Ток, напряжение? Это измерение чего-то конкретного? (1:33:13)

Сергей: Вообще дома я не применяю эту штуку. Генератор на работе и напряжение стоят строчные калибраторы . Наши компании уральские их выпускают. Это вообще будет использоваться в мультиметре

Николай: Ага! Значит это будет большой крутой девайс!
Сергей: Да. Измерительный
Николай: Генератор и измеритель и еще что-то?

Сергей: Это будет мультиметр. Я брал оттуда значения.
Николай: Все понятно. Я думаю, что я напишу тебе. Потому, что это вообще!! Бли-и-нн!! Реально очень классная тема. Я очень люблю цифровую обработку сигналов. Это круто! Все пожалуй. Рассказали все, что собирались.

Андрей: есть вопрос.

Николай: Да-да.

Андрей: Вопрос к Вадиму по поводу UART. (1:34:23)

Он сказал, что аудиоджек можно использовать. В принципе да, с этим я согласен. Это удобно. Но в промышленности DB9.

Вадим: Это не можно использовать, т.к. это реальный промышленный стандарт в плане того, что есть куча плат. Например, есть известный однокристальный компьютер Intel Galileo. Где впервые я обратил на это внимание, что там стоит CP2102, подключенная к основному ЦП и дальше она выведена на аудиоджек и написан UART. Я начал рыть эту тему — оказалось, да, действительно, сервис инженеры в развитых платах никогда не делают прямо на плате переходник USB – UART: обычно они его выносят, а в качестве проводов и коннекторов используют джеки 3.5. Когда провод смотришь, то там два кабеля и экранирование, там наводки меньше получаются. Это ГОСТовская стандартная деталь.

Сергей: В сетевом оборудовании очень часто это используется.

Вадим: Серьезно?

Сергей: Да.

Андрей: Я имею в виду что часто используется порт DB9, просто потому что есть ещё в RS-232 стандарте линии CTS, DTS прерывания. Или я ошибаюсь?

Вадим: Стандартные линии прерывания по началу и концу передачи.

Андрей: Да если они нужны, то используется DB9. Городить лишнее не стоит. Может кто-то слышал? Может я что-то путаю.

Вадим: DB9 это в старых компах. Такой разъем, он синий обычно. В него втыкается большая металлическая блямба. Там как раз линии UART. У неё ограничение по длине есть. У меня друг такую штуку городил. У него была реально вилка DB9-ая. по-моему. И он говорил, что это нужно было пустить по цеху. И у него рядом стоял электродвигатель, который его линии UART превращал в дикий хлам. В итоге он использовал 232-ю микросхему, повысил линии до ±12В. Слал по линиям ±12 вольт и тогда у него получилось все хорошо.

Андрей: Ну да. Это есть. Ограничение на КОМ-порт обычно 5-и вольтовое комповое по-моему до одного метра использовать.

Вадим: Да, там жесткие ограничения.

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

Вадим: Это нужно смотреть по месту применения. Просто 232-ой проще для народа, есть куча статей по его описанию. По 485-ой я смотрел в русском сегменте есть три статья всего. Люди его использовали, и он значительно лучше по шумам и значительно удобнее по сравнению с HIDом. В настройке.

Николай: А еще лучше CAN.

Вадим: Да. CAN это просто шикарная штука. CAN это автомобильный стандарт. Он в автомобилях используется, где куча помех.

Андрей: CAN чем удобен, что в старших контроллерах 4-ая серия точно есть.

Николай: В первой есть, во второй.

Вадим: Тему которую не раскрыли про фриланс. В области фриланса у меня постоянно получается, что нужно заюзать какое-нибудь 2-3 порта с выходом ШИМ и связать это дело с компом. Чтоб на компе был простой ШИМ генератор, который регулировал бы вам три канала горения светодиодов и это все дело управлялось. Это вообще не проблема. И ты туда не будешь впихивать 427 чип , возьмешь что-то попроще. Например 30-ый в лучшем случае и запихнешь в . Я долго думал AVR-ку или все-таки 030-ый. Но моя любовь уверила меня в 030-ом, и я их впихиваю куда могу. Да, в старших чипах есть и его лучше юзать, чем UART. Если у вас длинные дистанции. Я ответил на вопрос?

Андрей: Да.

Вадим: Хорошо.

Николай: Я думаю на этом можно закончить. Мы не рассмотрели конечно последнюю тему про фриланс электронный. Но уже просто много времени прошло. Всем спасибо! Все было действительно очень круто Просто офигенно! Я очень рад, что так все вышло. Все коды, статьи, ссылки, все, что захочется приложить дополнительно к рассказу можно будет выложить в комментариях на Youtube или в группе Вконтакте или где-то еще. Потому, что я выложу код для USB-HID и программу для контроллера и для компа. Думаю, что кто-то еще захочет. Андрей собирался выложить тоже что-то. Я думаю, что на этом можно заканчивать.

Андрей: Да. Спасибо за внимание всем. Я потом выложу и Николаю в комментах напишу. Наверно Вконтакте чтобы приложить видео.

Николай: Да, конечно. Я все выложу, все, что скинете. Я потом, возможно, сделаю статью, где будет небольшой дайджест этой встречи, видео и все материалы приложенные. В одном месте чтобы все можно было все посмотреть и скачать. Чтобы удобно было. Пожалуй все. Всем спасибо! До свидания!

10