Встроенный АЦП и непонятные моменты

ejsanyo

Active member
Продолжаем работать с периферией. И вот вопрос: кто-нибудь ещё кроме меня пробовал пользовать АЦП? Если да, какие ваши впечатления и как вам удалось заставить работать его лучше всего?
Расскажу пока о своих текущих наблюдениях:
  • Странности встречают нас сразу на этапе настройки: источник опоры выбирают два бита, EXTPAD и EXTEN, что даёт выбор между встроенным ИОНом, когда они оба 0, внешним входом, когда они оба 1 (наверное), и...чем ещё? Или эти два бита следует изменять вместе и синхронно, иначе будет нерабочая схема?
  • Посмотрим далее в HAL_ADC_Init():
    C:
    #ifdef MIK32V0    hadc->Instance->ADC_CONFIG |= (hadc->Init.EXTRef << ADC_CONFIG_EXTREF_S) |   /* Настройка источника опорного напряжения */
    (hadc->Init.EXTClb << ADC_CONFIG_EXTPAD_EN_S); /* Выбор внешнего источника опорного напряжения */
    #else // MIK32V2
    hadc->Instance->ADC_CONFIG = (hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) |
    ((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M) |
    (hadc->Init.EXTRef << ADC_CONFIG_EXTREF_S) | /* Настройка источника опорного напряжения */
    (hadc->Init.EXTClb << ADC_CONFIG_EXTPAD_EN_S); /* Выбор внешнего источника опорного напряжения */
    #endif // MIK32V0
    }
    Ого, да здесь ещё и разные версии чипа всплывают! И если для "MIK32V0" всё просто и понятно, то что проворачивает код с ADC_CONFIG для актуальной версии "MIK32V2"? Мне пока как-то не очевидно что, но без этого, похоже, АЦП адекватно не работает.
  • Кстати про этот параметр, SAH_TIME: как правило, при замедлении скорости работы в АЦП уровень шумов снижается, но, похоже, не с этим контроллером. Пробовал менять значение этих битов, и единственная замеченная разница, что при уменьшении значения ниже какого-то порога, АЦП, похоже, перестаёт работать. А младшие разряды отсчётов дёргаются примерно одинаково.
  • Величина встроенной опоры у моего чипа оказалась где-то в районе 1,215В (смотрел уровень напряжения на входе, которое давало результат 0x0FFF). Пробовал подстраивать её, меняя значения битов COEF_REFICLB и COEF_REFVCLB от нуля до максимума, и...похоже это не даёт ничего. По крайней мере, разницу в шумах я не заметил. Так что не понятно, то ли подстройка на самом деле не работает, то ли я что-то делаю не так?
 

Евгений

New member
Пробовал ацп от встроенного опорного. Работает. Есть небольшой шум.
С внешним работает как то криво - все что выше 1,2 вольт = 4093. Пришлось собирать делитель 3->1.2, чтобы переменником можно было покрутить.
С настройками не баловался сейчас пока отложил этот модуль в сторону.
 

ejsanyo

Active member
Ещё такой странный момент обнаружил: когда по очереди переключаю аналоговые входы 0->1->2->0... и в каждом канале делаю однократное измерение, то в результатах получается какая-то зависшая дичь, не зависящая от фактического сигнала на этих входах! 😵
Удалось заставить адекватно работать в многоканальном режиме только так:
  • Включаю циклические измерения HAL_ADC_ContinuousEnable(&hadc);
  • Переключаю канал hadc.Init.Sel = ADC_CHANNEL0; и HAL_ADC_ChannelSet(&hadc);
  • Делаю небольшую паузу. Наверно, чтобы успел переключиться внутренний коммутатор. А то у меня иногда захватывались данные из предыдущего канала.
  • Читаю результат HAL_ADC_GetValue(&hadc);
  • Переключаю на следующий канал hadc.Init.Sel = ADC_CHANNEL1; и HAL_ADC_ChannelSet(&hadc);
  • Делаю небольшую паузу.
  • Читаю результат HAL_ADC_GetValue(&hadc);
  • Переключаю на следующий канал...
  • ...
  • ...
Кстати, похоже, что в циклическом режиме регистр ADC_VALID не работает - там всегда висит 0.
 

papakaplo

New member
Помогите проинициализировать ADC для 1.5 пина. Не могу запустить, по нулям всё показывает. Не понимаю что записывать в регистр SAH_TIME, и как в регистре SEL выбрать АЦП0 для 1.5 пина
C:
        PM->CLK_APB_P_SET |=PM_CLOCK_APB_P_ANALOG_REGS_M;    //включаем на шине APB_P аналоговые блоки
        ANALOG_REG ->ADC_CONFIG |= ADC_CONFIG_EN_M;            //Включаем питание АЦП

        GPIO_1->DIRECTION_IN =  1<<(5);
        PAD_CONFIG ->PORT_1_CFG  |= 1<<10;
        PAD_CONFIG ->PORT_1_CFG  |= 1<<11;

        ANALOG_REG ->ADC_CONFIG |= 0x800;
        ANALOG_REG ->ADC_CONFIG |=1<<4;


        ANALOG_REG ->ADC_CONFIG &=~ADC_CONFIG_EXTREF_M;        // Выбор источника опорного напряжения:«1» внешний;«0» встроенный
        ANALOG_REG ->ADC_CONFIG &=~ADC_CONFIG_EXTPAD_EN_M;    // Выбор источника внешнего опорного напряжения («1» внешний вывод или «0» настраиваемый ОИН)
        ANALOG_REG->ADC_CONTINUOUS = 1; //запуск непрерывного измерения
 

ejsanyo

Active member
Помогите проинициализировать ADC для 1.5 пина. Не могу запустить, по нулям всё показывает. Не понимаю что записывать в регистр SAH_TIME, и как в регистре SEL выбрать АЦП0 для 1.5 пина
HAL-ом в принципе не пользуетесь? Попробуйте сначала библиотечными функциями, а как хоть что-то получится, дальше смотрите в чём разница. Тем более, что, как выяснилось ранее c HAL_ADC_Init(), нам что-то явно не договаривают про нюансы этого блока. :censored:
Гляньте также исходники в архиве, про моё поделие, конечно же в папке FW. Там у меня как раз используется канал ADC0 aka нога 1.5.
 

Garry

New member
Продолжаем работать с периферией. И вот вопрос: кто-нибудь ещё кроме меня пробовал пользовать АЦП? Если да, какие ваши впечатления и как вам удалось заставить работать его лучше всего?
Расскажу пока о своих текущих наблюдениях:
  • Странности встречают нас сразу на этапе настройки: источник опоры выбирают два бита, EXTPAD и EXTEN, что даёт выбор между встроенным ИОНом, когда они оба 0, внешним входом, когда они оба 1 (наверное), и...чем ещё? Или эти два бита следует изменять вместе и синхронно, иначе будет нерабочая схема?
  • Посмотрим далее в HAL_ADC_Init():
    C:
    #ifdef MIK32V0    hadc->Instance->ADC_CONFIG |= (hadc->Init.EXTRef << ADC_CONFIG_EXTREF_S) |   /* Настройка источника опорного напряжения */
    (hadc->Init.EXTClb << ADC_CONFIG_EXTPAD_EN_S); /* Выбор внешнего источника опорного напряжения */
    #else // MIK32V2
    hadc->Instance->ADC_CONFIG = (hadc->Instance->ADC_CONFIG & (~ADC_CONFIG_SAH_TIME_M)) |
    ((hadc->Instance->ADC_CONFIG >> 1) & ADC_CONFIG_SAH_TIME_M) |
    (hadc->Init.EXTRef << ADC_CONFIG_EXTREF_S) | /* Настройка источника опорного напряжения */
    (hadc->Init.EXTClb << ADC_CONFIG_EXTPAD_EN_S); /* Выбор внешнего источника опорного напряжения */
    #endif // MIK32V0
    }
    Ого, да здесь ещё и разные версии чипа всплывают! И если для "MIK32V0" всё просто и понятно, то что проворачивает код с ADC_CONFIG для актуальной версии "MIK32V2"? Мне пока как-то не очевидно что, но без этого, похоже, АЦП адекватно не работает.
  • Кстати про этот параметр, SAH_TIME: как правило, при замедлении скорости работы в АЦП уровень шумов снижается, но, похоже, не с этим контроллером. Пробовал менять значение этих битов, и единственная замеченная разница, что при уменьшении значения ниже какого-то порога, АЦП, похоже, перестаёт работать. А младшие разряды отсчётов дёргаются примерно одинаково.
  • Величина встроенной опоры у моего чипа оказалась где-то в районе 1,215В (смотрел уровень напряжения на входе, которое давало результат 0x0FFF). Пробовал подстраивать её, меняя значения битов COEF_REFICLB и COEF_REFVCLB от нуля до максимума, и...похоже это не даёт ничего. По крайней мере, разницу в шумах я не заметил. Так что не понятно, то ли подстройка на самом деле не работает, то ли я что-то делаю не так?
COEF_REFVCLB сильно влияет на монитор напряжения питания. По умолчанию там коэф равен 8. При этом монитор у меня срабатывал при напряжении 3.2 внизу и 3.8 вверху. При коэф 4 стало 3.0/3.55 вверху, как и положено. Флаги при этом взводятся, но прерывания не возникает (пока разбираюсь). Зачем спрятали настройку в dac не понятно.
 

kutukvpavel

New member
Ещё такой странный момент обнаружил: когда по очереди переключаю аналоговые входы 0->1->2->0... и в каждом канале делаю однократное измерение, то в результатах получается какая-то зависшая дичь, не зависящая от фактического сигнала на этих входах! 😵
Удалось заставить адекватно работать в многоканальном режиме только так:
  • Включаю циклические измерения HAL_ADC_ContinuousEnable(&hadc);
  • Переключаю канал hadc.Init.Sel = ADC_CHANNEL0; и HAL_ADC_ChannelSet(&hadc);
  • Делаю небольшую паузу. Наверно, чтобы успел переключиться внутренний коммутатор. А то у меня иногда захватывались данные из предыдущего канала.
  • Читаю результат HAL_ADC_GetValue(&hadc);
  • Переключаю на следующий канал hadc.Init.Sel = ADC_CHANNEL1; и HAL_ADC_ChannelSet(&hadc);
  • Делаю небольшую паузу.
  • Читаю результат HAL_ADC_GetValue(&hadc);
  • Переключаю на следующий канал...
  • ...
  • ...
Кстати, похоже, что в циклическом режиме регистр ADC_VALID не работает - там всегда висит 0.
У меня вот тоже какая-то дичь происходит, если делать однократные измерения, переключая каналы. Нет, по факту значения верные, но не с нужного канала. Пробовал делать 2 преобразования после переключения и выбрасывать первое, немного помогло: значения "сдвинуты" относительно каналов всего на 1 канал (3 на 4 и т.д.). Правда один, некогда известный тут товарищ, говорит что это всё мой "сумбурный код со сплошными ошибками" (написан действительно в 5 утра), но судите сами: https://github.com/kutukvpavel/MicronTryout/tree/adc_channel_test.
 

kutukvpavel

New member
Помогите проинициализировать ADC для 1.5 пина. Не могу запустить, по нулям всё показывает. Не понимаю что записывать в регистр SAH_TIME, и как в регистре SEL выбрать АЦП0 для 1.5 пина
C:
        PM->CLK_APB_P_SET |=PM_CLOCK_APB_P_ANALOG_REGS_M;    //включаем на шине APB_P аналоговые блоки
        ANALOG_REG ->ADC_CONFIG |= ADC_CONFIG_EN_M;            //Включаем питание АЦП

        GPIO_1->DIRECTION_IN =  1<<(5);
        PAD_CONFIG ->PORT_1_CFG  |= 1<<10;
        PAD_CONFIG ->PORT_1_CFG  |= 1<<11;

        ANALOG_REG ->ADC_CONFIG |= 0x800;
        ANALOG_REG ->ADC_CONFIG |=1<<4;


        ANALOG_REG ->ADC_CONFIG &=~ADC_CONFIG_EXTREF_M;        // Выбор источника опорного напряжения:«1» внешний;«0» встроенный
        ANALOG_REG ->ADC_CONFIG &=~ADC_CONFIG_EXTPAD_EN_M;    // Выбор источника внешнего опорного напряжения («1» внешний вывод или «0» настраиваемый ОИН)
        ANALOG_REG->ADC_CONTINUOUS = 1; //запуск непрерывного измерения
Описание SAH_TIME есть в текущей версии документации. Это время сэмплирования сигнала УВХ АЦП. В HAL всегда пишется максимальное (3F тактов АЦП). Обратите внимание, что эта часть регистра при чтении и при записи оказывается сдвинута на 1 бит (тоже уже документировано).
 

Yuri

New member
Ещё такой странный момент обнаружил: когда по очереди переключаю аналоговые входы 0->1->2->0... и в каждом канале делаю однократное измерение, то в результатах получается какая-то зависшая дичь, не зависящая от фактического сигнала на этих входах! 😵
Удалось заставить адекватно работать в многоканальном режиме только так:
  • Включаю циклические измерения HAL_ADC_ContinuousEnable(&hadc);
  • Переключаю канал hadc.Init.Sel = ADC_CHANNEL0; и HAL_ADC_ChannelSet(&hadc);
  • Делаю небольшую паузу. Наверно, чтобы успел переключиться внутренний коммутатор. А то у меня иногда захватывались данные из предыдущего канала.
  • Читаю результат HAL_ADC_GetValue(&hadc);
  • Переключаю на следующий канал hadc.Init.Sel = ADC_CHANNEL1; и HAL_ADC_ChannelSet(&hadc);
  • Делаю небольшую паузу.
  • Читаю результат HAL_ADC_GetValue(&hadc);
  • Переключаю на следующий канал...
  • ...
  • ...
Кстати, похоже, что в циклическом режиме регистр ADC_VALID не работает - там всегда висит 0.
Добрый день, подскажите пожалуйста, а как вы делали задержку и сколько она приблизительно занимает по времени. У меня не получилось реализовать измерение с переключением каналов ни Вашим способом, ни способом с офф. репозитория https://github.com/MikronMIK32/mik32-examples/blob/main/HAL_ADC/src/main.c. Канал, который выбирается при инициализации работает корректно, а остальные нет.
 
В доке в принципе всё разжёвано. Но не очень убедительно.
Одиночное преобразование:

Вы записываете номер канала в ADC_CONFIG.SEL, например, 0 (ноль).
Вы взводите бит SINGLE, что считается сигналом СТАРТ запуска преобразования.
По сигналу СТАРТ выход входного мультиплексора подключается к УВХ, отсчитывается SAH_TIME тактов АЦП.
УВХ отключается от входного мультиплектора, начинается отсчёт 28 тактов преобразования.
После первых двух тактов преобразование входной мультиплексор переключается на канал, указанный в ADC_CONFIG.SEL (там 0).
Преобразование завершается, взводится бит ADC_VALID.VALID и в ADC_VALUE лежит результат преобразования для неизвестно какого канала.

Вы записываете номер канала в ADC_CONFIG.SEL, например, 1 (один).
Вы взводите бит SINGLE, что считается сигналом СТАРТ запуска преобразования.
По сигналу СТАРТ выход входного мультиплексора подключается к УВХ, отсчитывается SAH_TIME тактов АЦП.
УВХ отключается от входного мультиплектора, начинается отсчёт 28 тактов преобразования.
После первых двух тактов преобразование входной мультиплексор переключается на канал, указанный в ADC_CONFIG.SEL (там 1).
Преобразование завершается, взводится бит ADC_VALID.VALID и в ADC_VALUE лежит результат преобразования для канала 0 (ноль).

Вы записываете номер канала в ADC_CONFIG.SEL, например, 2 (два).
Вы взводите бит SINGLE, что считается сигналом СТАРТ запуска преобразования.
По сигналу СТАРТ выход входного мультиплексора подключается к УВХ, отсчитывается SAH_TIME тактов АЦП.
УВХ отключается от входного мультиплектора, начинается отсчёт 28 тактов преобразования.
После первых двух тактов преобразование входной мультиплексор переключается на канал, указанный в ADC_CONFIG.SEL (там 2).
Преобразование завершается, взводится бит ADC_VALID.VALID и в ADC_VALUE лежит результат преобразования для канала 1 (один).

Для непрерывного преобразования после установки номера канала нужно отбросить два измерения, третье должно быть уже для установленного номера канала.
 

ejsanyo

Active member
Добрый день, подскажите пожалуйста, а как вы делали задержку и сколько она приблизительно занимает по времени.
Конечно же самым тупым способом: пустыми командами. :whistle:
C:
#define __NOP() __asm volatile ("ADDI x0, x0, 0")
Ну а потом как-нибудь так.
C:
voltage_in[i] = (float)HAL_ADC_GetValue(&hadc) / 4095 * voltage_coeff; //провели измерение
hadc.Init.Sel = ADC_CHANNEL1; //и после этого сразу переключаем канал
HAL_ADC_ChannelSet(&hadc);
__NOP(); //задержка. Не знаю сколько конкретно надо
__NOP();
__NOP();
current_hall[i] = (float)HAL_ADC_GetValue(&hadc) / 4095 * current_hall_coeff;
hadc.Init.Sel = ADC_CHANNEL2;
HAL_ADC_ChannelSet(&hadc);
__NOP();
__NOP();
__NOP();
current_ref[i] = (float)HAL_ADC_GetValue(&hadc) / 4095 * current_ref_coeff;
hadc.Init.Sel = ADC_CHANNEL0;
HAL_ADC_ChannelSet(&hadc);
__NOP();
__NOP();
__NOP();
Полную версию см. тут.
 

Yuri

New member
Конечно же самым тупым способом: пустыми командами. :whistle:
C:
#define __NOP() __asm volatile ("ADDI x0, x0, 0")
Ну а потом как-нибудь так.
C:
voltage_in[i] = (float)HAL_ADC_GetValue(&hadc) / 4095 * voltage_coeff; //провели измерение
hadc.Init.Sel = ADC_CHANNEL1; //и после этого сразу переключаем канал
HAL_ADC_ChannelSet(&hadc);
__NOP(); //задержка. Не знаю сколько конкретно надо
__NOP();
__NOP();
current_hall[i] = (float)HAL_ADC_GetValue(&hadc) / 4095 * current_hall_coeff;
hadc.Init.Sel = ADC_CHANNEL2;
HAL_ADC_ChannelSet(&hadc);
__NOP();
__NOP();
__NOP();
current_ref[i] = (float)HAL_ADC_GetValue(&hadc) / 4095 * current_ref_coeff;
hadc.Init.Sel = ADC_CHANNEL0;
HAL_ADC_ChannelSet(&hadc);
__NOP();
__NOP();
__NOP();
Полную версию см. тут.
Мне удалось реализовать похожее (по измерениям) на смену каналов следующим образом:
C:
void adc_channel_select(uint8_t channel)
{
    hadc.Init.Sel = channel;
    HAL_ADC_Init(&hadc);
    HAL_ADC_Single(&hadc);
}
и дальше ждём получение результата предварительно меняя канал:

Код:
adc_channel_select(adcChannels[adcChannel]);
summ += HAL_ADC_WaitAndGetValue(&hadc) - ADC_OFFSET;
 

hinto

New member
Заметил, что что в разных источниках упоминают разную максимальную частоту дискредитации. 0,8 МГц либо 1 МГц.
Если согласно документации 0.8МГц = 32 МГц / (28(тактов преобразования) + 12 (SAH_TIME рекомендованное)).
Тогда при 1 МГц SAH_TIME = 32 - 28 = 4 такта.
Как я понял SAH_TIME это время которое отводиться на переходные процессы, перед началом преобразования, следовательно чем оно меньше, чем больше погрешность.
Так ли это? И если так, то как можно построить характеристику погрешности измерений ( SAH_TIME ) ?
 
12 - это не "рекомендованное", а по-моему "минимальное значение SAH для частоты ABP_P 32МГц и выходного сопротивления каскада, подключенного ко входу, равного нулю (ну, стремящегося к нулю, например, выход повторителя на ОУ)". Это время на зарядку "измерительного" конденсатора через входной коммутатор входов и всего того, что навешано на вход снаружи. Т.е. конденсатор должен успеть зарядиться до какой-то части уровня напряжения на входе за время SAH_TIME/(частота шины APB_P), см. тайминги RC цепи. Если не давать зарядиться достаточно, будет расти "погрешность". В документации к той же STM32 приведены как ёмкость конденсатора, так и таблицы максимальных значений для внешнего сопротивление в зависимости от времени SAH и разрядности преобразования. По MIK32 такой информации нет, так что построение "характеристики" только экспериментами с разными входными сопротивлениями.
 

hinto

New member
Если не сложно, опубликуйте результаты опытов.
Напишу здесь. На достоверность не претендую, просто опишу что получилось.
При запуске в непрерывном режиме ANALOG_REG->ADC_VALID не обновляется. Поэтому измерять пришлось косвенным путём.
Идея была следующая: На аналоговый вход подать сигнал. Измерять время, за которое значение ANALOG_REG->ADC_VALUE смениться 1000 раз. Разделить это время на 1000 и получить время одного сэмпла в тактах.
По началу что то не пошло, немного сменил подход.
Подключил генератор, выбрал меандр, стал подбирать частоту.
Оказалось, что на частоте сэмплирования из-за совпадения фаз соседние измерения стали одинаковыми и измеренное время таким способом увеличивалось в сотни раз, на половинной же частоте наоборот получился минимум.
Выписал выявленные максимумы и вот что вышло (дублирующие результаты опущу):

SAH_TIME​
Частота сэмплирования, кГц​
Время в тактах цпу на 1 сэмпл​
1​
1000​
32
2​
941​
34
3​
941​
34
4​
889​
36
6​
842​
38
8​
800​
40
10​
762​
42
62​
340​
94
При SAH_TIME = 0 преобразование работает, но значение на выходе частенько повисает :rolleyes:
Кстати значения в последней колонке близки к измеренному времени T/1000, в своём минимуме при половинной частоте сэмплирования, то есть получены 2мя способами.
Да результат вышел неожиданным, таким образом, при непрерывном преобразовании 1 сэмпл это ([SAH_TIME/2]*2 + 32) такта цпу.
Разница между чётными и нечётными SAH_TIME похоже существует, но на более нижнем уровне.
 
Последнее редактирование:
Что ещё раз подтверждает - непрерывный режим преобразования АЦП в Мик32 можно использовать только для мониторинга вялотекущих процессов, например, контроля напряжения питания на аккумуляторе. Т.е. для апериодических запросов. Нужна привязка к частоте выборки - тогда режим единичного преобразования с запуском из прерывания.
 

hinto

New member
Нужна привязка к частоте выборки - тогда режим единичного преобразования с запуском из прерывания.
Я согласен, если требуется длительное, непрерывное измерение, всё так и есть.
Но вот допустим требуется исследовать короткий по времени фрагмент.
Попробовал реализовать такой вариант через прерывания (сохранение всех регистров выпилил из crt0.S):
C++:
extern "C" {
  __attribute__((used, interrupt))
    void trap_handler(void)
  {
    ANALOG_REG->ADC_SINGLE = 1; //Одиночное преобразование
    buffer[count++] = ANALOG_REG->ADC_VALUE; // Сохраняем предыдущий результат
    if (count > SAMPLES) TIMER32_1->INT_MASK = 0; // Отключаем прерывание, если буфер заполнен
    TIMER32_1->INT_CLEAR = -1; // Сбрасываем флаги прерываний
    EPIC->CLEAR = -1;
  }
}
Вроде короче некуда, перевёл компилятором в ассемблер, насчитал, что выполняться это будет не меньше 100 тактов.
Вывод: если используем прерывания, то задаём SAH_TIME=63, всё равно преобразование закончиться раньше,
чем программа выйдет из прерывания.
Ну и чтоб это было более наглядно. Подключил дисплей ST7735, подаю на вход ADC сигнал с генератора (10 кГц на всех фото),
сохраняю 160 измерений, затем вывожу в виде графика, сетка 10 пикселей, в динамике выглядит ну прям как осциллограф =)
i5.jpg
i4.jpg
Ну вот и поплыли, да можно перебросить прерывание в рам, переписать его на ассемблере,
но вряд ли частота сэмплирования будет выше 300кГц.
И наконец, непрерывное преобразование, запись данных из ADC в память с помощью DMA:
p1.jpg
В последнем случае, правда есть иное ограничение: нужно либо ожидать завершения операции съёма сигнала, либо жёстко лимитировать обращение к памяти пока процесс не закончится.
 
Последнее редактирование:
Если для Ваших задач такое решение подходит - то и хорошо :) Мне не подходит, т.к. важна привязка моментов выборки к другим событиям, ну и преобразование должно идти параллельно остальной работе. Другое дело, что эти подходы можно скрестить, запуская в прерывании от таймера единичное преобразование, а считывать очередное значение через DMA по пинку от того же таймера.
 

hinto

New member
Другое дело, что эти подходы можно скрестить, запуская в прерывании от таймера единичное преобразование, а считывать очередное значение через DMA по пинку от того же таймера.
Упс. Не догадался. Да, так прерывание будет до 2х раз быстрее.
 
Последнее редактирование:
Сверху