جدول المحتويات:

3 مراحل مولد موجة جيبية على أساس Arduino Due: 5 خطوات
3 مراحل مولد موجة جيبية على أساس Arduino Due: 5 خطوات

فيديو: 3 مراحل مولد موجة جيبية على أساس Arduino Due: 5 خطوات

فيديو: 3 مراحل مولد موجة جيبية على أساس Arduino Due: 5 خطوات
فيديو: كيف يعمل كاشف المعادن How does a metal detector work? 2024, يوليو
Anonim
3 مراحل مولد موجة جيبية على أساس Arduino Due
3 مراحل مولد موجة جيبية على أساس Arduino Due

الغرض من هذه المشاركة هو مساعدة شخص يحاول الاستفادة من أداء Due الأفضل + نقص المرجع + ورقة البيانات غير المفيدة.

هذا المشروع قادر على توليد ما يصل إلى 3 مراحل موجة جيبية @ 256 عينة / دورة بتكرار منخفض (<1 كيلو هرتز) و 16 عينة / دورة عند التكرار العالي (حتى 20 كيلو هرتز) ، وهو أمر جيد بما يكفي ليتم تنعيمه بواسطة LPFs البسيط و الإخراج يكاد يكون مثاليا.

لم يكن الملف المرفق هو إصداري النهائي لأنني أضفت بعض الميزات الإضافية ولكن جوهرها هو نفسه. لاحظ أن العينات / الدورة تم تعيينها أقل من البيان أعلاه.

نظرًا لتعظيم سعة وحدة المعالجة المركزية من خلال الطريقة الموضحة في الملف المرفق ، فقد استخدمت Arduino Uno كوحدة تحكم ، والتي تستخدم المقاطعة الخارجية لـ Arduino Due لتمرير قيمة التردد إلى Arduino Due. بالإضافة إلى التحكم في التردد ، يتحكم Arduino Uno أيضًا في السعة (من خلال مقياس الجهد الرقمي + OpAmp) بالإضافة إلى I / O - سيكون هناك مساحة كبيرة للعب بها.

الخطوة 1: إنشاء مصفوفة بيانات الجيب

نظرًا لأن الحساب في الوقت الفعلي يتطلب وحدة المعالجة المركزية (CPU) ، يلزم وجود مصفوفة بيانات جيبية للحصول على أداء أفضل

uint32_t sin768 PROGMEM =…. في حين x = [0: 5375]؛ y = 127 + 127 * (الخطيئة (2 * pi / 5376 / * أو البعض # الذي تفضله يعتمد على المتطلبات * /))

الخطوة 2: تمكين الإخراج المتوازي

على عكس Uno ، فإن الاستحقاق لها مرجع محدود. ومع ذلك ، من أجل توليد موجة جيبية ثلاثية الطور استنادًا إلى Arduino Uno ، أولاً وقبل كل شيء ، الأداء غير مقبول نظرًا لانخفاض MCLK (16 ميجاهرتز بينما يكون الاستحقاق 84 ميجاهرتز) ، ثانيًا ، يمكن أن ينتج GPIO الحد الأقصى لمخرجات المرحلة 2 وتحتاج إلى إضافية الدائرة التماثلية لإنتاج المرحلة الثالثة (C = -AB).

اعتمد تمكين GPIO في الغالب على المحاولة والتجربة + ورقة بيانات غير مفيدة لـ SAM3X

PIOC-> PIO_PER = 0xFFFFFFFE ؛ // PIO controller PIO قم بتمكين التسجيل (راجع p656 من ورقة بيانات ATMEL SAM3X) و https://arduino.cc/en/Hacking/PinMappingSAM3X وتم تمكين Arduino Due pin 33-41 و 44-51

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: تمكين المقاطعة

لتحقيق أقصى قدر من الأداء ، يجب أن يكون حمل وحدة المعالجة المركزية منخفضًا قدر الإمكان. ومع ذلك ، نظرًا للمراسلات غير 1to1 بين دبوس وحدة المعالجة المركزية ودبوس الاستحقاق ، فإن تشغيل البت ضروري.

يمكنك تحسين الخوارزمية بشكل أكبر ولكن الغرفة محدودة للغاية.

باطل TC7_Handler (باطل) {TC_GetStatus (TC2، 1) ؛

ر = عينات ٪ ؛ // استخدم 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 المقابل: pin 33-40 ، وبالتالي التحول إلى اليسار لرقم واحد

p_B = sin768 [phaseBInc] << 12 ؛ // راجع PIOC: PC12 إلى PC19 ، ودبوس Arduino Due المقابل: pin 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 بت = المرحلة أ (8 بت) | المرحلة ب | المرحلة ج

PIOC-> PIO_ODSR = p_A ؛ // سجل الإخراج = p_A

تي ++ ؛ }

الخطوة 4: R / 2R DAC

بناء 3x8bit R / 2R DAC ، الكثير من المرجع على google.

الخطوة 5: الكود الكامل

#define _BV (x) (1 << (x)) ؛ uint32_t sin768 PROGMEM = / * x = [0: 5375] ؛ ص = 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، freq، freqNew ؛ فاصل uint32_t ؛ عينات uint16_t ، محددة مسبقًا ؛ uint32_t t = 0 ؛

الإعداد باطل() {

// إعداد PIOC للإخراج المتوازي: يتم استخدام Arduino Due pin33-40 كإخراج المرحلة A بينما يعمل الدبوس 44-51 لإخراج المرحلة B

PIOC-> PIO_PER = 0xFFFFFFFE ؛ // PIO controller PIO تمكين التسجيل (راجع p656 من ورقة بيانات ATMEL SAM3X) و https://arduino.cc/en/Hacking/PinMappingSAM3X وتم تمكين Arduino Due pin 33-41 و 44-51

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 (/ * clock * / TC2، / * channel * / 1، TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1) ؛ // TC clock 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 ؛ // تهيئة التردد على أنه 60 هرتز مضبوط مسبقًا = 21 ؛ // زيادة فهرس الصفيف بمقدار 21 عينة = 256 ؛ // عينات الإخراج 256 / فاصل الدورة = 42000000 / (التكرار * العينات) ؛ // عدد المقاطعات TC_SetRC (TC2 ، 1 ، الفاصل الزمني) ؛ // بدء TC Serial.begin (9600) ؛ // لغرض الاختبار}

فحص باطل

{freqNew = 20000 ،

إذا (التكرار == التكرار الجديد) {} آخر

{freq = freqNew ؛

إذا (التكرار> 20000) {التكرار = 20000 ؛ / * أقصى تردد 20 كيلو هرتز * /} ؛

إذا (التكرار <1) {التكرار = 1 ؛ / * الحد الأدنى للتردد 1 هرتز * /} ؛

إذا (التكرار> 999) {الإعداد المسبق = 384 ؛ عينات = 14 ؛} / للتردد> = 1 كيلو هرتز ، 14 عينة لكل دورة

وإلا إذا (التكرار> 499) {الإعداد المسبق = 84 ؛ عينات = 64 ؛} // لـ 500 <= تردد 99) {ضبط مسبق = 42 ؛ عينات = 128 ؛} // لـ 100 هرتز <= التردد <500 هرتز ، 128 عينة / دورة

آخر {الإعداد المسبق = 21 ؛ عينات = 256 ؛} ؛ // للتردد <100 هرتز ، 256 عينة لكل دورة

الفاصل الزمني = 42000000 / (التكرار * العينات) ؛ ر = 0 ؛ TC_SetRC (TC2 ، 1 ، فاصل زمني) ؛ }}

حلقة فارغة() {

checkFreq () ؛ تأخير (100) ؛ }

باطل TC7_Handler (باطل)

{TC_GetStatus (TC2، 1) ،

ر = عينات ٪ ؛ // استخدم عينات t٪ لتجنب تجاوز طور tAInc = (مضبوط مسبقًا * t)٪ 5376 ؛ // استخدم٪ 5376 لتجنب تجاوز فهرس الصفيف

phaseBInc = (phaseAInc + 1792)٪ 5376 ؛

phaseCInc = (phaseAInc + 3584)٪ 5376 ؛

p_A = sin768 [phaseAInc] << 1 ؛ // الرجوع إلى PIOC: PC1 إلى PC8 ، ودبوس Arduino Due المقابل: pin 33-40 ، وبالتالي التحول إلى اليسار لرقم واحد

p_B = sin768 [phaseBInc] << 12 ؛ // راجع PIOC: PC12 إلى PC19 ، ودبوس Arduino Due المقابل: pin 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 بت = المرحلة أ (8 بت) | المرحلة ب | المرحلة C //Serial.println(p_A>>21 ، BIN) ؛ // PIOC-> PIO_ODSR = 0x37E00000 ؛

PIOC-> PIO_ODSR = p_A ؛ // سجل الإخراج = p_A t ++ ؛ }

موصى به: