Двухканальный usb осциллограф на stm32 – miniscope v2c

Двухканальный usb осциллограф на stm32 – miniscope v2c

Дельта принтеры крайне требовательны к точности изготовления комплектующих (геометрия рамы, длины диагоналей, люфтам соединения диагоналей, эффектора и кареток) и всей геометрии принтера. Так же, если концевые выключатели (EndStop) расположены на разной высоте (или разный момент срабатывания в случае контактных концевиков), то высота по каждой из осей оказывается разная и мы получаем наклонную плоскость не совпадающая с плоскостью рабочего столика(стекла). Данные неточности могут быть исправлены либо механически (путем регулировки концевых выключателей по высоте), либо программно. Мы используем программный способ калибровки.
Далее будут рассмотрены основные настройки дельта принтера.
Для управления и настройки принтера мы используем программу Pronterface.
Калибровка принтера делится на три этапа:

1 Этап. Корректируем плоскость по трем точкам

Выставление в одну плоскость трех точек — A, B, C (расположенных рядом с тремя направляющими). По сути необходимо уточнить высоту от плоскости до концевых выключателей для каждой из осей.
Большинство (если не все) платы для управления трехмерным принтером (В нашем случае RAMPS 1.4) работают в декартовой системе координат, другими словами есть привод на оси: X, Y, Z.
В дельта принтере необходимо перейти от декартовых координат к полярным. Поэтому условимся, что подключенные к двигателям X, Y, Z соответствует осям A, B, C.(Против часовой стрелки начиная с любого двигателя, в нашем случае смотря на логотип слева — X-A, справа Y-B, дальний Z-C) Далее при слайсинге, печати и управлении принтером в ручном режиме, мы будем оперировать классической декартовой системой координат, электроника принтера сама будет пересчитывать данные в нужную ей систему. Это условность нам необходима для понятия принципа работы и непосредственной калибровки принтера.

  • Обнуляем высоты осей X, Y, Z командой M666 x0 y0 z0.
    И сохраняем изменения командой M500. После каждого изменения настроек необходимо нажать home (или команда g28), для того что бы принтер знал откуда брать отсчет.
  • Калибровка принтера производится “на горячую”, то есть должен быть включен подогрев стола (если имеется) и нагрев печатающей головки (HotEnd’а) (Стол 60град., сопло 185 град.) Так же нам понадобится щуп, желательно металлический, известных размеров. Для этих задач вполне подойдет шестигранный ключ (самый большой, в нашем случае 8мм, он предоставляется в комплекте с принтерами Prizm Pro и Prizm Mini)
  • Опускаем печатающую головку на высоту (условно) 9мм (от стола, так, что бы сопло еле касалось нашего щупа, т.к. высота пока что не точно выставлена.) Команда: G1 Z9.
  • Теперь приступаем непосредственно к настройке наших трех точек.
    Для удобства можно вместо g- команд создать в Pronterface четыре кнопки, для перемещения печатающей головки в точки A, B, C, 0-ноль.

  • Последовательно перемещаясь между тремя точками (созданными ранее кнопками или командами) выясняем какая из них находится ниже всего (визуально) и принимает эту ось за нулевую, относительно нее мы будем менять высоту остальных двух точек.
  • Предположим, что точка A у нас ниже остальных. Перемещаем головку в точку B(Y) и клавишами управления высотой в Pronterface опускаем сопло до касания с нашим щупом, считая величину, на которую мы опустили сопло (в лоб считаем количество нажатий на кнопки +1 и +0.1)
    Далее командой меняем параметры высоты оси Y: M666 Y <посчитанная величина>
    M666 Y0.75
    M500
    G28
  • Ту же операцию проделываем с оставшимися осями. После чего следует опять проверить высоту всех точек, может получится, что разброс высот после первой калибровки уменьшится, но высота все равно будет отличатся, при этом самая низкая точка может изменится. В этом случае повторяем пункты 6-7.
  • 2 Этап. Исправляем линзу

    После того как мы выставили три точки в одну плоскость необходимо произвести коррекцию высоты центральной точки. Из за особенности механики дельты при перемещении печатающей головки между крайними точками в центре она может пройти либо ниже либо выше нашей плоскости, тем самым мы получаем не плоскость а линзу, либо вогнутую либо выпуклую.
    Внешняя USB звуковая карта US $1.03 http://ali.pub/35d2rl

    Проектов по созданию осциллографов из разного рода аудиокарт немало. Выполнить модификацию карты с тем, чтобы превратить ее в полезный для электронщика инструмент, не так сложно, но зачастую встает вопрос цены. И здесь приходит на помощь интересный вариант с ценой вопроса около 1 доллара США.

    Именно столько стоит внешняя звуковая карта, которая изображена на анонсной фотографии. Купить это чудо техники можно на электронной барахолке (во многих городах такие есть), или же на интернет-аукционе, где всегда есть, из чего выбрать. Маркировка текущего девайса — HX2010-0705, выпущен он в конце 2013 года.

    Устройство является гибридным, это звуковая карта + HID input. Что касается последнего, то эта часть предназначена для регулировки громкости и выполнения некоторых других задач, включая работу с медиаклавиатурой.

    Дамп USB дескриптора:

    V > Product string: C-Media USB Headphone Set
    Audio Device Class + HID (composite device)

    Судя по всему, чип внутри аналогичен чипу, установленному в недорогих звуковых картах «C-Media», без каких-либо кнопок.

    Читайте также:  Обзор плк фирмы siemens

    Примечания:

    • аудиовход — моно, и два контакта не должны вводить в заблуждение, они замкнуты друг на друга; DLL здесь общий, может работать как со стерео-картами, так и с моно. Второй канал можно отключить самостоятельно.

    • Частота дискретизации — 44100 и 48000 Гц;
    • 2,23 В на С6; ток короткого замыкания 20 мА, при добавлении резистора на 120к этот показатель можно снизить до 8 мА;
    • Резистор на 120к является наиболее недорогим методом увеличения диапазона измерения до 0-6В;
    • AGC нужно убрать, настройки должны быть следующими:

    Конденсатор C6 нужно отпаять, его емкость составляет 80 нФ, и он может серьезно ограничить возможности нашего осциллографа.

    Настройки:

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

    Взято с сайта: https://geektimes.ru/post/265280/

    2 Часть

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

    Сразу оговорюсь, что данный девайс не сможет работать с постоянными напряжениями, но увидеть, например, появился ли ШИМ на ножках вполне реально. Схема до безобразия проста:

    STM Урок 27. HAL. DAC

    Урок 27

    HAL. DAC

    Сегодня мы начнём изучать интересную технологию – цифро-аналоговый преобразователь (ЦАП) или по-английски Digital-to-analog converter (DAC).

    Как видно из названия данного преобразователя, он занимается преобразованием цифрового кода или величины в напряжение определённой величины, каким-то образом зависящим от данного цифрового кода. И также из названия видно, что цифро-аналговый преобразователь занимается задачей, обратной той, которой занимается аналого-цифровой преобразователь (АЦП), который мы уже изучили, начиная с урока 16.

    Вообщем, слишком подробно мы не будем изучать принцип работы цифро-аналогового преобразователя. Нам важно научиться с ним работать с использованием контроллера STM32.

    Во-первых, откроем Reference Manual и посмотрим, какой шиной управляется данная периферия

    Как мы видим – это шина APB1.

    Также в этой же документации посмотрим краткие характеристики нашего ЦАП

    ЦАП наш является 12-битным.

    Мы видим, что существует два таких ЦАПа, но также здесь находится ремарка, что не очень радостно, что на каждый такой конвертер находится только одна ножка контроллера и переопределить её невозможно.

    Также можно выровнять данные по правому или левому краю двухбайтного регистра DHRx. То есть в зависимости от определённых настроек мы назначаем, каким образом мы будем располагать данные в этом регистре для последующего преобразования в электрический сигнал.

    Также существует возможность синхронного обновления, генерации шума, треугольных импульсов, раздельного преобразования по каналам, а также совместного их использования, использования DMA для каждого канала, обнаружения ошибок опустошения DMA, использования внешнего управления преобразованием с помощью триггеров и использования опорного напряжения.

    Существует также структурная схема ЦАП

    На данной схеме видно, что существует ряд таймеров, которыми мы можем воспользоваться в качестве триггеров. Есть у нас управляющий регистр, биты которого служат для определённых настроек, регистр данных DHRx, ну, верней их два – DHR1 и DHR2, которые мы используем для хранения значения, которое будет преобразовано в электрический сигнал, а номера соответствуют номерам ЦАПов. Ну, и непросредственно, сам преобразователь.

    А вот здесь указано, какие существуют режимы для преобразования

    Мы видим, что существует также 8-битный режим и два варианта 12-битного режима в зависимости от выравнивания преобразуемой величины. Данные регистры мы в коде непосредственно использовать не будем, мы разве что к ним обратимся в процессе отладки, если у нас что не заработает.

    Ну давайте наконец займёмся кодом.

    Проект создаём из проекта TEST001, т.к. там ничего лишнего не подключено. Назовем его DAC. Запустим проект в Cube, включим там DAC OUT1

    В Clock Configuration внесем следующие настройки

    В самом DAC настройки следующие

    Больше ничего не включаем.

    Генерируем и запускаем проект. Соберем код, настроим программатор на авторезет и начнем писать.

    Запустим ЦАП, найдя функцию в документации HAL User Manual на странице 215

    /* USER CODE BEGIN 2 */

    /* USER CODE END 2 */

    Попробуем затем занести в ЦАП какое-нибудь значение.

    Значение, которое неоходимо занести в периферию ЦАП, рассчитывается по следующей формуле

    Ну вернее эту формулу необходимо перевернуть, выразив из неё DOR. Это и будет значение, которое мы используем в функции.

    Вообщем, например, нам необходимо сгенерировать напряжение на выходе ЦАП значением 1 вольт. Перевернув вышеуказанную формулу, мы должны 1 вольт разделить на опорное напряжение или на 3 и затем умножить на 4095. Получим мы 1365.

    Давайте так и поступим.

    Прежде чем прошивать контроллера, посмотрим, как мы всё подключили

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

    Соберем, прошьем и померяем напряжение на ножке PA4

    Напряжение у нас вполне соответствует заявленному с очень малой погрешностью.

    Напишем следующий код в бесконечный цикл, который будем постепенно то наращивать напряжение на выходе

    Двухканальный usb осциллограф на stm32 – miniscope v2c

    Собрал, проверил, оценил. Выношу на суд общественности.
    Проект не мой! Мой вклад минимален. Оригинал/разработчики – https://www.scopefun.com
    Весь проект под “CERN Open Hardware Licence ( CERN OHL ) “. Все материалы лежат в откроытом доступе и доступны для модификаций.

    Прекрасный проект для радиолюбителей среднего уровня. Для тех, кого китайские самоделки уже не устраивают, а на Rigol денег нет.
    Обычно нужны:
    1) 2-х канальный осциллограф. АЦП на 100МГц, если выше – начинает сильно расти цена и возникают технические проблеммы.
    2) Логический пробник. Без него с цифрой не разобраться.
    3) Генератор.

    И если все объединить – будет ScopeFun ! Его можно собрать самому. Все можно спаять паяльником ( у меня самоделка на жалах Т12) и феном ( у меня 8858 ) . Никаких BGA.

    Количеество каналов: 2
    Sampling rate, max.: 100 Msps Real-Time / 3.2 Gsps with Equivalent-Time Sampling ( ETS )
    Sampling rate, min.: 1 sps
    Разрешение: 10 бит
    Размер памяти: 10.000 выбороки на канал
    Диапазон напряжения: 10 mV/деление – 2 V/деление ( для 1× щупа ); 100 mV/деление – 20 V/деление ( для 10× probe )
    Смещение сигнала: регулируется ( +/- 100 % )
    Режим входа: DC, AC, GND
    Параметры входа: 1 MΩ || 12 pF
    Защита входа: +/- 50 V ( долговремено )
    LED индикатор триггера

    Количество каналов: 2
    Скорость выборки: 50 Msps
    Разрешение: 12 bit
    Выходное сопротивление: 50 Ω
    Доступные сигналы: Sin, Cos, Tреугольник, Меандр, Ramp up/down, Дельта, DC, Шум, пользовательский
    Размер памяти для пользовательского сигнала: 4.096 отчетов на канал
    Максимальное выходное напряжение: +/- 2,0 V
    Смещение и уровень сигнала настраиваемый
    Защита от перегрузки: +/- 50 V ( долговремено )
    Защита от короткого замыкания

    Логический анализатор / генератор логических сигналов

    Количество каналов: 16 ( логический анализатор / генератор логических сигналов: 8-вход / 8-выход; 16-вход; 16-выход )
    Скорость работы: max. 100 Msps
    Напряжение интерфейса: настраивается в диапазоне 1,25 V – 3,3 V всего 256 шагов
    Размер памяти: 10.000 отчетов на канал
    Входное сопротивление ( Логический анализатор ): 200 kΩ
    Выходное сопротивление ( генератор логических сигналов ): 1 kΩ
    Защита от перегрузки: +/-5 V ( долговременно ); +/- 20V ( кратковременно

    15 s )
    Размер памяти генератора логических сигналов: 4.096 отчетов на канал
    Делитель частоты генератора логических сигналов: настраиваемый 32-bit ( 100 Mhz – 0,023 Hz )

    Источник: Аналоговый канал 1, Аналоговый канал 2, цифровые каналы ( внешний запуск), Генератор канал 1, Генератор канал 2
    Режим: Auto, Normal, Single ( with Re-Arm )
    Pre-Trigger: настраиваемый 0 – 100 %
    Уровень триггера: 0 – 100 %
    Гистерезис уровня срабатывания: настраивается
    Задержка срабатывания: настраиваемая 0 – 4,2 сек. ( 10 ns размер шага )
    Цифровой триггер: 4 стадии ( настраиваемая задержка каждой стадии )
    Цифровой триггер: маска на выбранных каналах ( логический уровень: ‘0’, ‘1’, ‘фронт’, ‘спад’ )

    Читайте также:  Двухканальный 16-разрядный, 1.6-гсмпл/с, цап синтезирует высококачественные широкополосные сигналы

    Что сам сделал:
    1) Отрисовал проект на https://circuitmaker.com/Projects/De. gey/MyScopeFun
    2) Изменил схему тактирования АЦП. И еще по мелочи.
    3) Небольшие изменения в печатной платы для более доступных компонентов.

    Заказал плату в Китае. Купил комплектующие. Собрал.

    Личное мнение.
    Плюсы:
    1) Работает. Хорошо работает. Хорошая вещь для домашней лаборатории.
    2) Очень низкий уровень шумов аналогового канала. Если конечно не лезть пальцами в входной высокоомный делитель.
    3) Защита входов/выходов реально работает. Шансы случайно спалить реально будут меньше. Например сунув выход генератора “не туда”.
    4) Возможность выгрузить отчеты в текстовой файл для последующей обработки.
    5) 16 цифровых входов на частоте 100 Msps – это очень шикарно.
    6) Простая возможность локализовать софт.
    Минусы:
    1) Софт нуждается в “допиливании”. Я уже этим занимаюсь.
    2) Калибровка . странная. Есть режим “автокалибровка”. По встроенному генератору. Который по напряжению тоже подвирает. В моем “допиленном” софте это будет решено.
    3) Авторы походу охладели к этому варианту. Сейчас пилят вариант с USB 3.0, 250 Msps dual ch. (500 MSps single ch.). И предполагаемой ценой 750 евро. Я пас .

    Фотки выложу чуть позже. На все вопросы готов ответить. Если нужно – помогу с советами и рекомендациями по работам и компонентам.

    История одного осциллографа на stm32

    Чуть больше года назад, мне в голову пришла мысль о том, что хорошо бы было сделать осциллограф. Тогда мне хотелось, чтобы это было независимое устройство с собственным TFT дисплеем, да и вообще, идея разобраться с TFT дисплеями, мне казалась очень перспективной. Спустя некоторое время на али был заказан TFT размером 3.2 дюйма с драйвером SSD1289.

    На тот момент у меня уже был опыт программирования микроконтроллеров AVR, поэтому решил запустить дисплей на моём любимом Atmega16. Дойдёт ли дело до создания осциллографа тогда ещё не знал, но то что буду в своих проектах использовать TFT знал точно, поэтому не стал искать сторонние библиотеки, а решил написать свою, которой пользуюсь и по сей день.

    После того, как получилось инициализировать дисплей, стало понятно, что на Atmega16 сделать осциллограф не получится. Уж очень медленный он для дисплея такого размера. И что-то внутри подсказывало мне, что пора переходить на STM32, но оно же и останавливало меня. В общем, процесс обдумывания был недолгим и на али была заказана плата с STM32F103VET6 на борту. Но кроме причины описанной выше, была ещё одна причина перейти на STM32 – встроенный 12 битный АЦП на 1Msps, который можно использовать для оцифровки сигнала.

    К моему удивлению, после нескольких недель работы с STM32 стало понятно, что в них нет ничего сложного и я перестал понимать, почему не перешёл на них раньше. Перенести код, написанный для AVR, на STM32, не составило труда, но не давала покоя мысль о том, что мне необходимо, чтобы дисплей работал на максимальной скорости, а для этого надо было разобраться с FSMC. На самом деле и тут оказалось всё просто — это заняло у меня одни выходные. На этом подготовительные мероприятия с дисплеем были закончены и можно было переходить непосредственно к реализации осциллографа.

    Первоочередной задачей было научиться выводить сигнал на дисплей, для этого накапливал необходимое количество выборок АЦП, затем выводил их на экран, заливал экран чёрным цветом и так по кругу. Кстати, уже тогда для сохранения данных в буфер использовал DMA.

    Первый шаг был сделан и меня переполняла радость и гордость за проделанную работу. Далее, хотелось, чтобы синусоида не бежала, а стояла, для этого надо было научиться запускать преобразование АЦП по триггеру.
    Сделать это можно с помощью обычного компаратора, как показано на схеме ниже.

    Компаратор на ОУ.

    На инвертирующий вход подаётся опорное напряжение, которое формируется с помощью ШИМ и RC цепочки. А на прямой вход подаётся сигнал, тот же что подаётся на вход АЦП.

    Когда напряжение на прямом входе становится выше или ниже напряжения на инверсном входе изменяется полярность на выходе ОУ. Это изменение фиксирует вывод МК настроенный на внешнее прерывание. Изменяя активный фронт, для внешнего прерывания можно производить захват как по возрастающему, так и по спадающему фронту.

    Далее, в прерывании включается DMA и работает до тех, пор пока буфер не заполнится. Да именно DMA, АЦП в моей реализации работает всегда. Резистор в обратной связи необходим для увеличения скорости нарастания, да и сам ОУ для этого дела, желательно выбрать побыстрее.

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

    Фрагмент схемы DSO 138.

    Что делает этот кусочек схемы?
    Диапазон напряжений, с которыми может работать АЦП определяют уровни опорных напряжений(+VREF и -VREF), они не должны выходить за диапазон питания микроконтроллера. Нижнюю границу диапазона ограничивает 0 вольт, верхнюю — 3.3 вольта. Отсюда становится понятно что измерять отрицательные напряжения АЦП не может, а это необходимо.

    Для того чтобы АЦП чувствовало отрицательные напряжения необходимо, чтобы в отсутствие сигнала на его вход подавалась половина опорного напряжения в нашем случае 1.6 вольта. В таком случаем при измерении отрицательного напряжения, например, минус 0,3 вольта, напряжение на входе АЦП уменьшится на 0,3 вольта и станет равно 1,6 — 0,3 = 1,3 вольта. Такое напряжение АЦП с лёгкостью оцифрует. Этот пример приблизителен потому, что не учитывает коэффициент усиления схемы(в данном случае мы приняли его за 1), зато нагляден.

    Также хотелось обратить внимание, что питание ОУ двухполярное, это надо для того чтобы ОУ мог работать с отрицательным напряжением. В случае если питание ОУ однополярное(на один вывод питания подаётся 0, на второй 5 вольт)и на вход ему подать отрицательное напряжение, ОУ просто его не почувствует и сделать с ним ничего не сможет, вот так вот.

    Для реализации двухполярного питания использовал две зарядки от телефона, соединив плюс одной с минусом другой, и принял потенциал этого соединения за точку отсчёта, то есть землю.

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

    На тот момент времени у меня уже было чёткое понимание, что буфер должен быть кольцевой, а размер позаимствовал у DSO 138, то есть 4096 точек.

    Для чего столько точек?
    Такое количество точек, с помощью прореживания позволяет реализовать некоторые развёртки, которые нельзя реализовать аппаратно. У STM32 длительность преобразования составляет 12.5 цикла, для того чтобы найти период выборок надо к длительности преобразования прибавить значение, которое определяется битовым полем SMPx[2:0]. На данный момент у DSO 138 уменьшили размер буфера до 1024 точек, у меня же осталось 4096.

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

    1. накапливаем нужное количество предвыборок;
    2. разрешаем внешние прерывания;
    3. МК начинает выполнение каких-то сторонних задач, до тех пор, пока не придёт сигнал внешнего прерывания.
    Читайте также:  Программатор для перепрограммирования чипов принтеров

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

    Результат можно посмотреть на видео.

    Что мог прототип осциллографа на тот момент?(а что он что-то мог?)
    Можно было изменять время развёртки, выбрать тип триггера, выбрать активный фронт, изменять количество пред и пост выборок, изменять уровень триггера, также изменять базовый уровень.
    Что касается типа триггера, в режиме авто, всё происходит также как в режиме норм за исключением того, что если в течение 100 миллисекунд не приходит сигнал, вызывающий внешнее прерывание, то происходит прерывание по таймеру и в нём заполняется буфер.

    Для того чтобы реализовать остальные функции пришлось снова вернуться к железу. И думаю у многих возник вопрос, почему не заюзать всю схему от DSO138?
    Всё просто, хотелось чтобы положение аттенюатора переключалось электроникой, а не переключателями и, главное, чтобы при смене открытого входа на закрытый и наоборот щёлкало реле))
    В общем, передо мной стояла задача, найти аналоговую часть, которая бы соответствовала моим требованиям. На самом деле это задача непростая, если бы не одно но…
    В один прекрасный момент я вспомнил, что у меня есть осциллограф, а его разработчик около года назад отвечал мне на вопросы по его использованию в skype, в общем, решил ему написать.
    После того как рассказал ему о своих планах сделать осциллограф он предложил мне несколько вариантов аналоговой части, я выбрал наиболее мне понятную схему, задал ему имеющиеся у меня вопросы и принялся за реализацию. Через несколько месяцев осциллограф был готов.

    В итоге получилось сделать осциллограф обладающий следующими характеристиками:
    Напряжение питания: 9 В
    Потребляемый ток: 110 мА
    Частота сэмплирования: 1 Мвыб/с
    Аналоговая полоса пропускания: 0 — 200 КГц
    Разрешение по вертикали: 12 бит
    Максимальное входное напряжение: 50 В
    Чувствительность по вертикали: 10 мВ/дел — 10 В/дел
    Время горизонтальной развертки: 10 мкс/дел до 200 мс/дел
    Входной импеданс: 1 МОм/20пФ
    Режимы входа: DC, AC, земля
    Режимы запуска — развертки: авто, нормальный, однократный

    Результат можно посмотреть на видео.

    STM32F103C8T6 — делаем осциллограф. Часть 3 12.07.2016 19:37

    Аналоговая чать

    Почти всё как было описано во второй части, кроме источника двухполярного питания. ОУ потребляют значительный ток (порядка 10 мА) и как не пытался схемами умножителей напряжения на диодах и конденсаторах получить приемлемых результатов — не удалось. Поэтому для положительного напряжения поставил вот такой модуль на основе МТ3608:

    настроенный на 10 В выходного напряжения. А отрицательное напряжение получаю путём инвертирования положительного с помощью LT1054.

    Про размер кода

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

    CooCox CoIDE выводит информацию о размер программы в таком виде:

    • text — размер сегмента с кодом, векторами прерываний и константами только на чтение;
    • data — размер сегмента с инициализированными не нулём переменными;
    • bss — размер сегмента с неинициализированными и инициализированными нулём переменными.

    Вся программа занимает:

    • флеш — text + data + 10…50 байт
    • ОЗУ — data + bss + 10…50 байт

    Теперь посмотрим на что тратится память. Делаем новый проект и компилируем:

    Чтобы использовать макросы типа GPIO_BSRR_BS9 надо подключить файл stm32f10x.h.
    Чтобы подключить файл stm32f10x.h надо в репозитоях добавить компонент STM32F10x_MD_STDLIB, который подтягивает за собой cmsis_core. В итоге для программы, записывающей одно значение в регистр получаем:

    Далее меня интересуют функции типа sprintf и sscanf. Чтобы их использовать надо определить некоторые функции типа _sbrk и возможно некоторых других. Я взял готовый файл (есть в архиве с проектом). Добавляем 1 вызов sscanf и получаем:

    Режимы работы

    Реализовал 3 режима по принципу действия: непрерывный, пакетный и логический и 3 по количеству каналов: 1, 2 и 4-х канальный.
    МК имеет 9 аналоговых входов, но я не представляю когда мне может понадобиться больше 4-х каналов.

    Непрерывный

    Тут всё просто: в главном цикле МК считываем данные АЦП и передаём их на ПК, где можем строить непрерывный график. Недостаток — ограничение скорости со стороны канала МК → ПК. Чтобы его обойти реализовал ещё 2 режима.

    Пакетный

    В этом режиме МК вначале набирает данные, потом пачкой передаёт на ПК. Опционально его можно разгонять. Про разгон подробно писал в предыдущих частях.

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

    В отличие от проекта baghear у меня триггер программный. Преимущества такого решения:

    • Меньше деталей, а значит меньше цена и проще монтаж;
    • Возможность в будущем реализовать более сложные триггеры, а не просто «сигнал в A канале стал больше Х».

    В одноканальном режиме оба АЦП по очереди преобразуют значение одного канала.
    В двухканальном — каждый АЦП преобразует свой канал запускаясь одновременно с другим.
    В 4-х канальном — у каждого АЦП есть 2 канала, которые он преобразует. Старт обоих АЦП одновременный.
    Очевидно, что скорость частота преобразования канала обратнопропорциональна количеству каналов.

    Логический анализатор

    Самый быстрый режим. Примерно 20 MSPS на каждом канале. Самый быстрый код для этого режима выглядит так:

    и так далее на весь буфер.
    Значение переменной i в этом случае вычисляются на этапе компиляции и в итоге из dataBuffer.u8[++i] = GPIOA→IDR; получается всего 2 операции — загрузить данные в регистр из порта и сохранить данные в память по заранее посчитанному адресу. Никакими циклами такой производительности достичь не получилось.

    Программа для ПК

    Главные, на мой взгляд, измение — переход на OpenGL. С ним графики рисовать стало проще (для меня это оказалось неожиданно, но там всё действительно просто и кратко!), рисуются они быстрее и получаются гораздо красивей, чем были раньше.

    Проект не завершён, есть глюки, допиливать ещё много чего, но каких-то прорывов уже не предвидится. Для более быстрых систем нужно другое железо, например, отдельный АЦП + ПЛИС + память —, а это уже будет гораздо дороже и сложнее монтировать.

    Почитав комментарии к статье «История одного осциллографа на stm32» сразу отвечу на некоторые вопросы:

    • Дисплей прикручивать не собираюсь т.к.:
      • Он стоит денег, а комп есть.
      • По качеству будет хуже, чем на большом экране ПК.
      • Создавать и изменять пользовательский интерфейс на C# проще, чем паять и перепаивать.

    • Я не планирую его доводить коммерческого продукта и продавать.
    • Делал для 2-х целей: освоить МК и сделать себе цифровой осциллограф.

    Архив с проектом
    Если у кого появятся вопросы, а тут не зарегистрированы, пишите в почту: adefikux на gmail точка com.

    Рейтинг
    ( Пока оценок нет )
    Загрузка ...
    Adblock
    detector