- ما هو مولد وظيفة DDS؟
- فهم طريقة عمل مولد وظيفة AD9833 IC
- المكونات المطلوبة لبناء مولد الوظيفة القائم على AD9833
- مولد دالة قائم على AD9833 - رسم تخطيطي
- مولد الوظيفة القائم على AD9833 - كود اردوينو
- اختبار مولد الوظيفة القائم على AD9833
- مزيد من التحسينات
إذا كنت من المتحمسين للإلكترونيات مثلي الذين يرغبون في إجراء تعديلات على الدوائر الإلكترونية المختلفة ، فإن وجود مولد وظيفة لائق يصبح أحيانًا إلزاميًا. لكن امتلاك واحدة يمثل مشكلة لأن مثل هذه المعدات الأساسية يمكن أن تكلف ثروة. إن بناء معدات الاختبار الخاصة بك ليس أرخص فقط ولكنه طريقة رائعة لتحسين معرفتك.
لذلك في هذه المقالة ، سنقوم ببناء مولد إشارة بسيط مع Arduino و AD9833 DDS Function Generator Module والتي يمكن أن تنتج موجات جيبية ومربعة ومثلثة بتردد أقصى يبلغ 12 ميجا هرتز عند الإخراج. وأخيرًا ، سنختبر تردد الخرج بمساعدة راسم الذبذبات.
لقد قمنا سابقًا ببناء مولد موجة جيبية بسيطة ، ومولد موجة مربعة ، ومولد موجة مثلثية بمساعدة الدوائر التناظرية الأساسية. يمكنك التحقق من ذلك إذا كنت تبحث عن بعض دوائر مولد الموجي الأساسية. أيضًا ، إذا كنت ترغب في إنشاء مولد وظيفة Arduino أرخص بدون استخدام وحدة AD9833 ، فيمكنك التحقق من مشروع DIY Arduino Waveform Generator Project.
ما هو مولد وظيفة DDS؟
كما يوحي الاسم ، فإن مولد الوظيفة هو جهاز يمكنه إخراج شكل موجة معين بتردد معين عند الإعداد. على سبيل المثال ، ضع في اعتبارك أن لديك مرشح LC الذي تريد اختبار استجابة تردد الخرج من أجله ، يمكنك القيام بذلك بسهولة بمساعدة مولد الوظيفة. كل ما عليك فعله هو ضبط تردد الإخراج وشكل الموجة المطلوبين ، ثم يمكنك تحريكه لأسفل أو لأعلى من أجل اختبار الاستجابة. كان هذا مجرد مثال واحد ، يمكنك فعل المزيد من الأشياء باستخدامه مع استمرار القائمة.
DDS تعني التوليف الرقمي المباشر. إنه نوع من مولدات الموجات التي تستخدم المحولات الرقمية إلى التناظرية (DAC) لبناء إشارة من الألف إلى الياء. تُستخدم هذه الطريقة على وجه التحديد لتوليد موجة جيبية. لكن IC الذي نستخدمه يمكنه إنتاج إشارات موجة مربعة أو مثلثة. العمليات التي تحدث داخل شريحة DDS رقمية لذا يمكنها تبديل التردد بسرعة كبيرة أو يمكن التبديل من إشارة إلى أخرى بسرعة كبيرة. يتمتع هذا الجهاز بدقة تردد جيدة مع طيف تردد واسع.
فهم طريقة عمل مولد وظيفة AD9833 IC
في قلب مشروعنا يوجد AD9833 Programmable Waveform Generator IC الذي تم تصميمه وتطويره بواسطة الأجهزة التناظرية. وهو أدنى مستوى السلطة، برمجة الموجي مولد قادرة على إنتاج جيب ، الثلاثي ، و مربع مع موجة تردد أقصاها 12 ميغاهرتز. إنه IC فريد للغاية قادر على تغيير تردد الإخراج والمرحلة باستخدام برنامج فقط. يحتوي على واجهة SPI 3 أسلاك ، وهذا هو السبب في أن الاتصال بهذا IC أصبح بسيطًا وسهلاً للغاية. يظهر الرسم التخطيطي الوظيفي لهذا IC أدناه.
عمل هذا IC بسيط للغاية. إذا ألقينا نظرة على مخطط الكتلة الوظيفية أعلاه ، فسنلاحظ أن لدينا تراكم الطور الذي تتمثل مهمته في تخزين جميع القيم الرقمية الممكنة لموجة جيبية ، بدءًا من 0 إلى 2π. بعد ذلك ، لدينا ROM SIN الذي تتمثل مهمته في تحويل معلومات المرحلة التي يمكن تعيينها لاحقًا مباشرة إلى السعة. يستخدم SIN ROM معلومات المرحلة الرقمية كعنوان لجدول بحث وتحويل معلومات المرحلة إلى سعة. وأخيرًا ، لدينا محول رقمي إلى تناظري بحجم 10 بت تتمثل مهمته في استقبال البيانات الرقمية من SIN ROM وتحويلها إلى الفولتية التناظرية المقابلة ، وهذا ما نحصل عليه من الإخراج. عند الإخراج ، لدينا أيضًا مفتاح يمكننا تشغيله أو إيقاف تشغيله باستخدام رمز برنامج صغير. سنتحدث عن ذلك لاحقًا في المقالة.التفاصيل التي تراها أعلاه هي نسخة مجردة جدًا مما يحدث داخل IC ، ومعظم التفاصيل التي تراها أعلاه مأخوذة من ورقة بيانات AD9833 ، يمكنك أيضًا التحقق منها للحصول على مزيد من المعلومات.
المكونات المطلوبة لبناء مولد الوظيفة القائم على AD9833
تم سرد المكونات المطلوبة لبناء مولد الوظيفة القائم على AD9833 أدناه ، لقد صممنا هذه الدائرة بمكونات عامة جدًا ، مما يجعل عملية النسخ المتماثل سهلة للغاية.
- اردوينو نانو - 1
- مولد وظيفة AD9833 DDS - 1
- شاشة OLED 128 × 64 - 1
- جهاز التشفير الدوراني العام - 1
- جاك برميل DC - 1
- منظم الجهد LM7809 - 1
- 470 فائق التوهج مكثف - 1
- 220 فائق التوهج مكثف - 1
- 104pF مكثف - 1
- 10 كيلو المقاوم - 6
- مفاتيح اللمس - 4
- المسمار الطرفي 5.04 مم - 1
- رأس أنثى - 1
- مصدر طاقة 12 فولت - 1
مولد دالة قائم على AD9833 - رسم تخطيطي
يظهر أدناه مخطط الدائرة الكاملة لمولد الوظائف القائم على AD9833 و Arduino.
سنستخدم AD9833 مع Arduino لتوليد التردد المطلوب. وفي هذا القسم ، سنشرح كل التفاصيل بمساعدة التخطيطي ؛ اسمحوا لي أن أقدم لكم لمحة موجزة عن ما يحدث مع الدائرة. لنبدأ بوحدة AD9833. وحدة AD9833 هي وحدة مولد الوظيفة وهي متصلة بـ Arduino وفقًا للتخطيط. لتشغيل الدائرة ، نستخدم IC منظم الجهد LM7809 ، مع مكثف فصل مناسب ، وهذا ضروري لأن ضوضاء الإمداد يمكن أن تتداخل مع إشارة الخرج مما يؤدي إلى خرج غير مرغوب فيه. كما هو الحال دائمًا ، يعمل Arduino كعقل لهذا المشروع. لعرض التردد المحدد والمعلومات القيمة الأخرى ، قمنا بتوصيل وحدة عرض 128 X 64 OLED. لتغيير نطاق التردد ، نستخدم ثلاثة مفاتيح. الأول يضبط التردد على Hz ، والثاني يضبط تردد الخرج على KHz ، والثالث يضبط التردد على MHz ، ولدينا أيضًا زر آخر يمكن استخدامه لتمكين أو تعطيل الإخراج. أخيرًا ، لدينا جهاز التشفير الدوار ،وعلينا إرفاق بعض المقاوم للسحب به وإلا فلن تعمل هذه المفاتيح لأننا نتحقق من حدث الضغط على الزر في طريقة التجميع. يستخدم المشفر الدوار لتغيير التردد ويتم استخدام المفتاح اللمسي داخل المشفر الدوار لتحديد شكل الموجة المحدد.
مولد الوظيفة القائم على AD9833 - كود اردوينو
يمكن العثور على الكود الكامل المستخدم في هذا المشروع في أسفل هذه الصفحة. بعد إضافة ملفات الرأس وملفات المصدر المطلوبة ، يجب أن تكون قادرًا على ترجمة ملف Arduino مباشرةً. يمكنك تنزيل مكتبة أردوينو ad9833 والمكتبات الأخرى من الرابط أدناه وإلا يمكنك استخدام طريقة مدير اللوحة لتثبيت المكتبة.
- تحميل مكتبة AD9833 بواسطة بيل ويليامز
- قم بتنزيل مكتبة SSD1306 OLED من Adafruit
- قم بتنزيل مكتبة Adafruit GFX
شرح الكود في ino. الملف على النحو التالي. أولاً ، نبدأ بتضمين جميع المكتبات المطلوبة. تتبع مكتبة وحدة AD9833 DDS أولاً مكتبة OLED ومكتبة الرياضيات مطلوبة لبعض حساباتنا.
# تضمين // LIbrary for AD9833 Module # include
بعد ذلك ، نحدد جميع دبابيس الإدخال والإخراج اللازمة للأزرار والتبديل والتشفير الدوار و OLEDs.
#define SCREEN_WIDATA_PINH 128 // OLED display العرض بالبكسل #define SCREEN_HEIGHT 64 // OLED display height، by pixels #define SET_FREQUENCY_HZ A2 // Pushbutton To Set Frequency in Hz #define SET_FREQUENCY_KHZD # PushbuttonCY_KHZ A6 // Pushbutton لضبط التردد بالميجاهرتز # تعريف ENABLE_DISABLE_OUTPUT_PIN A7 // Pushbutton لتمكين / تعطيل الإخراج # تعريف FNC_PIN 4 // Fsync مطلوب بواسطة وحدة AD9833 # تعريف CLK_PIN 8 // Clock Pin of the Encoder #PIN / DATA / دبوس البيانات في جهاز التشفير #define BTN_PIN 9 // زر الضغط الداخلي في جهاز التشفير
بعد ذلك ، نحدد جميع المتغيرات الضرورية المطلوبة في هذا الكود. أولا، نحن تعريف متغير صحيح مضادة من شأنها أن تخزين قيمة التشفير الدوارة. المتغيرين التاليين clockPin و clockPinState يخزنان تمثال الدبوس المطلوب لفهم اتجاه المشفر. لدينا متغير زمني يحتفظ بقيم عداد المؤقت الحالية ، ويستخدم هذا المتغير لخفض الأزرار. بعد ذلك ، لدينا وحدة نمطية متغيرة طويلة غير موقعة تحمل التردد المحسوب الذي سيتم تطبيقه. بعد ذلك ، لدينا تأخير السداد. يمكن تعديل هذا التأخير حسب الحاجة. بعد ذلك ، لدينا ثلاثة متغيرات منطقية set_frequency_hz ،set_frequency_Khz و set_frequency_Mhz تُستخدم هذه المتغيرات الثلاثة لتحديد الإعداد الحالي للوحدة. سنتحدث عنها بمزيد من التفصيل لاحقًا في المقالة. بعد ذلك ، لدينا المتغير الذي يخزن حالة شكل الموجة الناتج ، وشكل موجة الإخراج الافتراضي هو موجة جيبية. وأخيرًا ، لدينا متغير encoder_btn_count الذي يحتوي على عدد زر التشفير المستخدم لتعيين شكل الموجة الناتج.
عداد int = 1 ؛ // ستزيد قيمة العداد هذه أو تنقص إذا تم تشغيل المشفر الدوار في clockPin ؛ // عنصر نائب لحالة الدبوس المستخدمة بواسطة المشفر الدوار int clockPinState ؛ // عنصر نائب لحالة الدبوس التي يستخدمها المشفر الدوار بدون توقيع وقت طويل = 0 ؛ // تستخدم للتخلص من تردد الوحدة النمطية الطويلة غير الموقعة ؛ // تستخدم لضبط debounce طويل التردد الناتج = 220 ؛ // Debounce delay bool btn_state ؛ // المستخدمة لتمكين إخراج تعطيل وحدة AD98333 bool set_frequency_hz = 1 ؛ // التردد الافتراضي لوحدة AD9833 bool set_frequency_khz ؛ bool set_frequency_mhz ؛ سلسلة waveSelect = "SIN" ؛ // شكل موجة بدء تشغيل الوحدة النمطية int encoder_btn_count = 0 ؛ // تستخدم للتحقق من زر التشفير ، اضغط على التالي ، لدينا كائنان لدينا أحدهما لشاشة OLED والآخر مخصص للوحدة النمطية AD9833.عرض Adafruit_SSD1306 (SCREEN_WIDATA_PINH ، SCREEN_HEIGHT ، & Wire ، -1) ؛ AD9833 gen (FNC_PIN) ؛
بعد ذلك ، لدينا وظيفة الإعداد () الخاصة بنا ، في وظيفة الإعداد هذه ، نبدأ بتمكين المسلسل من أجل التصحيح. نقوم بتهيئة الوحدة النمطية AD9833 بمساعدة طريقة start (). بعد ذلك ، قمنا بتعيين جميع دبابيس التشفير الدوارة المعينة كمدخلات. ونقوم بتخزين قيمة دبوس الساعة في متغير clockPinState ، فهذه خطوة ضرورية للتشفير الدوار.
بعد ذلك ، قمنا بتعيين جميع دبابيس الأزرار كمدخلات وتمكين شاشة OLED بمساعدة طريقة display.begin () ، ونتحقق أيضًا من وجود أي أخطاء في عبارة if . عند الانتهاء من ذلك ، نقوم بمسح الشاشة وطباعة شاشة بدء التشغيل ، ونضيف تأخيرًا لمدة ثانيتين وهو أيضًا تأخير شاشة البداية ، وأخيرًا ، نسمي وظيفة update_display () التي تمسح الشاشة وتقوم بتحديث عرض مرة أخرى. ستتم مناقشة تفاصيل طريقة update_display () لاحقًا في المقالة.
إعداد باطل () {Serial.begin (9600) ؛ // Enable Serial @ 9600 baud gen.Begin () ؛ // يجب أن يكون هذا هو الأمر الأول بعد التصريح عن وضع pinMode للكائن AD9833 (CLK_PIN ، INPUT) ؛ // إعداد الدبابيس كوضع إدخال pinMode (DATA_PIN ، INPUT) ؛ pinMode (BTN_PIN ، INPUT_PULLUP) ، clockPinState = digitalRead (CLK_PIN) ، pinMode (SET_FREQUENCY_HZ ، INPUT) ؛ // إعداد الدبابيس مثل إدخال pinMode (SET_FREQUENCY_KHZ ، INPUT) ؛ pinMode (SET_FREQUENCY_MHZ ، INPUT) ، pinMode (ENABLE_DISABLE_OUTPUT_PIN ، INPUT) ؛ if (! display.begin (SSD1306_SWITCHCAPVCC، 0x3C)) {// العنوان 0x3D لـ 128x64 Serial.println (F ("فشل تخصيص SSD1306")) ؛ إلى عن على (؛؛)؛ } display.clearDisplay ()؛ // مسح شاشة العرض. setTextSize (2) ؛ // تعيين حجم النص display.setTextColor (WHITE) ؛ // تعيين شاشة ملونة LCD.setCursor (30 ، 0) ؛ // تعيين موضع المؤشر display.println ("AD9833") ؛ // اطبع عرض النص هذا.setCursor (17 ، 20) ؛ // تعيين موضع المؤشر display.println ("الوظيفة") ؛ // اطبع عرض النص هذا. setCursor (13 ، 40) ؛ // تعيين موضع المؤشر display.println ("المولد") ؛ // طباعة عرض النص هذا. display () ؛ // تحديث تأخير العرض (2000) ؛ // تأخير 2 ثانية update_display () ؛ // Call update_display Function}
بعد ذلك ، لدينا وظيفة الحلقة () الخاصة بنا ، تتم كتابة جميع الوظائف الرئيسية في قسم الحلقة.
أولاً ، قرأنا دبوس الساعة الخاص بمشفر الروتاري وقمنا بتخزينه في متغير clockPin الذي أعلناه سابقًا. بعد ذلك ، في عبارة if ، نتحقق مما إذا كانت القيمة السابقة للرقم السري والقيمة الحالية للرقم السري متشابهة أم لا ، ونتحقق أيضًا من القيمة الحالية للرقم السري. إذا كان كل شيء صحيحا، وتحقق للدبوس البيانات، إذا كان صحيحا أن وسائل التشفير تدور عكس عقارب الساعة ، ونحن إنقاص قيمة العداد بمساعدة counter-- الأوامر. وإلا فإننا نزيد قيمة العداد باستخدام الأمر counter ++. أخيرًا ، وضعنا عبارة if أخرى لتعيين الحد الأدنى للقيمة على 1. بعد ذلك ، نقوم بتحديث clockPinState باستخدام clockPin الحاليقيمة للاستخدام في المستقبل.
حلقة باطلة () {clockPin = digitalRead (CLK_PIN) ؛ إذا (clockPin! = clockPinState && clockPin == 1) {if (digitalRead (DATA_PIN)! = clockPin) {counter -؛ } else {counter ++؛ // Encoder يقوم بتدوير CW so increment} if (counter <1) counter = 1؛ Serial.println (عداد) ؛ update_display () ، }
بعد ذلك ، لدينا الكود الخاص بنا لاكتشاف الضغط على الزر. في هذا القسم ، اكتشفنا الزر الموجود داخل المشفر بمساعدة بعض عبارات if المتداخلة ، إذا كان (digitalRead (BTN_PIN) == LOW && millis () - time> denounce) ، في هذا البيان ، نتحقق أولاً مما إذا كان الزر دبوس منخفض أم لا ، إذا كان منخفضًا ، يتم الضغط عليه. ثم نتحقق مرة أخرى من قيمة المؤقت مع تأخير Debounce ، إذا كانت كلتا العبارتين صحيحة ، فإننا نعلن أنه إجراء ضغط زر ناجح إذا قمنا بزيادة قيمة encoder_btn_count. بعد ذلك ، نعلن عبارة if أخرى لتعيين قيمة العداد القصوى على 2 ، نحتاجها لأننا نستخدمها لضبط شكل الموجة الناتج.عبارات if الثلاثة المتتالية تفعل ذلك ، إذا كانت القيمة صفر ، يتم تحديد شكل موجة جيبية ، إذا كانت واحدة ، فهي موجة مربعة ، وإذا كانت القيمة 2 ، فهي موجة مثلثة. في جميع عبارات if الثلاثة هذه ، نقوم بتحديث العرض بوظيفة update_display () . وأخيرًا ، نقوم بتحديث متغير الوقت بقيمة عداد المؤقت الحالية.
// إذا اكتشفنا إشارة منخفضة ، فسيتم الضغط على الزر إذا (digitalRead (BTN_PIN) == LOW && millis () - time> debounce) {encoder_btn_count ++؛ // قم بزيادة القيم إذا (encoder_btn_count> 2) // إذا كانت القيمة أكبر من 2 أعد تعيينها إلى 0 {encoder_btn_count = 0 ؛ } إذا (encoder_btn_count == 0) {// إذا كانت القيمة 0 تم تحديد موجة جيبية waveSelect = "SIN" ؛ // تحديث متغير السلسلة بقيمة sin update_display () ؛ // تحديث العرض} إذا (encoder_btn_count == 1) {// إذا كانت القيمة 1 موجة مربعة محددة waveSelect = "SQR" ؛ // تحديث متغير السلسلة بقيمة SQR update_display () ؛ // قم بتحديث العرض} إذا (encoder_btn_count == 2) {// إذا كانت القيمة هي 1 موجة مثلثة محددة waveSelect = "TRI" ؛ // تحديث متغير السلسلة بقيمة TRI update_display () ؛// update the display} time = millis () ؛ // تحديث متغير الوقت}
بعد ذلك ، نحدد جميع الكودات الضرورية المطلوبة لإعداد جميع الأزرار مع تأخير الإلغاء. نظرًا لأن الأزرار متصلة بالدبابيس التناظرية في Arduino ، فإننا نستخدم أمر القراءة التناظرية لتحديد الضغط على الزر إذا كانت قيمة القراءة التناظرية أقل من 30 ، ثم نكتشف ضغط الزر الناجح ، وننتظر 200 مللي ثانية حتى تحقق مما إذا كان ضغط زر فعليًا أم ضجيجًا فقط. إذا كانت هذه العبارة صحيحة ، فسنقوم بتعيين المتغيرات المنطقية مع القيم المستخدمة لتعيين قيم Hz و Khz و Mhz لمولد الوظيفة. بعد ذلك ، نقوم بتحديث العرض وتحديث متغير الوقت. نقوم بذلك لجميع الأزرار الأربعة المتصلة بـ Arduino.
إذا (analogRead (SET_FREQUENCY_HZ) <30 && millis () - time> debounce) {set_frequency_hz = 1 ؛ // تحديث القيم المنطقية set_frequency_khz = 0 ؛ set_frequency_mhz = 0 ؛ update_display ()؛ // تحديث وقت العرض = millis ()؛ // تحديث متغير الوقت} إذا (analogRead (SET_FREQUENCY_KHZ) <30 && millis () - time> debounce) {set_frequency_hz = 0 ؛ // تحديث القيم المنطقية set_frequency_khz = 1 ؛ set_frequency_mhz = 0 ؛ وحدة التردد = عداد * 1000 ؛ update_display ()؛ // قم بتحديث وقت العرض = millis ()؛ // تحديث متغير الوقت} if (analogRead (SET_FREQUENCY_MHZ) <30 && millis () - time> debounce) {// تحقق من الدبوس التناظري مع تأخير التصحيح set_frequency_hz = 0 ؛ // تحديث القيم المنطقية set_frequency_khz = 0 ؛ set_frequency_mhz = 1 ؛ وحدة التردد = عداد * 1000000 ؛ update_display () ،// update the display time = millis ()؛ // تحديث متغير الوقت} إذا (analogRead (ENABLE_DISABLE_OUTPUT_PIN) <30 && millis () - time> debounce) {// check analog pin with debounce delay btn_state =! btn_state ؛ // عكس حالة الزر gen.EnableOutput (btn_state) ؛ // تمكين / تعطيل إخراج منشئ الوظيفة اعتمادًا على حالة الزر update_display () ؛ // تحديث وقت العرض = مللي () ؛ // تحديث متغير الوقت}}// تحديث متغير الوقت}}// تحديث متغير الوقت}}
أخيرًا ، لدينا وظيفة update_display () الخاصة بنا. في هذه الوظيفة ، فعلنا أكثر من مجرد تحديث هذه الشاشة لأنه لا يمكن تحديث جزء معين من الشاشة في OLED. لتحديثه ، عليك إعادة رسمه بقيم جديدة. هذا يجعل عملية الترميز أكثر صعوبة.
داخل هذه الوظيفة ، نبدأ بمسح الشاشة. بعد ذلك ، قمنا بتعيين حجم النص المطلوب. بعد ذلك ، قمنا بتعيين المؤشر ومولد الوظيفة المطبوع مع display.println ("وظيفة الوظيفة") ؛ أمر. قمنا مرة أخرى بتعيين حجم النص على 2 ، والمؤشر على (0،20) بمساعدة وظيفة display.setCursor (0 ، 20).
هذا هو المكان الذي نطبع فيه المعلومات الخاصة بالموجة.
display.clearDisplay () ، // أولاً امسح شاشة العرض.setTextSize (1) ؛ // تعيين حجم النص display.setCursor (10 ، 0) ؛ // تعيين عرض موضع المؤشر. println ("مولد الوظيفة") ؛ // طباعة عرض النص. setTextSize (2) ؛ // ضبط حجم النص المعروض. setCursor (0 ، 20) ؛ // تعيين موضع المؤشر
بعد ذلك ، نتحقق من المتغيرات المنطقية للحصول على تفاصيل التردد وتحديث القيمة في متغير moduleFrequency. نقوم بذلك لقيم Hz و kHz و MHz. بعد ذلك ، نتحقق من متغير waveSelect وتحديد الموجة المحددة. الآن ، لدينا القيم لضبط نوع الموجة والتردد.
if (set_frequency_hz == 1 && set_frequency_khz == 0 && set_frequency_mhz == 0) {// تحقق مما إذا كان الزر لضبط التردد بالهرتز مضغوط moduleFrequency = counter؛ // قم بتحديث متغير moduleFrequency بقيمة العداد الحالية} إذا كان (set_frequency_hz == 0 && set_frequency_khz == 1 && set_frequency_mhz == 0) {// تحقق مما إذا كان الزر الخاص بضبط التردد بالكيلو هرتز تم الضغط عليه moduleFrequency = counter * 1000؛ // قم بتحديث متغير moduleFrequency بقيمة العداد الحالية ولكننا نضرب 1000 لضبطه على KHZ} إذا كان (set_frequency_hz == 0 && set_frequency_khz == 0 && set_frequency_mhz == 1) {// تحقق مما إذا كان زر ضبط التردد بالميجاهرتز مضغوطًا على الوحدة النمطية = العداد * 1000000 ؛ إذا (moduleFrequency> 12000000) {moduleFrequency = 12000000 ؛// لا تدع التردد يكون مبشرة بأن عداد 12 ميجا هرتز = 12 ؛ }} إذا (waveSelect == "SIN") {// تم تحديد موجة جيبية display.println ("SIN") ؛ gen.ApplySignal (SINE_WAVE ، REG0 ، moduleFrequency) ؛ Serial.println (moduleFrequency) ؛ } إذا (waveSelect == "SQR") {// تم تحديد موجة Sqr display.println ("SQR") ؛ gen.ApplySignal (SQUARE_WAVE، REG0، moduleFrequency) ؛ Serial.println (moduleFrequency) ؛ } إذا (waveSelect == "TRI") {// تم تحديد Tri wave display.println ("TRI") ؛ gen.ApplySignal (TRIANGLE_WAVE، REG0، moduleFrequency) ؛ // تحديث وحدة AD9833. Serial.println (moduleFrequency) ؛ }} إذا (waveSelect == "SQR") {// تم تحديد موجة Sqr display.println ("SQR") ؛ gen.ApplySignal (SQUARE_WAVE، REG0، moduleFrequency) ؛ Serial.println (moduleFrequency) ؛ } إذا (waveSelect == "TRI") {// تم تحديد Tri wave display.println ("TRI") ؛ gen.ApplySignal (TRIANGLE_WAVE، REG0، moduleFrequency) ؛ // تحديث وحدة AD9833. Serial.println (moduleFrequency) ؛ }} إذا تم تحديد (waveSelect == "SQR") {// Sqr wave display.println ("SQR") ؛ gen.ApplySignal (SQUARE_WAVE، REG0، moduleFrequency) ؛ Serial.println (moduleFrequency) ؛ } إذا (waveSelect == "TRI") {// تم تحديد Tri wave display.println ("TRI") ؛ gen.ApplySignal (TRIANGLE_WAVE، REG0، moduleFrequency) ؛ // تحديث وحدة AD9833. Serial.println (moduleFrequency) ؛ }
قمنا بتعيين المؤشر مرة أخرى وتحديث قيم العداد. مرة أخرى نتحقق من منطقية لتحديث نطاق التردد على الشاشة ، وعلينا القيام بذلك لأن مبدأ عمل OLED غريب جدًا.
display.setCursor (45 ، 20) ؛ display.println (عداد) ؛ // طباعة معلومات العداد على الشاشة. إذا (set_frequency_hz == 1 && set_frequency_khz == 0 && set_frequency_mhz == 0) {display.setCursor (90، 20)؛ display.println ("هرتز") ؛ // طباعة هرتز على شاشة العرض. // when all set تقوم بتحديث العرض} if (set_frequency_hz == 0 && set_frequency_khz == 1 && set_frequency_mhz == 0) {display.setCursor (90، 20)؛ display.println ("Khz") ؛ display.display () ، // when all set تقوم بتحديث العرض} if (set_frequency_hz == 0 && set_frequency_khz == 0 && set_frequency_mhz == 1) {display.setCursor (90، 20)؛ display.println ("Mhz") ؛ display.display () ، // عندما تقوم كل مجموعة بتحديث العرض}
بعد ذلك ، نتحقق من متغير ضغط الزر لطباعة الإخراج على / إيقاف تشغيل OLED. مرة أخرى ، يجب القيام بذلك بسبب وحدة OLED.
إذا (btn_state) {display.setTextSize (1) ، display.setCursor (65 ، 45) ؛ display.print ("Output ON") ؛ // إخراج الطباعة على شاشة العرض. display.setTextSize (2) ، } else {display.setTextSize (1) ؛ display.setCursor (65 ، 45) ؛ display.print ("Output OFF") ؛ // إخراج الطباعة من على شاشة العرض. display.setTextSize (2) ، }
هذا يمثل نهاية عملية الترميز لدينا. إذا كنت مرتبكًا في هذه المرحلة ، يمكنك التحقق من التعليقات في الكود لمزيد من الفهم.
اختبار مولد الوظيفة القائم على AD9833
لاختبار الدائرة ، يتم استخدام الإعداد أعلاه. كما ترون ، لقد قمنا بتوصيل محول طاقة بجهد 12 فولت بمقبس أسطوانة DC وقمنا بتوصيل Hantek Oscilloscope بمخرج الدائرة. لقد قمنا أيضًا بتوصيل مرسمة الذبذبات بالكمبيوتر المحمول لتصور وقياس تردد الخرج.
بمجرد الانتهاء من ذلك ، قمنا بتعيين تردد الخرج على 5 كيلو هرتز بمساعدة المشفر الدوار ونختبر موجة جيبية ناتجة وبالتأكيد هي موجة جيبية 5 كيلو هرتز عند الخرج.
بعد ذلك ، قمنا بتغيير شكل الموجة الناتج إلى موجة مثلثة ولكن التردد ظل كما هو ، يظهر شكل الموجة الناتج أدناه.
ثم قمنا بتغيير الخرج إلى موجة مربعة ولاحظنا الناتج ، وكان ذلك عبارة عن موجة مربعة كاملة.
قمنا أيضًا بتغيير نطاقات التردد واختبرنا الإخراج ، وكان يعمل بشكل جيد.
مزيد من التحسينات
هذه الدائرة ليست سوى دليل على المفهوم وتحتاج إلى مزيد من التحسينات. أولاً ، نحتاج إلى ثنائي الفينيل متعدد الكلور عالي الجودة وبعض موصل BNC عالي الجودة للإخراج وإلا فلن نتمكن من الحصول على تردد أعلى. سعة الوحدة منخفضة جدًا ، ولتعزيز ذلك ، نحتاج إلى بعض دوائر op-amp لتضخيم جهد الخرج. يمكن توصيل مقياس الجهد من أجل تغيير سعة الخرج. يمكن توصيل مفتاح لتعطيل الإشارة ؛ هذه أيضًا ميزة لا غنى عنها. علاوة على ذلك ، يحتاج الكود إلى الكثير من التحسين لأنه يحتوي على القليل من الأخطاء. أخيرًا ، يجب تغيير شاشات OLED وإلا فإنه من المستحيل كتابة رمز يسهل فهمه.
يمثل هذا نهاية هذا البرنامج التعليمي ، وآمل أن تكون قد أحببت المقالة وتعلمت شيئًا جديدًا. إذا كانت لديك أي أسئلة بخصوص المقالة ، فيمكنك تركها في قسم التعليقات أدناه أو يمكنك استخدام منتدى الإلكترونيات الخاص بنا.