Третья часть (первая и вторая) про то как я делаю осциллограф из отладочной платы ценой менее $3. Демонстрационное видео работы:

А описание некоторых ключевых особенностей под катом.



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


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

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

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


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

CooCox CoIDE выводит информацию о размер программы в таком виде:
      text	   data	    bss	    dec	    hex	filename
     60224	   2500	  10540	  73264	  11e30	projectName.elf

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


Вся программа занимает:
  • флеш — text + data + 10..50 байт
  • ОЗУ — data + bss + 10..50 байт


Теперь посмотрим на что тратится память. Делаем новый проект и компилируем:
      text	   data	    bss	    dec	    hex	filename
       364	   1080	     32	   1476	    5c4	test-size.elf

Чтобы использовать макросы типа GPIO_BSRR_BS9 надо подключить файл stm32f10x.h.
Чтобы подключить файл stm32f10x.h надо в репозитоях добавить компонент STM32F10x_MD_STDLIB, который подтягивает за собой cmsis_core. В итоге для программы, записывающей одно значение в регистр получаем:
      text	   data	    bss	    dec	    hex	filename
      1316	   1104	     32	   2452	    994	test-size.elf

Далее меня интересуют функции типа sprintf и sscanf. Чтобы их использовать надо определить некоторые функции типа _sbrk и возможно некоторых других. Я взял готовый файл (есть в архиве с проектом). Добавляем 1 вызов sscanf и получаем:
Попробуйте угадать сколько, прежде чем смотреть!
      text	   data	    bss	    dec	    hex	filename
     39312	   2264	     96	  41672	   a2c8	test-size.elf

41 кБ флеша! Больше половины, того, что есть в контроллере!
В рабочей же прошивке при использовании printf добавление sscanf увеличивает потребление флеша на 13.2 кБ. В итоге от sscanf отказался, а команды от ПК стал парсить менее ресурсоёмким методом.
Отказ же от printf позволяет сэкономить ещё 8.3 кБ.


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


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

Непрерывный


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

Пакетный


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

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

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


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

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


Самый быстрый режим. Примерно 20 MSPS на каждом канале. Самый быстрый код для этого режима выглядит так:
u32 i = 0;
dataBuffer.u8[i] = GPIOA->IDR;
dataBuffer.u8[++i] = GPIOA->IDR;
dataBuffer.u8[++i] = GPIOA->IDR;
dataBuffer.u8[++i] = GPIOA->IDR;
dataBuffer.u8[++i] = GPIOA->IDR;
dataBuffer.u8[++i] = GPIOA->IDR;

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

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


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

Итог


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

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

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


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

Комментарии (18)


  1. Flaksirus
    12.07.2016 15:30
    +1

    Архив с проектом? Серьезно? Почему не гит репозиторий? Так же гораздо удобнее для всех!


    1. xedas
      12.07.2016 16:09

      По старинке. Всё никак не заставлю себя научиться пользоваться Git.


      1. Flaksirus
        12.07.2016 16:12
        +3

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


        1. Foolleren
          12.07.2016 17:22

          Все в облаке, никуда не денется, еще и историю всегда можно глянуть.

          если в очередной раз роском-что-то-там, о себе не напомнит, или какой другой «сщит хепенс».


          1. Flaksirus
            13.07.2016 11:52

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


  1. uterr
    12.07.2016 15:56

    Привет! Расскажите, сколько отсчетов в секунду удается получить на таком МК? Есть ли разница, если использовать 1 канал или 4? Можете ли рассказать, какая разница по сравнению с другими МК, если сравнивали?


    1. xedas
      12.07.2016 16:50
      +1

      В первой части про скорость писал. Вкратце: без разгона получается 2 MSPS, с разгоном 9 MSPS.
      Имеющиеся выборки делятся на все каналы. Это в режиме осциллографа.

      В режиме логического анализатора ничего не делится — там читается порт целиком и скорость выборок каждого канала не зависит от количества каналов.

      Если сравнивать с AVR (ATmega, ATtiny), то этот выигрывает на 2 порядка у них.
      У доступного на ebay STM8S103F3P6 АЦП тоже быстрый, сколько не помню.
      Если смотреть на STM, то у STM32F303, насколько я понял, можно 20 MSPS без разгона получить, вот только он сильно дороже, а отладочные платы с ним порядка $25 стоят.


  1. x893
    12.07.2016 16:48

    А DMA из GPIOA->IDR в память не быстрее разве?


    1. xedas
      12.07.2016 16:54

      DMA медленней. Тут про это пишут. Я проверил — DMA действительно медленнее получается.


  1. GarryC
    12.07.2016 17:13

    По поводу размера маленькая подсказка — не знаю, как у Вашего компилятора, но в IAR есть специальное поле настройки, где можно указать вид форматера print и scanf, если поставить там и там tiny, Вы будете приятно удивлены результатами. Ведь маловероятно, чтобы Вам требовались форматы с плавающей точкой двойной точности. Наверняка у Вашего компиляторы должны быть аналогичные опции.


  1. jaiprakash
    13.07.2016 14:36

    Автору — респект, однако, появилось несколько вопросов.
    1) Не нашёл полной схемы, но по косвенным признакам понял что для ОУ выбрано питание +-10 В, а не +-5 В (как в USBee AX, например). Это так? И почему?
    2) Где вы покупаете LT1054 по $0.8? Это в розницу и без учёта доставки?
    Просто обычно в «народных» проектах — MC34063, доступный и недорогой.


  1. xedas
    13.07.2016 15:59

    1. Питание ОУ +10 и -8.4 В получается. Динамические характеристики ОУ при таком питании лучше, чем при +-5В. Сейчас легко менять напряжение питание ОУ крутя винт переменного резистора.
    2. Искал так. Сейчас цены от $1.05. Для MC34063 сложнее обвязка, а у LT1054 3 конденсатора — и инвертор готов.


    1. jaiprakash
      13.07.2016 16:15

      Спасибо.
      2) Ну для 5 штук — да)
      Ещё вопрос — как вы фильтруете напряжение после импульсных преобразователей? (схемы всё-таки не хватает в статье)
      Непонятно — эти шумы связаны с плохим питанием или с разогнанным АЦП.


      1. xedas
        13.07.2016 17:08

        Про шумы от импульсных преобразователей не подумал, понадеялся на конденсатор 10 мкФ на питании.
        Шумы действительно проходят. Вот с включённым преобразователем:

        вот тоже самое с выключенным:

        В обоих случаях АЦП не разогнан, период сигнал 1 мс.

        Надо будет в дальнейшем подумать над фильтрами + чтобы наводок поменьше было.

        Про схему: эти скриншоты делал без аналоговой части, сигналы подавал прям на ноги МК, но даже в этом случае работающие рядом преобразователи добавляют шум.


        1. jaiprakash
          13.07.2016 17:14

          Обычно в таких схемах помимо конденсаторов ставят индуктивности, пропуская питание через них.


  1. asakasinsky
    14.07.2016 07:02

    xedas, здравствуйте! Можете для завершения всей картины выложить схему?


    1. xedas
      14.07.2016 08:05

      Рисовать там особо нечего, напишу лучше инструкцию по сборке.

      1. Смотрим схему отладочной платы, видим резистор R10, ищем его на плате и выпаиваем/выламываем. Вместо него подпаиваем резистор на 1.5k (по стандарту USB) к ноге B9 (случайно выбрал и прописал её в коде). Получается резистор между A12 и B9.
      2. ST-Link подключаем к верхней гребёнке из 4-х штырьков согласно надписям на ST-Link и гребёнке.
      3. Вход осциллографа и анализатора будет на ногах A0, A1, A2, A3.
      4. Прошиваем МК.
      5. Подключаем отладочную плату через её micro-usb разъём к компу. Если не появился виртуальный com-порт, отключаем, устанавливаем драйверы, и снова подключаем. Должен появиться порт. Откуда брал драйверы, не помню. Возможно по ссылке из этой статьи, но эти ссылки сейчас не работают
      6. Открываем проект для Visual Studio из архива, прописываем свой номер порта, запускаем и должно заработать!

      В итоге получаем рабочую систему, но с ограничениями на входной сигнал 0..3.3 В. Если нужен диапазон шире, то во второй части есть пример аналоговой части. Чтобы управлять ей с ПК, открываем файл com.c и в функцию comIn дописываем обработчики своих команд. Ну и в программе для ПК добавляем элементы управления и прописываем к ним отправку этих команд, можно по образцу тех «делитель z», «усилитель x», что справа.


      1. asakasinsky
        14.07.2016 14:54

        Спасибо.