Оглавление:
- Шаг 1: Создайте массив данных синусоиды
- Шаг 2: Включение параллельного вывода
- Шаг 3: Включение прерывания
- Шаг 4: ЦАП R / 2R
- Шаг 5: Полный код
Видео: Генератор 3-фазной синусоидальной волны на базе Arduino Due: 5 шагов
2024 Автор: John Day | [email protected]. Последнее изменение: 2024-01-30 11:51
цель этой публикации - помочь тем, кто пытается использовать более высокую производительность Due + отсутствие справочной информации + бесполезную таблицу данных.
этот проект способен генерировать до 3-х фазных синусоидальных волн при 256 отсчетов / цикл на низкой частоте (<1 кГц) и 16 отсчетов / цикл при высокой частоте (до 20 кГц), что достаточно хорошо для сглаживания простыми LPF и вывод почти идеальный.
прикрепленный файл не был моей последней версией, потому что я добавил некоторые дополнительные функции, но ядро такое же. Обратите внимание, что выборка / цикл была установлена ниже, чем указано выше.
поскольку емкость ЦП максимизируется с помощью подхода, показанного в прикрепленном файле, я использовал Arduino Uno в качестве блока управления, который использует внешнее прерывание Arduino Due для передачи значения частоты в Arduino Due. В дополнение к контролю частоты, Arduino Uno также контролирует амплитуду (через цифровой измеритель потенциала + операционный усилитель), а также ввод / вывод - будет много места для игры.
Шаг 1: Создайте массив данных синусоиды
Поскольку расчет в реальном времени требует ресурсов ЦП, для повышения производительности требуется массив синусоидальных данных.
uint32_t sin768 PROGMEM =…. while x = [0: 5375]; y = 127 + 127 * (sin (2 * pi / 5376 / * или какой-то другой #, который вы предпочитаете, зависит от требований * /))
Шаг 2: Включение параллельного вывода
В отличие от Uno, у Due есть ограниченное количество ссылок. Однако для генерации 3-фазной синусоидальной волны на основе Arduino Uno, во-первых, производительность неприемлема из-за его низкого MCLK (16 МГц, а Due - 84 МГц), во-вторых, ограниченный GPIO может выдавать максимум 2-фазный выход, и вам нужны дополнительные аналоговая схема для получения 3-й фазы (C = -AB).
Последующее включение GPIO было в основном основано на пробной версии + не полезное техническое описание SAM3X
PIOC-> PIO_PER = 0xFFFFFFFE; // Регистр включения PIO контроллера PIO (см. P656 таблицы данных ATMEL SAM3X) и https://arduino.cc/en/Hacking/PinMappingSAM3X, были включены выводы 33-41 и 44-51 Arduino Due
PIOC-> PIO_OER = 0xFFFFFFFE; // Регистр разрешения выхода контроллера PIO, см. P657 таблицы данных ATMEL SAM3X PIOC-> PIO_OSR = 0xFFFFFFFE; // Регистр состояния выхода контроллера PIO, см. P658 таблицы данных ATMEL SAM3X
PIOC-> PIO_OWER = 0xFFFFFFFE; // Регистр разрешения записи выхода PIO, см. P670 таблицы данных ATMEL SAM3X
// PIOA-> PIO_PDR = 0x30000000; // необязательно в качестве страховки, похоже, не влияет на производительность, цифровой контакт 10 подключается как к PC29, так и к PA28, цифровой контакт 4 подключается к PC29 и PA28, здесь для отключения отключения PIOA # 28 и 29
Шаг 3: Включение прерывания
Чтобы обеспечить максимальную производительность, загрузка процессора должна быть как можно ниже. Однако из-за соответствия не 1: 1 между выводом CPU и выводом Due, необходима битовая операция.
Вы можете дополнительно оптимизировать алгоритм, но комната очень ограничена.
недействительным TC7_Handler (недействительным) {TC_GetStatus (TC2, 1);
t = t% образцов; // используйте t% samples вместо if, чтобы избежать переполнения t
phaseAInc = (предустановка * t)% 5376; // используйте% 5376, чтобы избежать переполнения индекса массива
phaseBInc = (phaseAInc + 1792)% 5376;
phaseCInc = (phaseAInc + 3584)% 5376;
p_A = sin768 [phaseAInc] << 1; // ссылка на PIOC: PC1 - PC8, соответствующий вывод Arduino Due: выводы 33-40, следовательно, сдвиг влево на 1 цифру
p_B = sin768 [phaseBInc] << 12; // обратитесь к PIOC: PC12 - PC19, соответствующий вывод Arduino Due: вывод 51-44, следовательно, сдвиньте влево 12 цифр
p_C = sin768 [phaseCInc]; // вывод фазы C использует PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 и PC29, соответствующий вывод Arduino Due: цифровой вывод: 9, 8, 7, 6, 5, 4, 3, 10, соответственно
p_C2 = (p_C & B11000000) << 22; // это генерирует PC28 и PC29
p_C3 = (p_C & B00111111) << 21; // это генерирует PC21-PC26
p_C = p_C2 | p_C3; // это генерирует параллельный вывод фазы C
p_A = p_A | p_B | p_C; // 32-битный выход = фаза A (8 бит) | фаза B | фаза C
PIOC-> PIO_ODSR = p_A; // выходной регистр = p_A
t ++; }
Шаг 4: ЦАП R / 2R
построить 3x8bit R / 2R DAC, множество ссылок в Google.
Шаг 5: Полный код
#define _BV (x) (1 << (x)); uint32_t sin768 PROGMEM = / * x = [0: 5375]; y = 127 + 127 * (sin (2 * pi / 5376)) * /
uint32_t, p_A, p_B, p_C, p_C2, p_C3; // фаза A фаза B значение фазы C - хотя выход только 8-битный, значения p_A и p_B будут использоваться для генерации нового 32-битного значения для копирования с 32-битным выходом PIOC
uint16_t phaseAInc, phaseBInc, phaseCInc, freq, freqNew; uint32_t interval; образцы uint16_t, предустановленные; uint32_t t = 0;
void setup () {
// Параллельный выход Настройка PIOC: контакты 33-40 Arduino Due используются как выход фазы A, а контакты 44-51 работают как выход фазы B
PIOC-> PIO_PER = 0xFFFFFFFE; // Регистр включения PIO контроллера PIO (см. P656 таблицы данных ATMEL SAM3X) и https://arduino.cc/en/Hacking/PinMappingSAM3X, были включены выводы 33-41 и 44-51 Arduino Due
PIOC-> PIO_OER = 0xFFFFFFFE; // Регистр разрешения выхода контроллера PIO, см. P657 таблицы данных ATMEL SAM3X
PIOC-> PIO_OSR = 0xFFFFFFFE; // Регистр состояния выхода контроллера PIO, см. P658 таблицы данных ATMEL SAM3X
PIOC-> PIO_OWER = 0xFFFFFFFE; // Регистр разрешения записи выхода PIO, см. P670 таблицы данных ATMEL SAM3X
// PIOA-> PIO_PDR = 0x30000000; // необязательно в качестве страховки, похоже, не влияет на производительность, цифровой контакт 10 подключается к PC29 и PA28, цифровой контакт 4 подключается к PC29 и PA28, здесь, чтобы отключить отключение PIOA # 28 и 29 // настройка таймера, см. https://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (ложь); // отключаем защиту от записи регистров управления питанием
pmc_enable_periph_clk (ID_TC7); // включить счетчик времени периферийных часов 7
TC_Configure (/ * часы * / TC2, / * канал * / 1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); // TC clock 42MHz (часы, канал, настройка режима сравнения) TC_SetRC (TC2, 1, interval); TC_Start (TC2, 1);
// разрешаем прерывания по таймеру TC2-> TC_CHANNEL [1]. TC_IER = TC_IER_CPCS; // IER = регистр разрешения прерывания TC2-> TC_CHANNEL [1]. TC_IDR = ~ TC_IER_CPCS; // IDR = регистр отключения прерывания
NVIC_EnableIRQ (TC7_IRQn); // Разрешить прерывание во вложенном векторном контроллере прерываний freq = 60; // инициализируем частоту как 60 Гц preset = 21; // увеличение индекса массива на 21 выборку = 256; // вывод сэмплов 256 / интервал цикла = 42000000 / (freq * samples); // количество прерываний TC_SetRC (TC2, 1, interval); // запускаем TC Serial.begin (9600); // в тестовых целях}
void checkFreq ()
{freqNew = 20000;
if (freq == freqNew) {} еще
{freq = freqNew;
если (частота> 20000) {частота = 20000; / * максимальная частота 20кГц * /};
если (частота <1) {частота = 1; / * минимальная частота 1 Гц * /};
если (частота> 999) {preset = 384; samples = 14;} // для частоты> = 1 кГц, 14 выборок на каждый цикл
иначе, если (частота> 499) {preset = 84; samples = 64;} // для 500 <= frequency99) {preset = 42; samples = 128;} // для 100 Гц <= частота <500 Гц 128 выборок / цикл
иначе {preset = 21; образцы = 256;}; // для частоты <100 Гц, 256 отсчетов для каждого цикла
интервал = 42000000 / (частота * выборки); t = 0; TC_SetRC (TC2, 1, интервал); }}
void loop () {
checkFreq (); задержка (100); }
недействительным TC7_Handler (недействительным)
{TC_GetStatus (TC2, 1);
t = t% образцов; // используйте t% образцов, чтобы избежать переполнения t phaseAInc = (preset * t)% 5376; // используйте% 5376, чтобы избежать переполнения индекса массива
phaseBInc = (phaseAInc + 1792)% 5376;
phaseCInc = (phaseAInc + 3584)% 5376;
p_A = sin768 [phaseAInc] << 1; // ссылка на PIOC: PC1 - PC8, соответствующий вывод Arduino Due: выводы 33-40, следовательно, сдвиг влево на 1 цифру
p_B = sin768 [phaseBInc] << 12; // обратитесь к PIOC: PC12 - PC19, соответствующий вывод Arduino Due: вывод 51-44, следовательно, сдвиньте влево 12 цифр
p_C = sin768 [phaseCInc]; // вывод фазы C использует PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 и PC29, соответствующий вывод Arduino Due: цифровой вывод: 9, 8, 7, 6, 5, 4, 3, 10, соответственно
p_C2 = (p_C & B11000000) << 22; // это генерирует PC28 и PC29
p_C3 = (p_C & B00111111) << 21; // это сгенерирует PC21-PC26 //Serial.println(p_C3, BIN); p_C = p_C2 | p_C3; // это генерирует параллельный вывод фазы C
p_A = p_A | p_B | p_C; // 32-битный вывод = фаза A (8 бит) | фаза B | фаза C //Serial.println(p_A>>21, BIN); // PIOC-> PIO_ODSR = 0x37E00000;
PIOC-> PIO_ODSR = p_A; // выходной регистр = p_A t ++; }
Рекомендуемые:
Производство платы управления синусоидальной волной: 5 шагов
Производство платы управления синусоидальной волной: на этот раз это плата управления автономной однофазной синусоидальной волной, за которой следует плата автономного управления однофазной синусоидальной волной, затем плата автономного управления трехфазной синусоидальной волной, и, наконец, плата автономного управления с трехфазной синусоидальной волной. Мы надеемся, что
Генерация волны ШИМ с помощью микроконтроллера PIC: 6 шагов
Генерация волны ШИМ с помощью микроконтроллера PIC: ЧТО ТАКОЕ ШИМ? СТЕНДЫ ШИМ ДЛЯ МОДУЛЯЦИИ ШИРИНЫ ИМПУЛЬСА - это метод, с помощью которого изменяется ширина импульса. Чтобы четко понять эту концепцию, рассмотрим тактовый импульс или любой прямоугольный сигнал с коэффициентом заполнения 50%, что означает, что периоды Ton и Toff одинаковы
См. Звуковые волны с использованием цветного света (светодиод RGB): 10 шагов (с изображениями)
См. Раздел «Звуковые волны с использованием цветного света (светодиод RGB)». Здесь вы можете видеть звуковые волны и наблюдать интерференционные картины, создаваемые двумя или более преобразователями при изменении расстояния между ними. (Крайний левый, интерференционная картина с двумя микрофонами при 40 000 циклов в секунду; вверху справа, один микрофон
Сделайте схему NE555 для генерации синусоидальной волны: 6 шагов
Сделай сам схему NE555 для генерации синусоиды: в этом руководстве вы узнаете, как сделать самодельную схему NE555 для генерации синусоиды. Эти доступные наборы для самостоятельного изготовления очень полезны для вас, чтобы понять, как конденсаторы могут работать с резисторами, чтобы контролировать время зарядки и разрядки, что
Как сделать интерактивную печать звуковой волны: 8 шагов (с изображениями)
Как сделать интерактивную печать звуковой волны: в этом уроке мы покажем вам, как сделать интерактивную печать звуковой волны в рамке изображения, чтобы вы могли одновременно видеть и слышать свою любимую песню! Когда прикоснешься к принту через стекло рамки, он сыграет сына