ViKo 1 26 января, 2017 Опубликовано 26 января, 2017 · Жалоба Естественно смещение 0 может быть любым. Конечно предварительно его вычесть надо. Команды LDM на кучу регистров и SSUB16 в комплекте с ORRS/ANDS творят чудеса. B) Предварительно - это когда? Сигнал влетает слово за словом, и по нему надо синхронизироваться. А найдя (программно, если вы так уверенно гарантируете), нужно запустить таймер, отсчитывающий количество выборок в захваченном кадре (или части кадра, от положения момента синхронизации зависит). Это еще несколько тактов нужно иметь. Набегает намного больше, чем 6. На STM32F303 многое можно сделать аппаратно. Я сделал. Открыть реализацию не считаю возможным. Имеющему интерес рекомендую изучить datasheet вдоль и поперек, там есть волшебные возможности. Еще один момент. Частоту дискретизации (развертку) желаете разную иметь? То есть, задавать таймером? А как тогда принимать данные с АЦП? Или прореживать непрерывно идущие данные, записывать реже? Здесь тоже есть где потерять тактов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 26 января, 2017 Опубликовано 26 января, 2017 · Жалоба Предварительно - это когда? Сигнал влетает слово за словом, и по нему надо синхронизироваться. А найдя (программно, если вы так уверенно гарантируете), нужно запустить таймер, отсчитывающий количество выборок в захваченном кадре (или части кадра, от положения момента синхронизации зависит). Это еще несколько тактов нужно иметь. Набегает намного больше, чем 6. Похоже у Вас нет опыта обработки потоков данных.... Никаких "слово за словом", никаких таймеров и прочей аппаратной лабуды. Работа идёт с потоком данных, находящимся в ОЗУ. Данные поступают в ОЗУ пакетно - блоками большой длины через DMA. В рассматриваемом случае - из внутреннего АЦП LPC4370. Процессор просматривает поток DMA-блоков в поиске старта синхронизации (откуда начинать захватывать кадр для показа на экране). Все времянки (отступы, размеры кадра и пр.) конечно задаются в сэмплах, так как частота их известна. А теперь открываем описание системы команд Cortex-M4 и пишем обработчик DMA-блоков данных, который ищет момент перехода через "0": PUBLIC AdcExec ;extern "C" void AdcExec(u32 *data, s32 sign, u32 zero); ;R0 - указатель на блок сэмплов для обработки (упакованы в 32-битные слова - по 2 сэмпла в каждом в битах 0...11 и 16...27 - в таком формате их выдаёт АЦП LPC4370) ;R1 - знак предыдущего значения сигнала ;R2 - текущее смещение нуля (в мл. 16 битах, остальные биты ==0) ;в блоке сэмплов [R0] находится 20*N*M сэмплов принятых в очередном блоке DMA ;каждый сэмпл - 12-битный беззнаковый, так что 0 - при мин. значении напряжения, 0xFFF - при макс, 0 шкалы АЦП == 0x800 histerezis EQU 10 ;если желаем гистерезис M EQU ... AdcExec: PUSH {R4-R11, LR} LSLS R3, R1, #1 BMI AdcExec_01 SUBS R2, R2, #histerezis IT MI MOVSMI R2, #0 B AdcExec_02 AdcExec_01: ADDS R2, R2, #histerezis LSRS R3, R2, #12 IT NE MOVNE R2, #0FFFh AdcExec_02: ORRS LR, R2, R2, LSL #16 MOVS R2, #M ;количество повторов 20*N для обработки всего блока сэмплов LSLS R3, R1, #1 BMI AdcExec_21 ;поиск <0 AdcExec_11: LDMIA R0!, {R3-R12} ;грузим 20 сэмплов в регистры SSUB16 R3, R3, LR ;вычтем смещение нуля из 2-х сэмплов SSUB16 R4, R4, LR ;повторим для остальных 18 сэмплов SSUB16 R5, R5, LR SSUB16 R6, R6, LR SSUB16 R7, R7, LR SSUB16 R8, R8, LR SSUB16 R9, R9, LR SSUB16 R10, R10, LR SSUB16 R11, R11, LR SSUB16 R12, R12, LR ORRS R3, R3, R4 ORRS R3, R3, R5 ORRS R3, R3, R6 ORRS R3, R3, R7 ORRS R3, R3, R8 ORRS R3, R3, R9 ORRS R3, R3, R10 ORRS R3, R3, R11 ORRS R3, R3, R12 ORRS R3, R3, R3, LSL #16 AdcExec_12: BMI AdcExec_14 ;переход если в предыдущих 20 сэмплах обнаружен переход через 0 вниз LDMIA R0!, {R3-R12} ;грузим следующие 20 сэмплов в регистры ;N раз повторим команды AdcExec_01...AdcExec_02 ;... SUBS R2, R2, #1 AdcExec_13: BNE AdcExec_11 ;обработали весь блок сэмплов, не нашли перехода через 0, ждём следующего блока от DMA POP {R4-R11, PC} AdcExec_14: ;здесь получено состояние "обнаружен переход через 0 вниз" в одном из предыдущих 20 сэмплов R0[-20]...R0[-1] ;сделаем более точное обнаружение с точностью до сэмпла и перейдём к захвату потока сэмплов для отображения AdcExec_21: ;здесь напишем аналог процедуры AdcExec_11...AdcExec_13, но для поиска перехода в >=0 Участок AdcExec_11...AdcExec_12 обрабатывающий 20 сэмплов, должен выполняться примерно за 23 такта (расположим его в самой быстрой памяти, в ОЗУ например). Берём калькулятор и видим, что на обработку одного сэмпла нужно немного более 1 такта. Так что о каких "намного больше, чем 6" речь? Может у Вас на STM32F303 это так, но для LPC4370 всё ГОРАЗДО быстрее. Еще один момент. Частоту дискретизации (развертку) желаете разную иметь? То есть, задавать таймером? А как тогда принимать данные с АЦП? Или прореживать непрерывно идущие данные, записывать реже? Здесь тоже есть где потерять тактов. Частота развёртки - в смысле частота сэмплирования АЦП? При чём тут таймер??? Она задаётся тактовой частотой АЦП и её не трудно установить какую нужно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 26 января, 2017 Опубликовано 26 января, 2017 · Жалоба Начну с конца. Что за тактовая частота АЦП? На которой работает SAR ADC? Это к делу не относится. Должна быть достаточно большой, чтобы АЦП успевал работать. Речь про частоту запуска АЦП, от десятков мегавыборок до единиц выборок в секунду. Временная база, делается на таймерах. У вас никак не делается, постоянно одна (максимальная) частота выборок? Это не осциллограф. Код рассмотрю в свободное от досуга время. Что там в AdcExec_14, "более точном"? Еще тактов 20? Или вас устраивает болтание кадра на 20 выборок вправо-влево? А для перехода не через 0 видим только "аналог" программы? Для всех 4096 уровней по "аналогу"? Или там речь про фронт и срез сигнала? Вычитая смещение (я правильно разглядел), можно ненароком перекрутить сигнал с минуса в плюс. Дальше что? Нашли переход, включаем таймер... Все нужно успеть за пачку выборок. Пока что полного решения не вижу. Оно было? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 26 января, 2017 Опубликовано 26 января, 2017 · Жалоба Берём калькулятор и видим, что на обработку одного сэмпла нужно немного более 1 такта. Так что о каких "намного больше, чем 6" речь? Может у Вас на STM32F303 это так, но для LPC4370 всё ГОРАЗДО быстрее. Это же пакетная постобработка. Не так интересно. И памяти лишней требует и претриггеринг не гарантированный. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 26 января, 2017 Опубликовано 26 января, 2017 · Жалоба Пакет еще дождаться надо, а в коде, кроме "ждём следующего блока от DMA", ничего не показано. А это еще несколько тактов+. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 26 января, 2017 Опубликовано 26 января, 2017 · Жалоба Начну с конца. Что за тактовая частота АЦП? На которой работает SAR ADC? Это к делу не относится. Должна быть достаточно большой, чтобы АЦП успевал работать. Речь про частоту запуска АЦП, от десятков мегавыборок до единиц выборок в секунду. Временная база, делается на таймерах. У вас никак не делается, постоянно одна (максимальная) частота выборок? Это не осциллограф. Имелась в виду частота сэмплирования АЦП. Я осциллограф не делаю. Делает ТС. У него в ТЗ указана только одна частота выборок. Нужность реализации других частот - его дело. И "у меня" тоже делается. Вам код инициализации АЦП LPC4370 привести? Сами юзермануал прочитайте. Для тактирования АЦП LPC4370 можно использовать отдельный PLL с пачкой опциональных делителей после него - никаких таймеров не нужно. Код рассмотрю в свободное от досуга время. Что там в AdcExec_14, "более точном"? Еще тактов 20? Или вас устраивает болтание кадра на 20 выборок вправо-влево? В смысле??? Вы смысл кода вообще поняли? Какое болтание и какая разница сколько тактов будет в AdcExec_14??? В точке AdcExec_14 уже найдено, что в последних 20 сэмплах точно есть переход. А значит этот участок выполняется 1 раз на одно срабатывание синхронизатора. Т.е. - 1 раз на один отображаемый кадр. Т.е. - не более чем 50 раз в секунду. И какая разница сколько там тактов? Да хоть 200 хоть 2000. А для перехода не через 0 видим только "аналог" программы? Для всех 4096 уровней по "аналогу"? Или там речь про фронт и срез сигнала? Не понял о чём речь Возьмите учебник по командам Cortex-M и разберитесь в коде. Этот код ищет момент перехода через "0". Это самая ресурсозатратная часть алгоритма. О чём писал AlexandrY и утверждал что её невозможно сделать на Cortex-M для данной частоты. Всё остальное - ерунда. Вычитая смещение (я правильно разглядел), можно ненароком перекрутить сигнал с минуса в плюс. Нет, неправильно. До вычитания данные беззнаковые, после вычитания получаются знаковые данные, дальше анализируется их знак. Дальше что? Нашли переход, включаем таймер... Все нужно успеть за пачку выборок. Какой таймер??? Вы опять за своё. Похоже что ничего не поняли..... Это же пакетная постобработка. Не так интересно. И памяти лишней требует и претриггеринг не гарантированный. Почему неинтересно? Именно так и работает любая обработка потоков данных. Именно так и можно сделать поиск точки синхронизации для осциллографа - вполне рабочий вариант. И почему не гарантированный? Пакет еще дождаться надо, а в коде, кроме "ждём следующего блока от DMA", ничего не показано. А это еще несколько тактов+. Какая разница сколько тактов? Ещё раз - Вы не поняли ничего в работе этого кода. Этот код должен запускаться на каждый принятый блок сэмплов от DMA. Размер такого блока должен быть достаточно большим (там приведено условие 20*N*M чем больше N и M - тем меньше загрузка CPU - эффективнее обработка). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 26 января, 2017 Опубликовано 26 января, 2017 · Жалоба О чём писал AlexandrY и утверждал что её невозможно сделать на Cortex-M для данной частоты. Всё остальное - ерунда. Эй, вы еще ничего не доказали. У вас есть всего три такта на ваших 204 МГц для каждого отсчета даже на постобработке. Полное решение в студию! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 26 января, 2017 Опубликовано 26 января, 2017 · Жалоба Эй, вы еще ничего не доказали. У вас есть всего три такта на ваших 204 МГц для каждого отсчета даже на постобработке. Полное решение в студию! В том коде что я привёл - полное доказательство. Знающий асм для Cortex-M может это увидеть. Не 3 такта, Слесарь хотел вообще-то 32MS/s. Берём калькулятор и считаем: 204/32 = 6.375 Но и на бОльших частотах должно хватить быстродействия. PS: Для непонявших: Приведённый код только ищет точку синхронизации (перехода через "0") сигнала. Это самая ресурсоёмкая часть работы которую должен выполнять процессор в осциллографе. Больше этот код ничего не делает. Остальная работа - по отображению картинки это уже ерунда по требуемой вычислительной мощности. Остальная работа тривиальна. И памяти лишней требует В LPC4370 282КБ внутреннего ОЗУ - за глаза хватит. Скажем выберем: N=4, M=10. Тогда будем обрабатывать DMA-блоки по 20*4*10 сэмплов. И того потребуется 2 DMA-буфера по 20*4*10*2 байт. Это ни о чём при 282КБ имеющихся. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 26 января, 2017 Опубликовано 26 января, 2017 · Жалоба И "у меня" тоже делается. Вам код инициализации АЦП LPC4370 привести? Сами юзермануал прочитайте. Поверю на слово - АЦП в LPC4370 может запускаться с частотой от единиц Гц до 80 МГц - подтверждаете? Для тактирования АЦП LPC4370 можно использовать отдельный PLL с пачкой опциональных делителей после него - никаких таймеров не нужно. Хоть так, хоть сяк, вам нужно ждать, пока придет весь пакет. Ждать - проверять условие. Тратить такты. Какое болтание и какая разница сколько тактов будет в AdcExec_14??? В точке AdcExec_14 уже найдено, что в последних 20 сэмплах точно есть переход. А значит этот участок выполняется 1 раз на одно срабатывание синхронизатора. И что с того, что один раз? Пока будете разбираться с этим пакетом, следующий потеряете. Возьмите учебник по командам Cortex-M и разберитесь в коде. Инкриминируете мне свои фантазии? :rolleyes: Я, не вникая в этот код, вижу его монстрообразность. Этот код ищет момент перехода через "0". В какую сторону? А в другую ищет? Вот на что намекал. Какой таймер??? Вы опять за своё. Похоже что ничего не поняли..... Вам слишком много мерещится. Когда захват останавливать будете? Надо отсчитать некое количество выборок после синхронизации. Об этом уже писал. Этот код должен запускаться на каждый принятый блок сэмплов от DMA. Размер такого блока должен быть достаточно большим (там приведено условие 20*N*M Так, конкретно, сколько было у вас? Вы рисовали на индикаторе кадр за кадром синхронизированные точно в одной выборке? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 26 января, 2017 Опубликовано 26 января, 2017 · Жалоба В том коде что я привёл - полное доказательство. В LPC4370 внутреннего ОЗУ несколько сотен КБ - за глаза хватит. Ладно, согласен. Одобряю для применения в детском осциллограффе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 26 января, 2017 Опубликовано 26 января, 2017 · Жалоба P.S. у меня STM32F303 автоматом аппаратно находит пересечение уровня (любого!). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 26 января, 2017 Опубликовано 26 января, 2017 · Жалоба Ладно, согласен. Одобряю для применения в детском осциллограффе. Конечно для детского варианта 32MS/s (и даже сколько-то больше) вполне хватит. А о серьёзных характеристиках в сотни MS/s и не говорил никто. P.S. у меня STM32F303 автоматом аппаратно находит пересечение уровня (любого!). Находит где/в_чём? Во внешнем аналоговом сигнале заведённом на ногу компаратора в МК? А толку? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 26 января, 2017 Опубликовано 26 января, 2017 · Жалоба Находит где/в_чём? Во внешнем аналоговом сигнале заведённом на ногу компаратора в МК? Не-а. В коде, поступающем с (внутреннего, естественно) АЦП. С точностью до LSB. "Сами юзермануал прочитайте." Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 26 января, 2017 Опубликовано 26 января, 2017 · Жалоба Не-а. В коде, поступающем с АЦП. С точностью до LSB. "Сами юзермануал прочитайте." В сэмплах в памяти МК? С помощью какой-то периферии? Я не знаком с периферией STM32F303 - не нужно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 26 января, 2017 Опубликовано 26 января, 2017 · Жалоба В сэмплах в памяти МК? С помощью какой-то периферии? Я не знаком с периферией STM32F303 - не нужно. Прямо в АЦП. :rolleyes: С помощью периферии. :rolleyes: Всяк кулик хвалит свое... :laughing: Сейчас мельком глянул в свои исходники. До 9 МВыб/с на одном АЦП получалось. При урезании разрядности. Два чередовать не получалось на высокой частоте. Сдвиг есть. Нерегулярные выборки. Причем, похоже, во всех АЦП в STM32. Когда они пишут, что можно в режиме чередования получить больше мегавыборок, это не совсем верно. А еще у меня были развертки со случайными выборками. То есть, эквивалентную частоту дискретизации можно было получить раз в 7 больше. Для периодического сигнала, понятно. Это не рисовал, только измеренное значение сдвига между синхронизацией и выборкой наблюдал. Там уже аппаратный компаратор работал, да. Встроенный. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться