İçindekiler:

Arduino'ya Dayalı 3 Fazlı Sinüs Jeneratörü Due: 5 Adım
Arduino'ya Dayalı 3 Fazlı Sinüs Jeneratörü Due: 5 Adım

Video: Arduino'ya Dayalı 3 Fazlı Sinüs Jeneratörü Due: 5 Adım

Video: Arduino'ya Dayalı 3 Fazlı Sinüs Jeneratörü Due: 5 Adım
Video: ELEKTRİK PARASI ÖDEMEYE SON, GÜNEŞ ENERJİ SİSTEMİYLE ELEKTRİK BEDAVA 2024, Temmuz
Anonim
Arduino Due Tabanlı 3 Fazlı Sinüs Jeneratörü
Arduino Due Tabanlı 3 Fazlı Sinüs Jeneratörü

Bu paylaşımın amacı, Due'nin daha yüksek performansından + referans eksikliği + yardımcı olmayan veri sayfasından yararlanmaya çalışan birine yardımcı olmaktır.

bu proje, basit LPF'ler ve çıktı neredeyse mükemmel.

ekli dosya benim son versiyonum değildi çünkü bazı ek özellikler ekledim ama çekirdek bununla aynı. Numunelerin/döngünün yukarıdaki ifadeden daha düşük ayarlandığına dikkat edin.

Ekteki dosyada gösterilen yaklaşımla CPU kapasitesi maksimize edildiğinden, kontrol ünitesi olarak Arduino Due'ın harici kesmesini kullanarak frekans değerini Arduino Due'a ileten bir Arduino Uno kullandım. Frekans kontrolüne ek olarak, Arduino Uno ayrıca genliği (dijital potansiyel ölçer + OpAmp aracılığıyla) ve ayrıca G/Ç'yi kontrol eder --- oynamak için çok fazla alan olacaktır.

Adım 1: Sinüs Veri Dizisi Oluşturun

Gerçek zamanlı hesaplama CPU gerektirdiğinden, daha iyi performans için bir sinüs veri dizisi gereklidir

uint32_t sin768 PROGMEM= ….while x=[0:5375]; y = 127+127*(sin(2*pi/5376/*veya tercih ettiğiniz bazı #, gereksinime bağlıdır*/))

Adım 2: Paralel Çıkışı Etkinleştirme

Uno'dan farklı olarak Due, sınırlı referansa sahiptir. Ancak Arduino Uno'ya dayalı 3 fazlı sinüs dalgası üretebilmek için, birincisi, düşük MCLK'si (Due 84MHz iken 16MHz iken) nedeniyle performans takdire şayan değildir. 3. fazı üretmek için analog devre (C=-AB).

GPIO etkinleştirmenin ardından, çoğunlukla SAM3X'in deneme ve deneme+yardımcı olmayan veri sayfasına dayanıyordu

PIOC->PIO_PER = 0xFFFFFFFE; //PIO controller PIO Enable register (ATMEL SAM3X veri sayfasının sayfa 656'sına bakın) ve https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 ve 44-51 etkinleştirildi

PIOC->PIO_OER = 0xFFFFFFFE; //PIO kontrolör çıkışı etkinleştirme kaydı, ATMEL SAM3X veri sayfasının p657'sine bakın PIOC->PIO_OSR = 0xFFFFFFFE; //PIO kontrolör çıkış durumu kaydı, ATMEL SAM3X veri sayfasının 658. sayfasına bakın

PIOC->PIO_OWER = 0xFFFFFFFE; //PIO çıktı yazma etkinleştirme kaydı, ATMEL SAM3X veri sayfasının p670'ine bakın

//PIOA->PIO_PDR = 0x30000000; //sigorta olarak isteğe bağlı, performansı etkilemiyor gibi görünüyor, dijital pin 10 hem PC29 hem de PA28'e bağlanır, dijital pin 4 hem PC29 hem de PA28'e bağlanır, burada PIOA #28 ve 29'u devre dışı bırakmak için

3. Adım: Kesintiyi Etkinleştirme

Performansını en üst düzeye çıkarmak için CPU yükü mümkün olduğunca düşük olmalıdır. Ancak CPU pini ile Due pini arasındaki 1'e 1 olmayan yazışmalar nedeniyle, bit işlemi gereklidir.

Algoritmayı daha da optimize edebilirsiniz ancak alan çok sınırlıdır.

void TC7_Handler(void){ TC_GetStatus(TC2, 1);

t = t%örnekler; // t'nin taşmasını önlemek için 'if' yerine t%samples kullanın

fazAInc = (ön ayar*t)%5376; //dizi indeksi taşmasını önlemek için %5376 kullan

fazBInc = (fazAInc+1792)%5376;

fazCInc = (fazAInc+3584)%5376;

p_A = sin768[fazAInc]<<1; // PIOC'ye bakın: PC1'den PC8'e, karşılık gelen Arduino Due pini: pin 33-40, dolayısıyla 1 basamak için sola kaydırma

p_B = sin768[fazBInc]<<12; // PIOC'ye bakın: PC12'den PC19'a, karşılık gelen Arduino Due pini: pin 51-44, dolayısıyla 12 basamak sola kaydır

p_C = sin768[fazCInc]; //faz C çıkışı PIOC kullanır: PC21, PC22, PC23, PC24, PC25, PC26, PC28 ve PC29, karşılık gelen Arduino Due pini: dijital pin: sırasıyla 9, 8, 7, 6, 5, 4, 3, 10

p_C2 = (p_C&B11000000)<<22; //bu PC28 ve PC29'u oluşturur

p_C3 = (p_C&B00111111)<<21; // bu PC21-PC26'yı oluşturur

p_C = p_C2|p_C3; // bu, C fazının paralel çıktısını üretir

p_A = p_A|p_B|p_C; //32 bit çıkış = faz A (8bit)|faz B|faz C

PIOC->PIO_ODSR = p_A; //çıktı kaydı =p_A

t++; }

Adım 4: R/2R DAC

3x8bit R/2R DAC oluşturun, google'da bir sürü referans.

Adım 5: Tam Kod

#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; //faz A faz B faz C değeri--çıktı sadece 8 bit olsa da, 32bit PIOC çıkışı ile kopyalanmak üzere yeni bir 32 bit değer üretmek için p_A ve p_B değeri çalıştırılacaktır

uint16_t fazAInc, fazBInc, fazCInc, freq, freqNew; uint32_t aralığı; uint16_t örnekleri, ön ayar; uint32_t t = 0;

geçersiz kurulum() {

//paralel çıkış PIOC kurulumu: Arduino Due pin33-40, faz A çıkışı olarak kullanılırken pin 44-51, faz B çıkışı için çalışır

PIOC->PIO_PER = 0xFFFFFFFE; //PIO controller PIO Enable register (ATMEL SAM3X veri sayfasının sayfa 656'sına bakın) ve https://arduino.cc/en/Hacking/PinMappingSAM3X, Arduino Due pin 33-41 ve 44-51 etkinleştirildi

PIOC->PIO_OER = 0xFFFFFFFE; //PIO kontrolör çıkışı kaydı etkinleştir, ATMEL SAM3X veri sayfasının 657. sayfasına bakın

PIOC->PIO_OSR = 0xFFFFFFFE; //PIO kontrolör çıkış durumu kaydı, ATMEL SAM3X veri sayfasının 658. sayfasına bakın

PIOC->PIO_OWER = 0xFFFFFFFE; //PIO çıktı yazma etkinleştirme kaydı, ATMEL SAM3X veri sayfasının p670'ine bakın

//PIOA->PIO_PDR = 0x30000000; //sigorta olarak isteğe bağlı, performansı etkilemiyor gibi görünüyor, dijital pin 10 hem PC29 hem de PA28'e bağlanır, dijital pin 4 hem PC29 hem de PA28'e bağlanır, burada PIOA #28 ve 29'u devre dışı bırakmak için //zamanlayıcı kurulumu, http'ye bakın://arduino.cc/en/Hacking/PinMappingSAM3X, pmc_set_writeprotect(yanlış); // Güç Yönetimi Kontrol kayıtlarının yazma korumasını devre dışı bırak

pmc_enable_periph_clk(ID_TC7); // çevresel saat zaman sayacını etkinleştir 7

TC_Configure(/* saat */TC2, /* kanal */1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1); //TC saati 42MHz (saat, kanal, karşılaştırma modu ayarı) TC_SetRC(TC2, 1, aralık); TC_Başlat(TC2, 1);

// zamanlayıcıda zamanlayıcı kesmelerini etkinleştir TC2->TC_CHANNEL[1]. TC_IER=TC_IER_CPCS; // IER = kesme etkinleştirme kaydı TC2->TC_CHANNEL[1]. TC_IDR=~TC_IER_CPCS; // IDR = kesme devre dışı kaydı

NVIC_EnableIRQ(TC7_IRQn); // İç içe vektör kesme denetleyicisinde kesmeyi etkinleştirin freq = 60; // frekansı 60Hz ön ayar olarak başlat = 21; //dizi indeksi 21 örnek artışı = 256; //çıktı örnekleri 256/döngü aralığı = 42000000/(sıklık*örnekler); //kesme sayıları TC_SetRC(TC2, 1, aralık); //TC Serial.begin(9600) başlat; //test amaçlı }

geçersiz kontrolFreq()

{ sıklıkYeni = 20000;

if (sıklık == sıklıkYeni) {} başka

{ sıklık = sıklıkYeni;

if (freq>20000) {freq = 20000; /*maksimum frekans 20kHz*/};

if (freq<1) {freq = 1; /*min frekans 1Hz*/};

if (freq>999) {ön ayar = 384; örnekler = 14;} //frekans >=1kHz için, her döngü için 14 örnek

else if (freq>499) {ön ayar = 84; örnekler = 64;} //500 için<=frekans99) {ön ayar = 42; örnekler = 128;} //100Hz için<=frekans<500Hz, 128 örnek/döngü

başka {ön ayar = 21; örnekler = 256;}; //frekans için<100hz, her döngü için 256 örnek

aralık = 42000000/(sıklık*örnekler); t = 0; TC_SetRC(TC2, 1, aralık); } }

boşluk döngüsü () {

kontrolFreq(); gecikme(100); }

geçersiz TC7_Handler(void)

{ TC_GetStatus(TC2, 1);

t = t%örnekler; //t%samples kullanarak t fazAInc = (preset*t)%5376; //dizi indeksi taşmasını önlemek için %5376 kullan

fazBInc = (fazAInc+1792)%5376;

fazCInc = (fazAInc+3584)%5376;

p_A = sin768[fazAInc]<<1; // PIOC'ye bakın: PC1'den PC8'e, karşılık gelen Arduino Due pini: pin 33-40, dolayısıyla 1 basamak için sola kaydırma

p_B = sin768[fazBInc]<<12; // PIOC'ye bakın: PC12'den PC19'a, karşılık gelen Arduino Due pini: pin 51-44, dolayısıyla 12 basamak sola kaydır

p_C = sin768[fazCInc]; //faz C çıkışı PIOC kullanır: PC21, PC22, PC23, PC24, PC25, PC26, PC28 ve PC29, karşılık gelen Arduino Due pini: dijital pin: sırasıyla 9, 8, 7, 6, 5, 4, 3, 10

p_C2 = (p_C&B11000000)<<22; //bu PC28 ve PC29'u oluşturur

p_C3 = (p_C&B00111111)<<21; //bu PC21-PC26'yı oluşturur //Serial.println(p_C3, BIN); p_C = p_C2|p_C3; // bu, C fazının paralel çıktısını üretir

p_A = p_A|p_B|p_C; //32 bit çıktı = faz A (8bit)|faz B|faz C //Serial.println(p_A>>21, BIN); //PIOC->PIO_ODSR = 0x37E00000;

PIOC->PIO_ODSR = p_A; //çıktı kaydı =p_A t++; }

Önerilen: