Мазмұны:

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

Бейне: Arduino Due негізіндегі 3 фазалы синусонды генератор: 5 қадам

Бейне: Arduino Due негізіндегі 3 фазалы синусонды генератор: 5 қадам
Бейне: Уроки Ардуино #0 - что такое Arduino, куда подключаются датчики и как питать Ардуино 2024, Қараша
Anonim
Arduino Due негізіндегі 3 фазалы синусоидалы генератор
Arduino Due негізіндегі 3 фазалы синусоидалы генератор

Бұл үлестің мақсаты-Дудың жоғары өнімділігін + анықтаманың болмауы + пайдалы емес деректер кестесін қолдануға тырысатын адамға көмектесу.

Бұл жоба төмен жиілікте (<1 кГц) 256 сынама / циклдегі 3 фазалық синусоиданы құруға қабілетті және жоғары жиілікте (20 кГц -ке дейін) 16 үлгі / циклде, бұл қарапайым LPF -пен тегістеуге жеткілікті жақсы. шығару дерлік мінсіз.

Қосылған файл менің соңғы нұсқам болмады, себебі мен кейбір қосымша мүмкіндіктерді қостым, бірақ ядро осыған ұқсас. Үлгілер/цикл жоғарыда көрсетілгеннен төмен орнатылғанын ескеріңіз.

процессордың сыйымдылығы қоса берілген файлда көрсетілген әдіс арқылы максималды болғандықтан, мен Arduino Due жиілік мәнін беру үшін Arduino Due сыртқы үзілісін қолданатын басқару блогы ретінде Arduino Uno қолдандым. Arduino Uno жиілікті басқарудан басқа амплитудасын (цифрлық потенциалды өлшеуіш + OpAmp арқылы) басқарады, сонымен қатар енгізу-шығару --- ойнауға көп орын болады.

1 -қадам: Деректер синусының массивін жасаңыз

Нақты уақыттағы есептеу процессорды қажет ететіндіктен, жақсы жұмыс істеу үшін синусты мәліметтер жиыны қажет

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 Регистрді қосу (ATMEL SAM3X деректер кестесінің p656 сілтемесін қараңыз) және https://arduino.cc/kz/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 түйреуіші мен 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 түйреуіші: PIN 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*пи/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, жиілік, жиілікNew; uint32_t аралығы; uint16_t үлгілері, алдын ала орнатылған; uint32_t t = 0;

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

// PIOC параллель шығысы: Arduino Due pin 33-40 А фазалық шығыс ретінде пайдаланылады, ал 44-51 түйреуіш В фазасы үшін жұмыс істейді

PIOC-> PIO_PER = 0xFFFFFFFE; // PIO контроллері PIO Регистрді қосу (ATMEL SAM3X деректер кестесінің p656 сілтемесін қараңыз) және https://arduino.cc/kz/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 өшіру үшін // таймерді орнатуды өшіру үшін http қараңыз.: //arduino.cc/kz/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/(жиілік*үлгілері); // үзіліс санауы TC_SetRC (TC2, 1, интервал); // іске қосу TC Serial.begin (9600); // тест мақсатында}

void checkFreq ()

{freqNew = 20000;

if (freq == freqNew) {} басқа

{freq = freqNew;

егер (жиілік> 20000) {жиілік = 20000; /*максималды жиілік 20 кГц*/};

егер (жиілік <1) {жиілік = 1; /*мин жиілігі 1Гц*/};

егер (жиілік> 999) {алдын ала орнатылған = 384; үлгілер = 14;} // жиілік үшін> = 1кГц, әрбір цикл үшін 14 үлгі

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

else {алдын ала орнатылған = 21; үлгілер = 256;}; // жиілігі <100Гц, әр цикл үшін 256 үлгі

интервал = 42000000/(жиілік*үлгілері); 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 түйреуіші: PIN 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 //Serial.println(p_C3, BIN) жасайды; p_C = p_C2 | p_C3; // бұл С фазасының параллель шығуын тудырады

p_A = p_A | p_B | p_C; // 32 биттік шығу = А фазасы (8 биттік) | В фазасы | С фазасы // Сериялық.println(p_A>>21, БСН); // PIOC-> PIO_ODSR = 0x37E00000;

PIOC-> PIO_ODSR = p_A; // шығыс регистрі = p_A t ++; }

Ұсынылған: