Съдържание:
- Стъпка 1: Генерирайте масив от данни за синусоида
- Стъпка 2: Активиране на паралелен изход
- Стъпка 3: Активиране на прекъсване
- Стъпка 4: R/2R DAC
- Стъпка 5: Пълен код
Видео: Трифазен генератор на синусоидални вълни, базиран на Arduino Due: 5 стъпки
2024 Автор: John Day | [email protected]. Последно модифициран: 2024-01-30 07:52
целта на този споделяне е да помогне на някой, който се опитва да използва по-голямата производителност на Due + липсата на справки + неполезни таблици с данни.
този проект е в състояние да генерира до 3 фази синусоидална вълна @ 256 проби / цикъл при ниски честоти (<1kHz) и 16 проби / цикъл при високи честоти (до 20kHz), което е достатъчно добро, за да бъде изгладено от прости LPF и изходът е почти перфектен.
прикаченият файл не беше последната ми версия, защото добавих допълнителна функция, но ядрото е същото. Обърнете внимание, че пробите/цикълът са зададени по -ниско от горното твърдение.
тъй като капацитетът на процесора е увеличен чрез подхода, показан в прикачения файл, използвах Arduino Uno като контролен блок, който използва външното прекъсване на Arduino Due, за да предаде стойността на честотата към Arduino Due. В допълнение към честотния контрол, Arduino Uno също така контролира амплитудата (чрез цифров потенциометър + OpAmp), както и I/O --- ще има много място за игра.
Стъпка 1: Генерирайте масив от данни за синусоида
Тъй като изчислението в реално време изисква CPU, за по-добра производителност е необходим масив от синусоидални данни
uint32_t sin768 ПРОГМЕТА = …. докато x = [0: 5375]; y = 127+127*(грех (2*pi/5376/*или някои #, които предпочитате, зависи от изискването*/))
Стъпка 2: Активиране на паралелен изход
За разлика от Uno, Due имат ограничени препратки. Въпреки това, за да се генерира 3 -фазова синусоида, базирана на Arduino Uno, първо, производителността не се аплодира поради ниската му MCLK (16MHz, докато Due е 84MHz), второ, това е ограничено GPIO може да произведе максимум 2 фазов изход и имате нужда от допълнителен аналогова верига за производство на 3-та фаза (C = -AB).
След активирането на GPIO се основаваше предимно на опити и проби+неполезни таблици с данни на SAM3X
PIOC-> PIO_PER = 0xFFFFFFFE; // PIO контролер Регистърът за активиране на PIO (вижте стр. 656 на листа с данни на ATMEL SAM3X) и https://arduino.cc/en/Hacking/PinMappingSAM3X, пин 33-41 и 44-51 на Arduino Due са активирани
PIOC-> PIO_OER = 0xFFFFFFFE; // Регистър за разрешаване на изхода на PIO контролер, вижте стр. 657 на листа с данни ATMEL SAM3X PIOC-> PIO_OSR = 0xFFFFFFFE; // Регистър на състоянието на изхода на PIO контролер, вижте стр. 658 от листа с данни ATMEL SAM3X
PIOC-> PIO_OWER = 0xFFFFFFFE; // Регистър за разрешаване на запис на изход PIO, вижте p670 на листа с данни ATMEL SAM3X
// PIOA-> PIO_PDR = 0x30000000; // по избор като застраховка, изглежда не влияе на производителността, цифров щифт 10 се свързва както с PC29, така и с PA28, цифров щифт 4 се свързва както с PC29, така и с PA28, тук за деактивиране на PIOA #28 & 29
Стъпка 3: Активиране на прекъсване
За да се постигне максимална производителност, натоварването на процесора трябва да бъде възможно най -ниско. Въпреки това, поради не-1to1 съответствие между пина на процесора и дължимия пин, операцията с битове е необходима.
Можете допълнително да оптимизирате алгоритъма, но мястото е много ограничено.
void TC7_Handler (void) {TC_GetStatus (TC2, 1);
t = t%проби; // използваме t%проби вместо „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 DAC
изградете 3x8bit R/2R DAC, много реф в google.
Стъпка 5: Пълен код
#define _BV (x) (1 << (x)); uint32_t sin768 ПРОГМЕТА = /* x = [0: 5375]; y = 127+127*(грех (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 интервал; uint16_t проби, предварително зададени; uint32_t t = 0;
void setup () {
// настройка на паралелен изход PIOC: Arduino Due щит 33-40 се използва като изход фаза А, докато щифт 44-51 работи за изход фаза В
PIOC-> PIO_PER = 0xFFFFFFFE; // PIO контролер Регистърът за активиране на PIO (вижте стр. 656 на листа с данни на ATMEL SAM3X) и https://arduino.cc/en/Hacking/PinMappingSAM3X, пин 33-41 и 44-51 на Arduino Due са активирани
PIOC-> PIO_OER = 0xFFFFFFFE; // Регистър за разрешаване на изхода на PIO контролер, вижте стр. 657 от листа с данни ATMEL SAM3X
PIOC-> PIO_OSR = 0xFFFFFFFE; // Регистър на състоянието на изхода на PIO контролер, вижте стр. 658 от листа с данни 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 часовник 42MHz (часовник, канал, настройка на режим за сравнение) TC_SetRC (TC2, 1, интервал); 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; // инициализираме честотата като 60Hz предварително зададена = 21; // увеличение на индекса на масива с 21 проби = 256; // изходни проби 256/интервал на цикъл = 42000000/(честотни*проби); // преброяване на прекъсвания TC_SetRC (TC2, 1, интервал); // стартиране на TC Serial.begin (9600); // за целите на теста}
void checkFreq ()
{freqNew = 20000;
if (freq == freqNew) {} иначе
{freq = freqNew;
ако (честота> 20000) {честота = 20000; /*максимална честота 20kHz*/};
ако (честота <1) {честота = 1; /*мин. честота 1Hz*/};
if (freq> 999) {preset = 384; проби = 14;} // за честота> = 1kHz, 14 проби за всеки цикъл
else if (freq> 499) {preset = 84; проби = 64;} // за 500 <= честота99) {предварително зададена = 42; проби = 128;} // за 100Hz <= честота <500Hz, 128 проби/цикъл
else {preset = 21; проби = 256;}; // за честота <100hz, 256 проби за всеки цикъл
интервал = 42000000/(честотни*проби); t = 0; TC_SetRC (TC2, 1, интервал); }}
void loop () {
checkFreq (); забавяне (100); }
void TC7_Handler (void)
{TC_GetStatus (TC2, 1);
t = t%проби; // използваме t%проби, за да избегнем препълването на 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 //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 ++; }
Препоръчано:
Wiggly Wobbly - Вижте Звуковите вълни !! Аудио визуализатор в реално време !!: 4 стъпки
Wiggly Wobbly - Вижте Звуковите вълни !! Аудио визуализатор в реално време !!: Чудили ли сте се как изглеждат песните на Beetle ?? Или просто искате да видите как изглежда звукът? Тогава не се притеснявайте, аз съм тук, за да ви помогна да го направите отново! Повдигнете високоговорителя си и се стремете към избледнелото
Ардуино генератор на вълни: 5 стъпки (със снимки)
Arduino Waveform Generator: Февруари 2021 актуализация: вижте новата версия с 300x честотата на дискретизация, базирана на Raspberry Pi Pico, В лабораторията често се нуждаете от повтарящ се сигнал с определена честота, форма и амплитуда. Възможно е да тествате усилвател, да проверите верига
Музикален генератор, базиран на времето (ESP8266 базиран midi генератор): 4 стъпки (със снимки)
Метеорологичен генератор, базиран на времето (ESP8266 базиран Midi генератор): Здравейте, днес ще ви обясня как да направите свой собствен малък музикален генератор, базиран на времето. Той е базиран на ESP8266, който е нещо като Arduino и реагира на температура, дъжд и интензивността на светлината. Не очаквайте това да прави цели песни или акорди
Процентно диференциално реле за защита на трифазен трансформатор: 7 стъпки
Процентно диференциално реле за защита на трифазен трансформатор: В тази инструкция ще ви покажа как да направите процентно диференциално реле, използвайки Arduino, което е много често срещана платка за микроконтролер. Силовият трансформатор е най -важното оборудване за пренос на енергия в електроенергийната система. Разходите за ремонт на да
Верига за задвижване на порта за трифазен инвертор: 9 стъпки
Верига за задвижване на порта за трифазен инвертор: Този проект е по същество схема на драйвер за оборудване, наречено SemiTeach, което наскоро купихме за нашия отдел. Показва се изображението на устройството. Свързването на тази верига на драйвера към 6 MOSFET генерира три 120 градуса изместени AC напрежения. Ра