في ممارسة راديو الهواة ، أحيانًا تكون هناك حاجة للقيام بشيء ما على وحدة التحكم الدقيقة. إذا كنت لا تفعل هذا النوع من الحرف طوال الوقت ، فعليك البحث لفترة طويلة عن حل الدائرة الضروري والمكتبات المناسبة لـ MK ، مما يسمح لك بحل المشكلة بسرعة. في الآونة الأخيرة ، أردت عمل مفتاح هوائي تلقائي. في هذه العملية ، كان علي استخدام العديد من ميزات Atmega MK في مشروع واحد مضغوط. يمكن لأولئك الذين يبدأون في دراسة AVR ، أو التبديل من arduino أو برنامج MK أحيانًا أن يكونوا قطعًا مفيدة من التعليمات البرمجية التي استخدمها في المشروع.
فكرت في مفتاح الهوائي كجهاز يربط الهوائي تلقائيًا بجهاز الإرسال والاستقبال ، وهو الأنسب لنطاق العمل من الموجات القصيرة. لدي هوائيان: V المقلوب والطائرة الأرضية ، وهما متصلان بموالف هوائي MFJ ، حيث يمكن تبديلهما عن بعد. هناك مفتاح يدوي ذو علامة تجارية MFJ ، والذي أردت استبداله.
للتبديل التشغيلي للهوائيات ، يتم توصيل زر واحد إلى MK. لقد قمت بتكييفه لتذكر الهوائي المفضل لكل نطاق: عند الضغط على الزر لأكثر من 3 ثوانٍ ، يتم تذكر الهوائي المحدد وتحديده بشكل صحيح تلقائيًا بعد التشغيل التالي للجهاز. يتم عرض معلومات حول النطاق الحالي والهوائي المحدد وحالة موالفته على شاشة LCD أحادية الخط.
يمكنك معرفة النطاق الذي يعمل عليه جهاز الإرسال / الاستقبال بطرق مختلفة: يمكنك قياس تردد الإشارة ، ويمكنك تلقي البيانات عبر واجهة CAT ، ولكن أبسط شيء بالنسبة لي هو استخدام واجهة جهاز الإرسال والاستقبال YAESU لتوصيل مكبر صوت خارجي. يحتوي على 4 خطوط إشارة ، في رمز ثنائي ، تشير إلى النطاق الحالي. إنها تعطي إشارة منطقية من 0 إلى 5 فولت ويمكن توصيلها بأرجل MK من خلال زوج من المقاومات الطرفية.
هذا ليس كل شيء. في وضع الإرسال ، يتم إرسال إشارات PTT و ALC من خلال نفس الواجهة. هذه إشارة منطقية حول تشغيل جهاز الإرسال (يتم سحبه إلى الأرض) وإشارة تناظرية من 0 إلى -4 فولت حول تشغيل نظام التحكم التلقائي في طاقة جهاز الإرسال. وقررت أيضًا قياسه وعرضه على شاشة LCD في وضع الإرسال.
بالإضافة إلى ذلك ، يمكن أن يرسل موالف MFJ إشارات إلى جهاز التحكم عن بعد يتم ضبطه وأن الهوائي مضبوط. للقيام بذلك ، تحتوي لوحة تحكم الشركة MFJ على مصباحي تحكم. بدلاً من مصابيح LED ، قمت بتوصيل أجهزة optocouplers وأرسلت منها إشارة إلى عضو الكنيست ، حتى أتمكن من رؤية جميع المعلومات على شاشة واحدة. يبدو الجهاز النهائي مثل هذا.
باختصار حول محلية الصنع مثل كل شيء. الآن عن جزء البرنامج. الرمز مكتوب في Atmel Studio (تنزيل مجاني من موقع Atmel). يوضح المشروع للمبتدئين الميزات التالية لاستخدام Atmega8 MK الشهير:
- زر الاتصال
- ربط إدخال الخط للإشارة الرقمية من جهاز الإرسال والاستقبال والموالف
- توصيل خرج التحكم في مرحل تبديل الهوائي
- توصيل شاشة LCD ذات خط واحد
- اتصال الجرس وإخراج الصوت
- ADC توصيل خط الإدخال التناظري وقياس الجهد
- باستخدام المقاطعات
- استخدام المؤقت لحساب الوقت الذي يتم فيه الضغط على زر
- باستخدام الوكالة الدولية للطاقة
- استخدام الذاكرة غير المتطايرة لتخزين الهوائيات المحددة
- باستخدام UART لطباعة التصحيح
- توفير الطاقة في MK الخامل
لذلك دعونا نبدأ. في سياق النص ، سيكون هناك جميع أنواع أسماء التسجيلات والثوابت التي تميز MK المطبق. هذا ليس اردوينو ، هنا ، لسوء الحظ ، عليك قراءة ورقة البيانات على MK. خلاف ذلك ، أنت لا تفهم ما تعنيه كل هذه السجلات وكيف يمكنك تغيير قيمها. لكن هيكل البرنامج ككل سيبقى كما هو.
أولاً ، قم بتوصيل الزر بـ MK
هذا هو الأبسط. نقوم بتوصيل جهة اتصال واحدة بقدم MK ، أما الزر الثاني فيتصل بالأرض. لكي يعمل الزر ، ستحتاج إلى تشغيل المقاوم القابل للسحب في MK. سيقوم بتوصيل الزر من خلال المقاومة لحافلة + 5V. للقيام بذلك أمر بسيط للغاية:
PORTB |= (1 << PB2);
وبالمثل ، يتم سحب جميع المدخلات الرقمية التي يتم التحكم فيها بواسطة خطأ أرضي (optocouplers ، خطوط الإشارة من جهاز الإرسال والاستقبال ، إشارة PTT) إلى ناقل + 5V. في بعض الأحيان يكون من الأفضل اللحام جسديًا لمثل هذا المقاوم الأصغر (على سبيل المثال 10 كيلو) بين إدخال MK وحافلة + 5V ، ولكن مناقشة هذه المشكلة خارج نطاق المقالة. نظرًا لأن جميع إشارات الإدخال في المشروع نادرًا ما تغير القيم ، يتم تحويلها إلى الأرض بواسطة 10 مكثفات نانوفاراد للحماية من التداخل.
الآن لدينا منطقي 1 عند الإدخال PB2 ، وعندما تضغط على الزر ، سيكون منطقيًا 0. عند الضغط على \ الضغط ، تحتاج إلى تتبع ارتداد الاتصال للزر ، والتحقق من أن مستوى الإشارة لم يتغير بمرور الوقت ، على سبيل المثال 50 مللي ثانية. يتم ذلك في البرنامج مثل هذا:
if(!(PINB&(1<<PINB2)) && !timer_on) {
الآن وصل squeaker
سيعطي إشارة تأكيد الصوت أن الهوائي مسجل في ذاكرة MK. مكبر الصوت هو مجرد عنصر كهرضغطية. يتم توصيله من خلال مقاومة صغيرة للقدم MK ، ومن خلال اتصال ثانٍ إلى + 5V. لكي يعمل هذا الجرس ، يجب عليك أولاً تكوين قدم MK لإخراج البيانات.
void init_buzzer(void) { PORTB &= ~(1 << PB0);
الآن يمكن استخدامه. للقيام بذلك ، يتم كتابة وظيفة صغيرة تستخدم التأخير الزمني للتبديل بين أرجل MK من 0 إلى 1 والعكس صحيح. التبديل مع التأخيرات اللازمة يجعل من الممكن توليد إشارة صوتية 4 كيلوهرتز لمدة حوالي ربع ثانية عند إخراج MK ، وهو صوت العنصر الكهروإجهادي.
void buzz(void) {
لكي تعمل وظائف التأخير ، لا تنسى تضمين ملف الرأس وتعيين سرعة المعالج ثابتة. وهو يساوي تردد مرنان الكوارتز المتصل بـ MK. في حالتي ، كان هناك كوارتز 16 ميجا هرتز.
#ifndef F_CPU # define F_CPU 16000000UL #endif #include <util/delay.h>
نقوم بتوصيل هوائيات تبديل التتابع MK
هنا تحتاج فقط إلى تكوين قدم MK للعمل على الخروج. يتم توصيل مرحل القصب بهذه الساق من خلال ترانزستور مضخم بطريقة قياسية.
void init_tuner_relay(void) { PORTB &= ~(1 << PB1);
اتصال الشاشة
استخدمت شاشة LCD 1601 أحادية الخط مؤلفة من 16 حرفًا ، مستخرجة من الأجهزة القديمة. ويستخدم جهاز تحكم HD44780 المعروف ، لإدارة العديد من المكتبات المتاحة على الشبكة. كتب شخص طيب مكتبة خفيفة الوزن للتحكم في العرض ، والتي استخدمتها في المشروع. يتم تقليل إعداد المكتبة للإشارة في ملف الرأس HD44780_Config.h عدد أرجل MK المتصلة بدبابيس العرض المطلوبة. قمت بتطبيق اتصال عرض عبر 4 خطوط بيانات.
#define Data_Length 0 #define NumberOfLines 1 #define Font 1 #define PORT_Strob_Signal_E PORTC #define PIN_Strob_Signal_E 5 #define PORT_Strob_Signal_RS PORTC #define PIN_Strob_Signal_RS 4 #define PORT_bus_4 PORTC #define PIN_bus_4 0 #define PORT_bus_5 PORTC #define PIN_bus_5 1 #define PORT_bus_6 PORTC #define PIN_bus_6 2 #define PORT_bus_7 PORTC #define PIN_bus_7 3
كانت إحدى سمات مثيل العرض الخاص بي أنه تم عرض سطر واحد على الشاشة كسطرين من 8 أحرف ، لذلك تم إنشاء مخزن مؤقت للشاشة في البرنامج لمزيد من العمل المريح مع الشاشة.
void init_display(void) { PORTC &= ~(1 << PC0);
تتيح وظيفة update_display () عرض محتويات المخزن المؤقت على الشاشة. قيم البايت في المخزن المؤقت هي رموز ASCII لأحرف الإخراج.
تصحيح إخراج الطباعة إلى منفذ COM
MK لديه UART ولقد استخدمته لتصحيح البرنامج. عند توصيل MK بالكمبيوتر ، ما عليك سوى أن تتذكر أن مستويات الإشارة عند إخراج MK تكون في معيار TTL وليس RS232 ، لذا فأنت بحاجة إلى محول بسيط. لقد استخدمت محول USB-Serial ، مشابه تمامًا على aliexpress. أي برنامج طرفي ، على سبيل المثال من اردوينو ، مناسب لقراءة البيانات. رمز إعداد منفذ UART:
#define BAUD 9600 #include <stdio.h> #include <stdlib.h> #include <avr/io.h> // UART RS232 void uart_init( void ) { /* // UBRRH = 0; UBRRL = 103; //9600 16 */ #include <util/setbaud.h> UBRRH = UBRRH_VALUE; UBRRL = UBRRL_VALUE; #if USE_2X UCSRA |= (1 << U2X); #else UCSRA &= ~(1 << U2X); #endif //8 , 1 , UCSRC = ( 1 << URSEL ) | ( 1 << UCSZ1 ) | ( 1 << UCSZ0 ); // // UCSRB = ( 1 << TXEN ) | ( 1 <<RXEN ); UCSRB = ( 1 << TXEN ); } int uart_putc( char c, FILE *file ) { // while( ( UCSRA & ( 1 << UDRE ) ) == 0 ); UDR = c; wdt_reset(); return 0; } FILE uart_stream = FDEV_SETUP_STREAM( uart_putc, NULL, _FDEV_SETUP_WRITE ); stdout = &uart_stream;
بعد إعداد دفق الإخراج ، يمكنك استخدام printf المعتاد للطباعة إلى المنفذ:
printf( "Start flag after reset = %u\r\n", mcusr_mirror );
يستخدم البرنامج طباعة أرقام حقيقية. لا تدعم المكتبات العادية وضع الإخراج هذا ، لذلك كان علي توصيل مكتبة كاملة عند ربط مشروع. صحيح ، إنه يزيد بشكل كبير من حجم الشفرة ، لكن كان لدي قدر كبير من الذاكرة ، لذلك كان ذلك غير نقدي. في خيارات الرابط ، تحتاج إلى تحديد الخط:
-Wl,-u,vfprintf -lprintf_flt
العمل مع الموقت والمقاطعات
لحساب الفترات الزمنية في البرنامج ، من المهم أن يكون لديك عداد وقت. هناك حاجة لتتبع الضغط على الزر لأكثر من 3 ثوان ، وبالتالي ، تحتاج إلى تذكر الإعدادات الجديدة في الذاكرة غير المتطايرة. لقياس الوقت في نمط AVR ، تحتاج إلى تكوين عداد النبض لمولد الساعة والمقاطعة التي سيتم تنفيذها عندما يصل العداد إلى القيمة المحددة. قمت بتعيين المؤقت بحيث ينتج مقاطعة حوالي مرة واحدة في الثانية. معالج المقاطعة نفسه يحسب عدد الثواني المنقضية. يتحكم المتغير timer_on في تشغيل / إيقاف المؤقت. من المهم عدم نسيان إعلان جميع المتغيرات التي يتم تحديثها في معالج المقاطعة على أنها متغيرة ، وإلا فإن المترجم يمكنه "تحسينها" ولن يعمل البرنامج.
يتم التحقق من قيمة pass_secs في الحلقة الرئيسية للبرنامج. عند الضغط على الزر ، يبدأ المؤقت ثم يتم فحص قيمة المؤقت أثناء الضغط على الزر في دورة البرنامج الرئيسية. إذا تجاوزت هذه القيمة 3 ثوانٍ ، فسيتم كتابة EEPROM ، ويتوقف المؤقت.
أخيرًا وليس آخرًا ، بعد كل التهيئة ، تحتاج إلى تمكين المقاطعات باستخدام الأمر sei ().
قياس مستوى ALC
وهي مصنوعة باستخدام المحول التناظري إلى الرقمي المدمج (ADC). قمت بقياس الجهد عند مدخل ADC7. يجب أن نتذكر أنه يمكنك قياس قيمة من 0 إلى 2.5 فولت. وكان جهد الإدخال الخاص بي من -4V إلى 0V. لذلك ، قمت بتوصيل MK من خلال أبسط مقسم للجهد على المقاومات ، بحيث يكون مستوى الجهد عند دخل MK عند مستوى معين. علاوة على ذلك ، لم أكن بحاجة إلى دقة عالية ، لذلك قمت بتطبيق تحويل 8 بت (يكفي قراءة البيانات فقط من سجل ADCH). كمصدر مرجعي ، استخدمت أيونًا داخليًا عند 2.56 فولت ، وهذا يبسط الحسابات قليلاً. لكي يعمل ADC ، تأكد من توصيل مكثف 0.1 µF بقدم REF على الأرض.
يعمل ADC في حالتي بشكل مستمر ، ويبلغ عن نهاية التحويل من خلال استدعاء المقاطعة ADC_vect. من الجيد متوسط قيم عدة دورات تحويل لتقليل الخطأ. في حالتي ، أستنتج متوسط 2500 تحويل. يبدو كل رمز ADC كما يلي:
باستخدام EEPROM
هذه ذاكرة غير متطايرة في MK. من السهل استخدامه لتخزين جميع أنواع الإعدادات وقيم التصحيح وما إلى ذلك. في حالتنا ، يتم استخدامه فقط لتخزين الهوائي المحدد للمدى المطلوب. لهذا الغرض ، يتم تخصيص صفيف 16 بايت في EEPROM. ولكن يمكنك الوصول إليه من خلال الوظائف الخاصة المحددة في ملف الرأس avr / eeprom.h. عند بدء التشغيل ، يقرأ عضو الكنيست معلومات حول الإعدادات المحفوظة في ذاكرة الوصول العشوائي ويقوم بتشغيل الهوائي المطلوب ، اعتمادًا على النطاق الحالي. عند الضغط على الزر لفترة طويلة ، يتم تسجيل قيمة جديدة في الذاكرة ، مصحوبة بإشارة صوتية. عند الكتابة إلى EEPROM ، يتم تعطيل المقاطعات فقط في حالة. كود تهيئة الذاكرة:
EEMEM unsigned char ee_bands[16];
مقتطف من كود المعالجة للضغط على زر لمدة 3 ثوان والكتابة على الذاكرة:
if (!(PINB&(1<<PINB2)) && passed_secs >= 3) {
باستخدام الوكالة الدولية للطاقة
ليس سرا أنه تحت ظروف التداخل الكهرومغناطيسي القوي يمكن لـ MK تجميده. عندما يكون الراديو قيد التشغيل ، هناك مثل هذا التداخل الذي "تبدأ المكواة بالحديث" ، لذلك تحتاج إلى التأكد من إعادة تشغيل MK بعناية في حالة حدوث تعليق. يخدم جهاز توقيت هذا الغرض. استخدامه بسيط للغاية. أولاً ، قم بتضمين ملف رأس avr / wdt.h في المشروع. في بداية البرنامج ، بعد إكمال جميع الإعدادات ، تحتاج إلى بدء المؤقت عن طريق استدعاء وظيفة wdt_enable (WDTO_2S) ، ثم تذكر إعادة تعيينها بشكل دوري عن طريق استدعاء wdt_reset () ، وإلا فسيتم إعادة تشغيل MK نفسه. لتصحيح الأخطاء لمعرفة سبب إعادة تشغيل MK ، يمكنك استخدام قيمة سجل MCUSR الخاص ، والتي يمكن تذكر قيمتها ثم إخراجها إلى طباعة التصحيح.
توفير الطاقة لعشاق البيئة
في حين أن عضو الكنيست ليس مشغولاً بأي شيء ، إلا أنه يمكن أن ينام وينتظر المقاطعة التالية. في هذه الحالة ، يتم توفير القليل من الطاقة الكهربائية. تافه ، ولكن لماذا لا تستخدمه في المشروع. علاوة على ذلك ، إنها بسيطة للغاية. قم بتضمين ملف رأس avr / sleep.h. يتكون جسم البرنامج من حلقة واحدة لا نهائية تحتاج فيها إلى استدعاء الدالة sleep_cpu () ، وبعد ذلك ينام MC قليلاً ، وتتوقف الحلقة الرئيسية حتى تحدث المقاطعة التالية. تحدث أثناء تشغيل المؤقت و ADC ، لذلك لن ينام MK لفترة طويلة. يتم تحديد وضع الإسبات عندما تتم تهيئة MK عن طريق استدعاء وظيفتين:
set_sleep_mode(SLEEP_MODE_IDLE);
هذا كل شيء الآن. لقد قمت بالتبديل ؛ يعمل بنجاح في محطة إذاعة الهواة بلا فشل. آمل أن تكون المواد المقدمة مفيدة للمبتدئين.
73 دي R2AJP