جدول المحتويات:
- الخطوة 1: جهاز الإدخال
- الخطوة 2: الأضواء الوامضة للإشارة
- الخطوة 3: استطراد بسيط في التصحيح
- الخطوة 4: المزيد من التصحيح
- الخطوة 5: استخدام Timer / Counter 0 لإصدار أصوات التنبيه
- الخطوة 6: تكوين عداد الوقت / العداد 0
- الخطوة 7: استخدام أربعة مفاتيح
- الخطوة 8: استخدام إنشاء المفتاح / الحالة
- الخطوة 9: الخاتمة
فيديو: مفاتيح القراءة مع ATtiny2313: 9 خطوات
2024 مؤلف: John Day | [email protected]. آخر تعديل: 2024-01-30 07:42
كان هناك العديد من التعليمات التي تتعامل مع مخرجات ATtiny2313 وأجهزة AVR المماثلة. على سبيل المثال ، https://www.instructables.com/id/Ghetto-Programming٪3a-Getting-started-with-AVR-micro/ ، https://www.instructables.com/id/Drive-a-Stepper- محرك مع معالج دقيق AVR /. من خلال العمل على أحدث إصدار من The Real Elliot ، والذي أظهر كيفية التحكم في محركات السائر ، وجدت أنه سيكون من المفيد حقًا أن تكون قادرًا على تشغيل أقسام بديلة من الكود في نفس البرنامج ، لذلك لم أضطر إلى إعادة برمجة ATtiny2313 لكل منها الوقت الذي أردت فيه تجربة اختلاف بسيط في الكود (مثل نصف خطوة أو تشغيل السائر في الاتجاه المعاكس). في حين أنه من السهل كتابة التعليمات البرمجية باستخدام بيان التبديل / الحالة للسماح بتحديد الاختلافات البديلة ، إلا أن هناك حاجة إلى طريقة ما لتحديد الحالة. هذا يعني أنه يجب قراءة نوع من أجهزة الإدخال للتحكم في الحالة. لحسن الحظ ، يحتوي ATtiny2313 على الكثير من دبابيس الإدخال / الإخراج وهو مصمم جيدًا لقراءة المدخلات من المفاتيح. سيوضح هذا Instructable كيفية قراءة المدخلات واتخاذ القرارات بناءً على حالتها. نظرًا لأن هذا وحده من شأنه أن يجعل Instructable مملًا جدًا ، فسأشرح طريقة بسيطة لاستخدام قدرة المؤقت / العداد في ATtiny2313 لتشغيل مكبر صوت صغير كصافير. سيكون هناك أيضًا استطراد بسيط في تقنيات تصحيح الأخطاء البسيطة.
الخطوة 1: جهاز الإدخال
يعتمد هذا Instructable على العمل الممتاز لـ Real Elliot ويستخدم نظام تطوير ATtiny2313 Ghetto الذي يصفه. ورقة البيانات ATtiny2313 من Atmel هي المرجع النهائي لجميع الوظائف ، ولكن ليس من السهل قراءتها بالضرورة. https://www.atmel.com/dyn/products/datasheets.asp؟family_id=607 (يحتوي الرابط على جميع أوراق بيانات AVR ، حدد موقع 2313.) يوضح الشكل مجموعة بسيطة من مفاتيح الإدخال. هذه مجرد حزمة من أربعة مفاتيح تشغيل / إيقاف ؛ يُعرف أيضًا باسم مفاتيح أحادية القطب (SPST). عادة ، يتم ربط اتصال أو قطب واحد لكل مفتاح بالأرض بينما يتم سحب الاتصال الآخر عالياً من خلال المقاوم الحالي المحدد (10 كيلو أو نحو ذلك). يتم توصيل مدخل متحكم بالقطب بالمقاوم. إذا كان المفتاح مفتوحًا ، فسوف يقرأ المتحكم الدقيق الإدخال على أنه HI. إذا تم إغلاق المفتاح ، فسيقوم المتحكم الدقيق بقراءة LO الإدخال. ارجع إلى التخطيطي للحصول على التفاصيل. يبسط ATtiny2313 الأشياء من خلال توفير مقاومات سحب قابلة للبرمجة على دبابيس الإدخال / الإخراج عند تكوينها كمدخلات. هذا يعني أنه يمكن للمفاتيح أن تحتوي ببساطة على قطب واحد مرتبط بالأرض (LO) والقطب الآخر متصل بإدخال معالج. يُظهر المثال الأول مفتاحين فقط. تتم قراءة المفاتيح وتكوينها باستخدام الكود التالي. قم بتكوين المفاتيح كمدخلات: (لا يوجد رمز مطلوب ؛ هذا هو الإعداد الافتراضي.) قم بتشغيل مقاومات السحب: PORTB = _BV (PB0) | _BV (PB1) ؛ اقرأ المدخلات: but1 = ~ PINB & 0x03 ؛ لاحظ استخدام الانعكاس والإخفاء للحصول على القيمة الصحيحة.
الخطوة 2: الأضواء الوامضة للإشارة
سنستخدم هذين المفتاحين لوميض مؤشر LED لعدد من المرات القابلة للبرمجة. ستكون المصابيح التي سنستخدمها هي الأضواء الوامضة التي اشتهر بها The Real Elliot. سيتم التعامل مع المفتاحين 1 و 2 على أنهما رقمان ثنائيان ، لذلك يمكن أن تمثل المجموعة الأرقام 0 و 1 و 2 و 3. سيقرأ برنامجنا المفتاحين ويومضان بالعدد المناسب من المرات ، ولكن فقط إذا كان المفتاح تغيرت الإعدادات. يتم إلغاء رموز التبديل لمدة 500 مللي ثانية (غير محسّن). خوارزمية debounce بسيطة جدًا. تتم قراءة المفاتيح ويتم تدوين القراءة. إذا كانت مختلفة عن قيمة oldBut (آخر قيمة محفوظة) ، فسيتم تأخير البرنامج لمدة 500 مللي ثانية وتتم قراءة المفاتيح مرة أخرى. إذا كانت القيمة هي نفسها التي تمت قراءتها مسبقًا ، فسيتم تحديث قيمة oldBut وسيومض مؤشر LED بعدد المرات التي تتضمنها القيمة الثنائية للمبدلين. لاحظ انعكاس القيمة منذ أن يقرأ مفتاح التبديل "قيد التشغيل" LO. سيتم فحص المفاتيح باستمرار لإجراء مزيد من التغييرات. يرجى الرجوع إلى Instructables السابقة بواسطة The Real Elliot لمعرفة المزيد حول الأضواء الوامضة. ألق نظرة على https://www.ganssle.com/debouncing.pdf هذا لمعرفة المزيد حول إلغاء رموز التبديل ، وإليك رمز ATtiny2313 لهذا المثال. أثناء التشغيل ، سيومض هذا البرنامج مؤشر LED الموجود على PB4 (رقم التعريف الشخصي 8) مرتين لإظهار أنه قد تمت تهيئته. سيقرأ بعد ذلك المفتاحين الأول والثاني ، ويومض من مرة إلى ثلاث مرات حسب إعداد المفتاح كلما تم تغييرهما. عندما لا تتغير المفاتيح ، سيومض مؤشر LED ببطء. لتشغيل هذا الرمز ، أنشئ دليلًا جديدًا (أطلق عليه اسم "أساسي" إذا كنت ترغب في ذلك) وقم بتنزيل ملف كود C التالي و makefile فيه. قم بإعادة تسمية Makefile1.txt إلى Makefile فقط. باستخدام WinAVR ، قم بترجمة البرنامج وتحميله في ATtiny2313 الخاص بك.
الخطوة 3: استطراد بسيط في التصحيح
إذا كنت مثلي (وكل مبرمج آخر في العالم) ، فمن المحتمل أن تكون قد مررت بأوقات لم يكن فيها الرمز "الخالي من الأخطاء" الذي كتبته بعناية وجمعته لا يفعل ما تتوقعه. ربما ببساطة لا تفعل شيئًا! إذا ما هي المشكلة؟ كيف ستكتشف؟ لحسن الحظ ، هناك عدة طرق لجعل الأشياء تعمل. (احصل على هذا الكتاب للحصول على معالجة ممتازة لموضوع التصحيح. https://www.debuggingrules.com/) أود تقديم بعض الاقتراحات البسيطة المتعلقة بموضوع تصحيح أخطاء تطبيقات وحدة التحكم الدقيقة. الخطوة الأولى هي البناء على ماذا تعرف. إذا حصلت على وميض يعمل مرة واحدة ، فاستخدمه مرة أخرى لمعرفة مكانك في برنامجك. أحب أن يومض LED مرتين للإشارة إلى بدء البرنامج. يمكنك وضع الكود للقيام بذلك مبدئيًا في بداية البرنامج. بمجرد أن تعرف أنه لا يوجد شيء خاطئ في أجهزتك ، قم بإنشاء وظيفة للقيام بالوميض. ها هي الوظيفة التي أستخدمها. / * ------------------------------------------ ------------------------------ ** blinkEm - وظيفة وميض LED باستخدام PD4 ** يجب تكوين PD4 كإخراج. ** ------------------------------------------------ --------------------- * / void blinkEm (uint8_t count) {while (count> 0) {PORTD = _BV (PD4)؛ _delay_ms (1000) ؛ PORTD = ~ _BV (PD4) ؛ _delay_ms (1000) ؛ عدد--؛ }} من الممكن الآن استخدام هذه الوظيفة في نقاط مختلفة في شفرتك كإشارة إلى أن الشفرة قد نفذت إلى هذا الحد. إن معرفة أن الشفرة قيد التشغيل تعني أنه يمكنك فحص كل قسم تم تشغيله بعناية ، ولكن لم يتم تنفيذ ما كنت تتوقعه ، للعثور على الأخطاء. يعد تغيير شيء واحد في كل مرة تقنية أساسية لتصحيح الأخطاء أيضًا (كما هو موضح في المرجع أعلاه). تعمل هذه الطريقة الكلاسيكية جنبًا إلى جنب مع "فرق تسد": اتخاذ خطوات صغيرة لإضافة وظائف تدريجية. قد يبدو هذا نهجًا بطيئًا ، لكنه ليس بطيئًا تقريبًا مثل محاولة تصحيح جزء كبير من التعليمات البرمجية غير العاملة دفعة واحدة.
الخطوة 4: المزيد من التصحيح
هناك عدة مرات نرغب فيها في التحقق من قسم من الكود عن طريق تخطي معظم الأسطر الموجودة فيه ، ثم تمكينها واحدة تلو الأخرى بينما نتحقق من أن كل سطر يعمل. عادة ، نقوم بذلك عن طريق "التعليق" على الأسطر التي نريد تخطيها. امتداد لهذه التقنية هو قص ولصق كتلة من التعليمات البرمجية ، والتعليق على النص الأصلي (حتى لا نفقده) ، واختراق النسخة. لدى C أربع طرق سهلة للتعليق على الأسطر. وضع "//" أمام سطر التعليقات خارج هذا السطر. سيؤدي إغلاق سطر واحد أو أكثر في "/ *" و "* /" إلى التعليق على القسم بأكمله. لكي تعمل هذه الطريقة بفاعلية ، يجب ألا يكون هناك "* /" أخرى في كتلة التعليمات البرمجية (بخلاف النهاية النهائية). لذا فإن الانضباط الفعال هو استخدام // للتعليقات داخل كتل التعليمات البرمجية ، واحتفظ بـ / * * / الإنشاء لمجموعات التعليقات وللتعليق على أقسام التعليمات البرمجية. وضع "#if 0" في بداية الكتلة للتعليق عليها وإنهاء القسم بـ "#endif". مزيد من التحكم الانتقائي ممكن باستخدام "#ifdef (المعرف)" في بداية الكتلة و "#endif" في النهاية. إذا كنت تريد تجميع الكتلة ، فاستخدم "#define (المعرف)" في وقت سابق من البرنامج. لاحظ أن علامات الاقتباس هي للتأكيد فقط ولا يجب تضمينها. يجب أن يوفر الجمع بين هذه الأساليب طريقة مفيدة لتصحيح أخطاء برامج ATtiny2313 الخاصة بك. قد تجد هذه الأدوات مفيدة ونحن نتابع من خلال هذا Instructable.
الخطوة 5: استخدام Timer / Counter 0 لإصدار أصوات التنبيه
يحتوي ATtiny2313 على مصدرين قويين للعداد / عداد: أحدهما 8 بت والآخر 16 بت. يمكن تكوينها كمولدات تردد ، ووحدات تحكم في تعديل عرض النبض المتغير ، وسجلات مقارنة الإخراج. تم وصف الوظائف الكاملة لهذه في 49 صفحة من ورقة البيانات. ومع ذلك ، سنستخدم حالة بسيطة. سيتم استخدام Timer / Counter 0 (8 بت واحد) فقط وسيتم استخدامه ببساطة كمولد تردد. سيتم توجيه التردد إلى مكبر صوت صغير لإصدار صوت تنبيه. تم وصف المؤقت / العداد 0 بالكامل في الصفحات 66 إلى 83 من ورقة بيانات ATtiny2313. ستوفر القراءة الدقيقة لهذه المادة للشخص فهماً كاملاً للوقت / العداد 0. لحسن الحظ ، فإن الوضع البسيط إلى حد ما ، Clear Timer on Compare (CTC) ، هو كل ما هو مطلوب لتوليد نغمة الصفير التي نريدها.
بالنسبة للوضع الذي سنستخدمه ، يكون تشغيل المؤقت / العداد مباشرًا. عند تحديد إشارة الساعة ، يبدأ العداد من الصفر ويزيد كل نبضة على مدار الساعة. عندما تصل قيمة العداد إلى القيمة الموجودة في سجل مقارنة الإخراج (TOP) ، تتم إعادة تعيين العداد إلى الصفر ويبدأ العد مرة أخرى. يتم تبديل بت الإخراج المرتبط بـ Timer / Counter لإنتاج خرج موجة مربعة. يؤدي هذا مباشرة إلى تشغيل محول الصوت لإصدار صوت صفير. يُصدر محول الصوت TDK الصغير صوت الصفير. الوحدة المناسبة هي Digikey 445-2530-ND، TDK SD1209T3-A1 (لقد استخدمت نسخة مبكرة من هذا). هذه نسخة 3 فولت. الإصدار 5 فولت سيعمل أيضًا كما أتوقع. أقود هذا مباشرة من منفذ الإخراج الخاص بـ Attiny2313 ويبدو أنه يعمل بشكل جيد. Sparkfun لديه جهاز مشابه.
الخطوة 6: تكوين عداد الوقت / العداد 0
يمكن استخدام وضع CTC لتبديل الإخراج OC0A على Pin 2 ، Port B (دبوس مادي 14). لتمكين الإخراج على هذا الدبوس ، يجب تعيين DDRB بشكل مناسب. رمز C لهذا يشبه تمامًا إعداد إخراج لضوء وامض. DDRB = _BV (PB2) ؛ // المنفذ B2 هو ناتج ، والخطوة التالية هي توفير إشارة ساعة وتحميل سجل مقارنة الإخراج لإنتاج شكل موجة كتردد. ترد معادلة التردد الناتج في ورقة البيانات (صفحة 72). سيتم وصف الشروط في المعادلة أدناه. ها هي المعادلة: fOC0A = fclk_I / O / 2 * N * (1 + OCR0A) حيث fOC0A: = تردد الخرج fclk_I / O: = تردد مصدر الساعة N: = عامل التدرج المسبق على مدار الساعة OCR0A: = القيمة في المخرجات مقارنة سجل المؤقت / عداد 0A تردد مصدر الساعة ، fclk_I / O هذا هو تردد ساعة النظام. القيمة الافتراضية هي 1 ميجا هرتز. تتحكم البتات CS00 و CS01 و CS02 من TCCR0B في هذا التحديد. نظرًا لأن هذه البتات تحدد أيضًا قيمة N ، فسيتم وصفها لاحقًا. قيمة ما قبل المقياس ، NN هي القيمة المستخدمة لتقسيم ساعة النظام أو قياسها مسبقًا. تتحكم البتات CS00 و CS01 و CS02 من TCCR0B في هذا التحديد. يصف الجدول 41 في الصفحة 81 من ورقة بيانات ATtiny2313 التركيبات. نظرًا لأن التردد بالقرب من 1 كيلو هرتز مطلوب ، فسيتم تعيين بت CS00 و CS01 من TCCR0B. لاحظ أن ضبط جميع البتات الثلاثة على 0 ، وبالتالي عدم تحديد مصدر ساعة ، يوقف الإخراج بشكل فعال. هذه هي الطريقة التي سيتم استخدامها لبدء وإيقاف التنبيه. القيمة الأعلى ، OCR0A هذه القيمة هي أعلى قيمة للعداد الذي يتم تحميله في سجل مقارنة الإخراج لـ Timer / Counter 0A. عند الوصول إلى هذه القيمة ، ستتم إعادة تعيين العداد إلى الصفر وسيبدأ العد مرة أخرى حتى يتم الوصول إلى TOP وتتكرر الدورة. يتم تعديل TOP بسهولة ، لذلك من السهل تغيير تردد الصافرة. نظرًا لأن التردد بالقرب من 1 كيلو هرتز مطلوب ، يتم تعيين TOP على 7. (لاحظ أنه يمكن ضبط المقياس المسبق على 8 ، وضبط TOP على 63. نفس النتيجة - اختيارك.) تردد الإخراج ، fOC0A باستخدام المعادلة لحساب نتائج تردد الخرج في: fOC0A = 1 ، 000 ، 000/2 * 64 * (1 + 7) fOC0A = 977 هرتز إليك الكود لتحميل سجل مقارنة الإخراج وسجل التحكم في عداد عداد الوقت 0B. يرجى الاطلاع على رمز البرنامج الفعلي لفهم كيفية استخدامها. OCR0A = 7 ؛ // قيمة الوقت TCCR0B = _BV (CS01) | _BV (CS00) ؛ // حدد الساعة الداخلية ومقياس مسبق = 8 TCCR0B = 0 ؛ // لا يوجد مصدر ساعة يوقف النغمة ضبط وضع الوقت / العداد كتفاصيل أخيرة ، سنحدد وضع المؤقت / العداد الذي نرغب فيه عن طريق ضبط البتات المناسبة في Timer / Counter Control Register 0A. يتم تحديد وضع CTC عن طريق ضبط البت WGM01 كما هو موضح في الجدول 40 ، الصفحة 79 من ورقة البيانات. نظرًا لأننا نريد أن يتم تبديل الإخراج مع كل دورة ، فيجب أيضًا تعيين بت COM0A0 كما هو موضح في الجدول 34 في الصفحة 77. إليك الكود: TCCR0A = _BV (COM0A0) | _BV (WGM01) ؛ // وضع تبديل CTC
الخطوة 7: استخدام أربعة مفاتيح
أثناء تنفيذنا للصفارة ، دعنا نوسع أجهزتنا وبرامجنا للتعامل مع أربعة مفاتيح. نظرًا لأن إخراج Timer Counter 0A موجود على المنفذ B ، الدبوس 2 ، لا يمكننا ببساطة توصيل المزيد من المفاتيح بشكل تسلسلي إلى المنفذ B. سيكون الحل السهل هو استخدام المنفذ D ، ولكن دعونا نحافظ على هذا المنفذ متاحًا لوظائف أخرى (ربما محرك متدرج). لذلك دعونا نربط المحولات الإضافية بـ PB3 و PB4. قراءة المفاتيح في الغالب لم تتغير. تم تغيير قيمة القناع إلى 0x1B (00011011 ثنائي) لإخفاء البت 2 مع 5 و 6 و 7. يتم استخدام خدعة أخرى لإنشاء رقم ثنائي من 4 بتات. انقل البتتين 3 و 4 إلى اليمين بمقدار بت واحد وادمجهما مع البتتين 0 و 1 في رقم ثنائي مكون من 4 بتات. هذا هو بناء جملة C قياسي لتغيير وحدات البت ودمجها ، ولكن قد لا يكون معروفًا جيدًا للمبتدئين. but1a = (but1 & 0x03) | ((but1 & 0x18) >> 1) ؛ // but1 لديه تبديل القراءة أثناء التشغيل ، سيومض البرنامج مرتين ويصدر صوتًا مرتين للإشارة إلى التهيئة. في أي وقت يتم تغيير المفاتيح ، سيتم إصدار صوت تنبيه بالرقم الذي تمثله. عندما لا تتغير المفاتيح ، سيومض مؤشر LED. لتشغيل هذا الرمز ، أنشئ دليلًا جديدًا (أطلق عليه Beep إذا كنت ترغب في ذلك) وقم بتنزيل ملف التعليمات البرمجية C التالي ثم makefile فيه. أعد تسمية Makefile2.txt إلى Makefile فقط. باستخدام WinAVR ، قم بترجمة البرنامج وتحميله في Attiny2313 الخاص بك.
الخطوة 8: استخدام إنشاء المفتاح / الحالة
الخطوة الأخيرة هي "البرنامج فقط": كما وعدنا ، سنقوم بتنفيذ بنية التبديل / الحالة. على الرغم من أن هذا المثال لا يعرض سوى إجراءين بديلين ، إلا أنه يجب أن يكون واضحًا جدًا كيفية استخدام هذا البناء لتحديد أحد أقسام التعليمات البرمجية البديلة المتعددة. أثناء التشغيل ، يراقب هذا البرنامج المفاتيح وإذا كان هناك تغيير ، فسيصدر صوتًا بالرقم المناسب إذا كان فرديًا ؛ سوف يومض إذا كان الرقم زوجيًا. لا يفعل شيئًا ما لم يتغير مفتاح.
لتشغيل هذا الرمز ، قم بإنشاء دليل جديد (أطلق عليه Switch إذا كنت ترغب في ذلك) وقم بتنزيل ملف C code التالي و makefile فيه. أعد تسمية Makefile3.txt إلى Makefile فقط. باستخدام WinAVR ، قم بترجمة البرنامج وتحميله في Attiny2313 الخاص بك.
الخطوة 9: الخاتمة
هذا كل شيء! أنت الآن تعرف كيفية استخدام المفاتيح للتحكم في تنفيذ برنامجك من خلال قراءتها واختيار إجراء بناءً على إعداد التبديل. أنت تعرف أيضًا كيفية إنشاء نغمة تنبيه وتعلمت أيضًا بعض إستراتيجيات التصحيح.
إذا كنت ترغب في اختبار فهمك ، فحاول تعديل البرنامج الأخير ليصدر صوتًا بنبرة عالية إذا كانت متساوية ، وقم بإصدار نغمة منخفضة إذا كانت غريبة ، ووميض مؤشر LED باستمرار إذا لم يكن هناك تغيير في المفاتيح. مرة أخرى في قسم التصحيح للحصول على المساعدة.
موصى به:
القراءة والرسوم البيانية لضوء ومستشعر درجة الحرارة مع Raspberry Pi: 5 خطوات
بيانات القراءة والرسم البياني للضوء ومستشعر درجة الحرارة باستخدام Raspberry Pi: في هذا Instructable سوف تتعلم كيفية قراءة مستشعر الضوء ودرجة الحرارة باستخدام محول raspberry pi و ADS1115 التناظري إلى محول رقمي ورسمه باستخدام matplotlib. لنبدأ بالمواد المطلوبة
لوحة مفاتيح USB عالمية مع مفاتيح RGB: 6 خطوات
لوحة مفاتيح USB عالمية مع مفاتيح RGB: في هذا التوجيه ، سأوضح لك كيفية إنشاء لوحة مفاتيح USB مخصصة تتصرف تمامًا مثل لوحة مفاتيح الكمبيوتر العادية. يمكنك تعيين أي مجموعة مفاتيح أو تسلسل مفاتيح للضغط عليها أثناء الضغط على زر ضغط واحد فقط. يمكنك استخدامه
رطوبة القراءة مع مستشعر إيثرنت: 3 خطوات
رطوبة القراءة باستخدام مستشعر الإيثرنت: كان الغرض من المشروع أن يكون قادرًا على قراءة قراءات الرطوبة ودرجة الحرارة من خلال شبكة إيثرنت ، بحيث يمكن استخدام النتائج لأتمتة المنزل (مساعد منزلي وما إلى ذلك). أداء في ar
لوحة مفاتيح سريعة وقذرة (لوحة مفاتيح فارغة): 3 خطوات
لوحة مفاتيح سريعة وقذرة (لوحة مفاتيح فارغة): لوحة مفاتيح داس هي اسم لوحة المفاتيح الأكثر شيوعًا بدون نقوش على المفاتيح (لوحة مفاتيح فارغة). يتم بيع لوحة مفاتيح Das بسعر 89.95 دولارًا. سيرشدك هذا الدليل أثناء إنشاء لوحة مفاتيح قديمة لديك
تنظيف لوحة مفاتيح Apple Aluminium . أو أي لوحة مفاتيح أخرى ناعمة الملمس: 5 خطوات
تنظيف لوحة مفاتيح Apple Aluminium …. أو أي لوحة مفاتيح أخرى ناعمة الملمس: نظيفة مثلك أو قد أحاول الحفاظ على لوحات مفاتيح Apple المصنوعة من الألومنيوم ، فإنها تصبح قذرة بعد عام أو نحو ذلك. هذا التوجيه هو لمساعدتك على تنظيفه. كن حذرًا ، لأنني لست مسؤولاً إذا تعطلت لوحة المفاتيح أثناء القيام بذلك …. SUCKS F