Мазмуну:

3 фазалуу синус толкун генератору Arduino Due негизделген: 5 кадам
3 фазалуу синус толкун генератору Arduino Due негизделген: 5 кадам

Video: 3 фазалуу синус толкун генератору Arduino Due негизделген: 5 кадам

Video: 3 фазалуу синус толкун генератору Arduino Due негизделген: 5 кадам
Video: Стоит ли брать трёхфазный генератор? 2024, Ноябрь
Anonim
3 фазалуу синус толкун генератору Arduino Due негизинде
3 фазалуу синус толкун генератору Arduino Due негизинде

Бул үлүштүн максаты Due'дин көбүрөөк иштөөсүн + маалымдаманын жоктугун + пайдалуу эмес маалымат баракчасын колдонууга аракет кылып жаткан бирөөгө жардам берүү.

Бул проект 3 фазалуу синус толкуну @ 256 үлгүлөрдү / циклди төмөнкү жыштыкта (<1kHz) жана 16 үлгүлөрдү / циклде @ жогорку жыштыкта (20 кГцке чейин) түзө алат, бул жөнөкөй LPFлер жана тегиздөө үчүн жетиштүү. чыгаруу дээрлик идеалдуу.

тиркелген файл менин акыркы версиям эмес болчу, анткени мен кээ бир кошумча функцияларды коштум, бирок өзөгү буга окшош. Үлгү/цикл жогорудагы билдирүүдөн төмөн коюлганына көңүл буруңуз.

CPU кубаттуулугу тиркелген файлда көрсөтүлгөн ыкма аркылуу максималдаштырылгандыктан, мен Arduino Uno башкаруу бирдиги катары колдондум, ал Arduino Due жыштыгынын маанисин өткөрүп берүү үчүн Arduino Due тышкы үзгүлтүгүн колдонот. Жыштыкты контролдоодон тышкары, Arduino Uno амплитудасын да башкарат (санарип потенциал-метр + OpAmp аркылуу), ошондой эле I/O --- менен ойной турган көп орун болот.

1 -кадам: Sine маалыматтар массивин түзүү

Реалдуу убакытта эсептөө CPU талап кылгандыктан, жакшыраак иштөө үчүн синустук маалымат массиви талап кылынат

uint32_t sin768 PROGMEM =…. while x = [0: 5375]; y = 127+127*(күнөө (2*pi/5376/*же сиз каалаган # # талапка жараша болот//))

2 -кадам: Параллелдүү чыгарууну иштетүү

Unoдон айырмаланып, Due чектелген маалыматка ээ. Бирок, Arduino Uno негизинде 3 фазалуу синус толкунду жаратуу үчүн, биринчиден, MCLKнин төмөндүгүнөн (16 МГц, 84 МГц болгондо) аткаруу кол чабууга болбойт, экинчиден, чектелген GPIO 2 фазалуу өндүрүштү өндүрө алат жана сизге кошумча керек 3-фазаны өндүрүү үчүн аналогдук схема (C = -AB).

GPIO иштетүүдөн кийин, негизинен, SAM3X боюнча пайдалуу эмес, текшерүү жана сыноо негизделген

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO контроллери PIO Enable register (ATMEL SAM3X маалымат барагынын p656-на кайрылыңыз) жана https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 жана 44-51 иштетилген

PIOC-> PIO_OER = 0xFFFFFFFE; // PIO контроллеринин өндүрүмүн иштетүү реестри, ATMEL SAM3X маалымат барагынын p657 караңыз PIOC-> PIO_OSR = 0xFFFFFFFE; // PIO контроллеринин чыгуу статусунун реестри, ATMEL SAM3X маалымат барагынын p658ине кайрылыңыз

PIOC-> PIO_OWER = 0xFFFFFFFE; // PIO чыгаруу жазууну иштетүү реестри, ATMEL SAM3X маалымат барагынын p670ине кайрылыңыз

// PIOA-> PIO_PDR = 0x30000000; // камсыздандыруу катары милдеттүү эмес, өндүрүмдүүлүккө таасир этпейт окшойт, санарип пин 10 PC29 менен PA28ге туташат, санарип пин 4 PC29 менен PA28ге туташат, бул жерде PIOA #28 & 29 өчүрүү үчүн

3 -кадам: Үзгүлтүктү иштетүү

Анын аткарылышын максималдаштыруу үчүн, CPU жүктөмү мүмкүн болушунча аз болушу керек. Бирок CPU пини менен Due пиндин ортосундагы 1to1 эмес жазышуулардан улам, бит операциясы зарыл.

Алгоритмди андан ары оптималдаштырсаңыз болот, бирок бөлмө өтө чектелген.

жараксыз TC7_Handler (боштук) {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 байланыштуу пин: пин 33-40, демек солго 1 цифрага солго

p_B = sin768 [PhaseBInc] << 12; // PIOCко кайрылыңыз: PC12ден PC19га, тиешелүү Arduino байланыштуу пин: пин 51-44, демек солго 12 сан

p_C = sin768 [PhaseCInc]; // этап C чыгаруу PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 жана PC29, тиешелүү Arduino байланыштуу пин: санарип пин: 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; // бул С фазасынын параллелдүү чыгарылышын жаратат

p_A = p_A | p_B | p_C; // 32 бит чыгаруу = фаза А (8бит) | фаза В | фаза

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 PROGMEM = /* x = [0: 5375]; y = 127+127*(күнөө (2*pi/5376))*/

uint32_t p_A, p_B, p_C, p_C2, p_C3; // фаза А фазасы В фазасы С мааниси-чыгаруу 8 бит гана болсо да, p_A жана p_B мааниси 32 биттик PIOC чыгаруу менен күрөшүү үчүн жаңы 32 биттик маанини түзүү үчүн иштетилет.

uint16_t PhaseAInc, PhaseBInc, PhaseCInc, Freq, FreqNew; uint32_t интервал; uint16_t үлгүлөрү, алдын ала коюлган; uint32_t t = 0;

жараксыз орнотуу () {

// параллелдүү чыгаруу PIOC орнотуусу: Arduino Due pin33-40 фаза А чыгаруу катары колдонулат, ал эми pin 44-51 B фазасы үчүн иштейт

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO контроллери PIO иштетүү реестри (ATMEL SAM3X маалымат барагынын p656-на кайрылыңыз) жана https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due пин 33-41 жана 44-51 иштетилген

PIOC-> PIO_OER = 0xFFFFFFFE; // PIO контроллеринин чыгуусу регистрди иштетет, ATMEL SAM3X маалымат барагынын p657 -ге кайрылыңыз

PIOC-> PIO_OSR = 0xFFFFFFFE; // PIO контроллеринин чыгуу статусунун реестри, ATMEL SAM3X маалымат барагынын p658ине кайрылыңыз

PIOC-> PIO_OWER = 0xFFFFFFFE; // PIO чыгаруу жазууну иштетүү реестри, ATMEL SAM3X маалымат барагынын p670ине кайрылыңыз

// PIOA-> PIO_PDR = 0x30000000; // камсыздандыруу катары милдеттүү эмес, өндүрүмдүүлүккө таасир этпейт окшойт, санарип пин 10 PC29 менен PA28ге туташат, санариптик пин 4 PC29 менен PA28ге туташат, бул жерде PIOA #28 & 29ду өчүрүү үчүн таймерди орнотуу үчүн, httpге кайрылыңыз.: //arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect (жалган); // Power Management Control регистрлеринин жазууну коргоону өчүрүү

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 сааты 42МГц (саат, канал, режимди салыштыруу) 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; // жыштыгы 60 Гц алдын ала коюлган = 21 катары инициализациялоо; // массивдин индекси 21 үлгүгө көбөйөт = 256; // чыгаруу үлгүлөрү 256/цикл аралыгы = 42000000/(freq*үлгүлөрү); // үзгүлтүк санап TC_SetRC (TC2, 1, интервал); // баштоо TC Serial.begin (9600); // сыноо максатында}

void checkFreq ()

{freqNew = 20000;

if (freq == freqNew) {} башка

{freq = freqNew;

if (freq> 20000) {freq = 20000; /*максималдуу жыштыгы 20 кГц*/};

if (freq <1) {freq = 1; /*мүн жыштыгы 1Гц*/};

if (freq> 999) {алдын ала коюлган = 384; үлгүлөр = 14;} // жыштык үчүн> = 1кГц, ар бир цикл үчүн 14 үлгү

else if (freq> 499) {preset = 84; үлгүлөр = 64;} // 500 үчүн <= жыштык99) {алдын ала коюлган = 42; үлгүлөр = 128;} // 100Гц үчүн <= жыштыгы <500Гц, 128 үлгү/цикл

else {preset = 21; үлгүлөр = 256;}; // жыштык үчүн <100Гц, ар бир цикл үчүн 256 үлгү

интервал = 42000000/(freq*үлгүлөрү); t = 0; TC_SetRC (TC2, 1, интервал); }}

void loop () {

checkFreq (); кечиктирүү (100); }

жараксыз TC7_Handler (жараксыз)

{TC_GetStatus (TC2, 1);

t = t%үлгүлөрү; // t fazAInc = (алдын ала орнотулган*t)%5376 алдын алуу үчүн t%үлгүлөрүн колдонуңуз; // массивдин индексинин толуп кетпеши үчүн %5376 колдонуңуз

PhaseBInc = (PhaseAInc+1792)%5376;

PhaseCInc = (PhaseAInc+3584)%5376;

p_A = sin768 [PhaseAInc] << 1; // PIOCко кайрылыңыз: PC1ден PC8ге, тиешелүү Arduino байланыштуу пин: пин 33-40, демек солго 1 цифрага солго

p_B = sin768 [PhaseBInc] << 12; // PIOCко кайрылыңыз: PC12ден PC19га, тиешелүү Arduino байланыштуу пин: пин 51-44, демек солго 12 сан

p_C = sin768 [PhaseCInc]; // фаза С чыгаруу PIOC: PC21, PC22, PC23, PC24, PC25, PC26, PC28 жана PC29, тиешелүү Arduino байланыштуу пин: санариптик пин: 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; // бул С фазасынын параллелдүү чыгарылышын жаратат

p_A = p_A | p_B | p_C; // 32 бит чыгаруу = фаза А (8бит) | фаза В | фаза C //Serial.println(p_A>>21, БИН); // PIOC-> PIO_ODSR = 0x37E00000;

PIOC-> PIO_ODSR = p_A; // чыгаруу реестри = p_A t ++; }

Сунушталууда: