Mündəricat:
- Addım 1: Klaviatura 1 -dən məhrum olun
- Addım 2: Klaviatura 2 -ni təmizləyin
- Addım 3: Klaviatura 3 -ü təmizləyin
- Addım 4: Klaviaturanı bağlayın
- Addım 5: Klaviaturanı Analizatorunuza bağlayın
- Addım 6: Hansı keçid açarlarını təyin etməliyik?
- Addım 7: Kəsmə İşləyicisini yazın
- Addım 8: Düymələrin dəyərlərini xəritəyə salın
- Addım 9: Versiya 1 üçün Kod və Video
- Addım 10: Versiya 2 üçün kod
- Addım 11: Düymədən Necə qurtulmalıyıq? Versiya 3
- Addım 12: İşçi versiyası üçün kod və video
Video: AVR Assembler Dərsliyi 7: 12 Addımlar
2024 Müəllif: John Day | [email protected]. Son dəyişdirildi: 2024-01-30 07:42
Tutorial 7 -ə xoş gəldiniz!
Bu gün əvvəlcə bir klaviaturanı necə təmizlədiyinizi və sonra klaviatura ilə əlaqə qurmaq üçün Analog giriş portlarını necə istifadə edəcəyinizi göstərəcəyik. Klaviaturanı tel ilə bağlayacağıq ki, hər bir düyməni basaraq analoq girişə bənzərsiz bir gərginlik göndərsin ki, bu da hansı düyməni basıldığını gərginliklə ayırd etməyimizə imkan verəcək. Sonra hər şeyin lazım olduğu kimi baş verdiyini göstərmək üçün qeyd analizatorumuza basdığımız nömrəni çıxaracağıq. ATmega328p -də Analogdan Rəqəmsal Dönüştürücüyü (ADC) istifadə edərkən işləyə biləcəyiniz bir çox çətinlik var. Yolda şeyləri bir neçə mərhələdə götürün və onlardan necə qaçınacağınızı anlayın. Niyə analoqdan rəqəmsal çeviriciyə istifadə etməyinizin mikrokontrolörünüzdə daha az liman istifadə etməsinə baxmayaraq bir klaviaturanı idarə etməyin ən yaxşı yolu olmadığını da görəcəyik. Bu təlimatda sizə lazım olacaq:
- klaviatura. Birini ala bilərsən, ya da mənim etdiyimi edə bilərsən və birini təmizləyə bilərsən.
- Klaviatura üçün 2 qadın başlığı (birini təmizləyirsinizsə)
- birləşdirən tellər
- çörək taxtası
- 4 1 Kohm rezistorlar
- 1 15 Kohm müqavimət
- 1 3.3 Kohm rezistor
- 1180 ohm müqavimət
- 1680 ohm müqavimət
- rəqəmsal multimetr
- Tutorial 5 -dən analizatorunuz
Zaten bir klaviaturainiz varsa və birini təmizləmək lazım deyilsə, ilk bir neçə addımı atmaq istəyə bilərsiniz.
AVR montajçı dərslərimin tam kolleksiyasına bir link:
Addım 1: Klaviatura 1 -dən məhrum olun
Uzun müddət əvvəl, hətta nənə və babanız hələ uşaq ikən insanlar bir -biri ilə ünsiyyət qurmaq üçün divara uzun kabellər bağlanmış bu qəribə görünüşlü cihazlardan istifadə edirdilər. Onlara "telefonlar" deyirdilər və adətən kimsə sizə zəng edəndə əsəbiləşən bir səs çıxaran ucuz plastik əşyalar idi (bu günkü "Justin Bieber" melodiyaları eyni dərəcədə əsəbiləşdirici deyil). Hər halda, bu cihazların üzərində çox sadə bir şəkildə bağlanmış klaviaturalar vardı və onları təmizləmək çox asandır və yenidən satın ala biləcəyiniz klaviatura üzərində 2 əlavə düymə ("yenidən zəng" və "flaş") var. "ox düymələri", "menyu düymələri" və ya başqa bir şey kimi. Köhnə bir telefondan bir klaviatura təmizləməklə başlayacağıq. Əvvəlcə telefonu götürün (şəkillərdə göstərildiyi kimi bir GE telefonu istifadə edirəm) və telləri açmaq üçün ayırın. Sonra bir kəsik götürün və klaviaturanı tutan kiçik plastik düymələri çıxarın və klaviaturanı çıxarın.
Addım 2: Klaviatura 2 -ni təmizləyin
İndi bir PVC mişar götürün və açar deliklərinin ətrafındakı plastikləri kəsin və sonra dərinliyi düzgün bir şəkildə əldə etmək üçün kənarını kəsin.
Sonra klaviaturanı son addımda üstlərini kəsdikdən sonra qalan kiçik dirəkləri istifadə edərək yenidən qoyun və bir lehimləmə dəmiri istifadə edərək isti dəmiri plastikin əriməsinə və hər tərəfə yayılmasına imkan verin. klaviaturanın altındakı düyməni əvvəlki kimi yerində saxlayacaq yeni "düymələr" meydana gətirir.
Üç spikeri və bəlkə də açar və lövhədə olmayan şeyləri təmizləməyi sevirəm. Ancaq bu dəfə açarları və əşyaları təmizləməyəcəyəm, çünki hazırda başqa məqsədlərimiz var. Ayrıca, telefon zəngi olan bir TA31002 xətti IC var. Məlumat cədvəli asanlıqla tapıla və yüklənə bilər. Bu səbəbdən onu lövhəyə lehimlə buraxacağam və sonra onunla oynayacağam. Bir osiloskopa bağlamaq və oradan hansı sərin siqnalları çıxara biləcəyimi görmək istərdim. Bəlkə də ondan bir qapı zəngi düzəlt. Kim bilir.
Hər halda telefonu məhv etməyi və hissələri təmizləməyi bitirdikdən sonra klaviatura hazırlamağı bitirəcəyik.
Addım 3: Klaviatura 3 -ü təmizləyin
Sökülmə fitili istifadə edin və klaviaturanın altındakı lent kabellərini çıxarın, elektron lövhədəki deliklərin açıq olduğundan əmin olun və sonra dəliklərin olduğu lövhəyə iki qadın başlıq bağlayın. Çox güman ki, başlıqlarınızı 4 pinli başlıqlar kimi kəsmək məcburiyyətində qalacaqsınız.
Başlıqlar bağlandıqdan sonra onu bir çörək taxtasına bağlaya, bir multimetr götürə və təsadüfi sancaqlar arasında multimetri yapışdıraraq və müqaviməti ölçərək düymələri sınaya bilərsiniz. Bu düymələri xəritələməyə imkan verəcəkdir. Dövrə baxaraq düymələrin çıxışlara necə bağlandığını görmək çətindir, ancaq bir multimetrdən istifadə etsəniz onu hər iki sancağa bağlaya bilərsiniz və sonra ekranda açıq dövrə əvəzinə bir rəqəm görənə qədər düymələri basa bilərsiniz.. Bu düymənin açarı olacaq.
Çıxış pinləri üçün bütün düymələri bu şəkildə xəritəyə salın.
Addım 4: Klaviaturanı bağlayın
İndi kabel sxemini izləyin və klaviaturanı çörək taxtanıza bağlayın.
Bunun necə işləyəcəyi 5V -ni sol tərəfə qoyacağıq və sağ tərəf GND -ə gedəcək. Diaqramdakı sağdakı ilk pin, Atmega328p mikrokontrolöründəki analog pinlərimizin birincisinə daxil olur. Düymələr olmadıqda siqnal 0V olacaq və fərqli düymələrin hər birinə basıldıqda analog porta giriş 0V ilə 5V arasında dəyişəcək, hansı düymənin basıldığından asılı olaraq fərqli miqdarda olacaq. Rezistor dəyərlərini hər yolun digərlərindən fərqli bir müqavimət ehtiva etməsi üçün seçdik. Mikro nəzarətçidəki analog port analoq siqnal alır və 0V ilə 5V arasında 1024 fərqli kanala bölür. Bu o deməkdir ki, hər bir kanalın eni 5V/1024 = 0.005 V/kanal = 5 mV/kanaldır. Belə ki, analog port 5 mV -dən çox fərqləndikləri müddətdə giriş gərginliklərini ayırd edə bilir. Bizim vəziyyətimizdə, müqavimət dəyərlərini seçdik ki, hər iki düyməni basmaq daha çox fərqlənən bir gərginlik siqnalı göndərsin, beləliklə mikrokontrolör hansı düymənin basıldığına asanlıqla qərar verə bilsin. Böyük problem, bütün sistemin çox səs -küylü olmasıdır, buna görə hər düyməni basmaq üçün bir sıra gərginlik seçməliyik - ancaq buna bir az sonra girəcəyik.
Nəzarətçiyə yalnız bir giriş xəttindən istifadə edərək 14 düyməli bir klaviaturanı idarə edə bildiyimizə diqqət yetirin. Bu analoq girişlərin faydalı cəhətlərindən biridir.
İndi klaviaturanı idarə etmək üçün ilk cəhdimiz bir düyməni basmaqdır ki, bir kəsmə baş versin, ara vermə alt proqramı analoq giriş portunu oxuyacaq və hansı düymənin basıldığına qərar verəcək və sonra bu nömrəni qeyd analizatoru alt proqramına çıxaracaq. Tutorial 5 -də qurduğumuz 8 LED -də ikili əsas dəyər.
Addım 5: Klaviaturanı Analizatorunuza bağlayın
Şəkillər, klaviaturanı mikrokontrolöre necə bağlamaq istədiyimizi göstərir ki, analizator ekranında çıxışı görə bilək. Əslində klaviaturadan çıxışı ATmega328P -də ADC0 olaraq da adlandırılan PortC pin 0 -a bağlayırıq.
Ancaq bir neçə əlavə şey var. PD2 -yə bir düyməni bağlayacağıq. Yəni 5V dəmir yolunuzdan bir düyməyə və düymənin digər tərəfindən PD2 -yə bir tel götürün və son olaraq, 5V rayımızdan AREF pinini ayırmaq və əvəzinə onu ayırmaq istəyirik. İstəsək 0.1 mikrofarad ayıran kondansatör daxil edə bilərik. Bunun üzərinə 104 yazılmış bir keramika kondansatörüdür. İlk iki rəqəm ədəddir və son rəqəm 10-un gücüdür və pikofaradlarda cavab almaq üçün onu vururuq (pico 10^-12 deməkdir), beləliklə 104, 10 x 10^4 pikofarad deməkdir, eyni 100 nanofarad (nano 10^-9 deməkdir), bu da 0,1 mikrofarad (mikro deməkdir 10^-6) ilə eynidir. Hər halda, bütün bunlar AREF pinini istinad pinimiz kimi istifadə edə biləcəyimiz zaman sabitləşdirməkdir.
PD2 ilə torpaq arasında 1 Mohm rezistor da istəyirik. PD2 -ni 0V -də bir çıxış pimi olaraq təyin edəcəyik və bu pində müsbət bir kənarda tetikleyeceğiz. Düyməni buraxdığımız zaman kənarın dərhal yox olmasını istəyirik ki, bu "aşağı çəkin" rezistorunu daxil edək.
Düyməni istəməyimizin səbəbi, PD2 olan çipdəki INT0 pinindən Analog-Rəqəmsal çeviricimizi işə salmaq istəməyimizdir. Nəhayət, düymənin həm ADC -ni işə salmasını, həm də girişin ayrı bir düyməyə sahib olmadan çevrilməsini təmin etməsini istərdik, ancaq işləmə müddətinə görə ADC -ni işə salmaq üçün ayrı bir düyməyə sahib olaraq başlayacağıq və hamısını ütülədikdən sonra. səhvlər aradan qalxdı və hər şeyin düzgün işlədiyinə əminik, sonra oxumaq istədiyimiz düyməni basmaqla gələn səs -küy və zaman məsələlərini həll edəcəyik.
Beləliklə, hələlik, işləmə üsulu bir düyməni basıb saxlayacağıq, sonra ADC -ni işə salmaq üçün düyməni basacağıq və sonra buraxın və inşallah basdığımız düymənin ikili dəyəri analizatorda görünəcək.
Buna görə də bunu yerinə yetirəcək bir neçə kod yazaq.
Addım 6: Hansı keçid açarlarını təyin etməliyik?
Gəlin əvvəlcə bunu necə kodlaşdıracağımızı düşünək ki, nəzarətçi klaviaturadan daxil olan məlumatları oxuya bilsin və düyməni sıxılmış düyməyə uyğun bir rəqəmə çevirə bilsin. Atmega328p -də quraşdırılmışdır. Referans gərginliyimiz olaraq AREF -dən istifadə edəcəyik və klaviatura çıxışımız PortC0 və ya PC0 -a bağlanacaq. Diqqət yetirin ki, bu pin Analog-Rəqəmsal Dönüştürücü 0 üçün ADC0 olaraq da adlandırılır. ATmega328P üçün kəsilmələr haqqında Bölmə 12.4 və Analogdan Rəqəmsal Dönüştürücünün 24-cü fəslini oxumamağınızdan əvvəl yaxşı bir fikir ola bilər. Analog giriş siqnalı ilə nə edəcəyini və proqramımızla necə əlaqə quracağını bilən mikrokontrolörü qurmaq üçün əvvəlcə müxtəlif ADC -lərdən bir neçəsini qurmalıyıq. əlaqəli qeyd bitləri. Bunlar əsasən ilk kompüterlərdəki köhnə keçid açarlarına bərabərdir. Ya bir açarı AÇIR və ya SÖKTÜRÜRSÜZ, ya da bir kənara başqa bir kabel ilə bağlayarsınız ki, yolda olan çəngələ çatan elektronlar bir qapının bağlı olduğunu, digərinin isə labirintdə fərqli bir yola girməyə məcbur olduğunu görərlər. dövrə və beləliklə fərqli bir məntiqi vəzifə yerinə yetirir. Assambleya dilində kodlaşdırarkən, mikrokontrolörün bu funksiyalarına yaxından daxil oluruq ki, bu da ilk növbədə bunu etməklə bağlı cəlbedici şeylərdən biridir. Daha çox "əllər" dir və daha az "pərdə arxasında" olduğu kimi davam edir. Buna görə də bu reyestrlərin qurulmasını yorucu bir iş kimi düşünməyin. Montaj dilini maraqlı edən budur! Çipin daxili işlənməsi və məntiqi ilə çox şəxsi bir əlaqə qururuq və onu tam olaraq istədiyimizi etməyə məcbur edirik - nə artıq, nə də az. Boşa gedən saat dövrü yoxdur, buna görə də təyin etməyimiz lazım olan açarların siyahısı:
- Güc Azaldılması ADC bitini, PRR qeydinin 0 biti olan PRADC -ni söndürün, çünki bu bit varsa ADC -ni bağlayacaq. Gücün azaldılması reyestri, əslində ehtiyacınız olmadığı zaman enerjidən istifadə edən müxtəlif şeyləri bağlamağın bir yoludur. ADC -dən istifadə etdiyimiz üçün bu şəkildə əlil olmadığından əmin olmaq istəyirik. (Bax PRADC, səhifə 46)
- ADC Multiplexer Selection (ADMUX) reyestrində MUX3… 0-ı söndürərək ADC0 olmaq üçün analoq giriş kanalını seçin (Cədvəl 24-4-ə baxın. 249) bunlar artıq standart olaraq söndürülmüşdür, buna görə də həqiqətən buna ehtiyacımız yoxdur. Ancaq ADC0 -dan başqa bir liman istifadə etsəniz, bu açarları müvafiq olaraq dəyişdirməlisiniz. Müxtəlif MUX3, MUX2, MUX1, MUX0 birləşmələri hər hansı bir analog portu giriş olaraq istifadə etməyə imkan verir və eyni anda bir çox fərqli analoq siqnalına baxmaq istəyirsinizsə bunları da dəyişə bilərsiniz.
- ADMUX reyestrindəki REFS0 və REFS1 bitlərini söndürün ki, AREF -i daxili istinad deyil, istinad gərginliyimiz kimi istifadə edək (Bax. Səhifə 248).
- ADMUX -da ADLAR bitini yandırın, nəticənin "sola düzəldilməsi" üçün bu seçimi növbəti addımda müzakirə edəcəyik.
- PC0 -ya rəqəmsal girişi söndürmək üçün ADC0D bitini Digital Input Disable Register -ə (DIDR0) daxil edin. Bu portu analog giriş üçün istifadə edirik, buna görə də rəqəmsal girişi deaktiv edə bilərik.
- INT0 pininə (PD2) bir gərginlik siqnalının yüksələn kənarında tətik etmək istədiyimizi bildirmək üçün ISC0 və ISC1 -i Xarici Kəsmə Nəzarət Reyestrinə A (EICRA) daxil edin, səhifə 71 -ə baxın.
- Bu pimdə kəsilmələrdən istifadə etmədiyimizi göstərmək üçün Xarici kəsilmə maskası reyestrində (EIMSK) INT0 və INT1 bitlərini təmizləyin. Bu pində kəsilmələri təmin etsəydik, 0x0002 ünvanında bir kəsmə işləyicisinə ehtiyacımız olardı, amma bunun əvəzinə bu pindəki bir siqnalın ADC çevrilməsini tetikleyeceği şəkildə qururuq, tamamlanması ADC çevrilməsinin tam kəsilməsi ilə aparılır. ünvan 0x002A. 72 -ci səhifəyə baxın.
- ADC -ni işə salmaq üçün ADC nəzarətində və status qeyd A -da (ADCSRA) ADC Enable (ADEN) bitini (bit 7) təyin edin. 249 səhifəsinə baxın.
- Hər dəfə analoq siqnalını oxumaq istədiyimiz zaman ADC başlanğıc dönüşüm bitini (ADSC) təyin edərək tək bir çevrilməyə başlaya bilərik, amma indiyə qədər kimsə düyməni basdıqda avtomatik olaraq oxumasını istərdik, bunun əvəzinə ADC -ni işə salacağıq. Autotrigger, ADCSRA reyestrində aktivləşdirmə (ADATE) bitini işə salır, belə ki tetikleme avtomatik olaraq aparılır.
- ADPS2..0 bitini (AD Prescalar bitləri) 111 olaraq qoyduq ki, ADC saatı 128 -ə bölünən CPU saatı olsun.
- AD2 -nin PD2 olaraq işə salınmasının mənbəyini seçəcəyik ki, bu da INT0 (Xarici Kəsmə İstəyi 0) adlanır. Bunu ADCSRB reyestrindəki müxtəlif bitləri dəyişdirərək edirik (bax: Cədvəl 24-6, səhifə 251). Cədvəldən görürük ki, ADTS0 -ı söndürmək, ADTS1 -i açmaq və ADTS2 -ni söndürmək istəyirik ki, ADC bu pimi tetikleyecek. Diqqət yetirin ki, analoq portu davamlı olaraq nümunə götürmək istəsək, bir az fasiləsiz analoq siqnal oxuyuruq (məsələn, səs nümunəsi və ya başqa bir şey) bunu Sərbəst Çalışma Rejiminə təyin edərdik. PD2 -də tetiklemeyi təyin etmək üçün istifadə etdiyimiz üsul, kəsilməyə səbəb olmadan PC0 analog portunun ADC oxumasını tetikler.
- ADCSRA reyestrində ADC Interrupt Enable (ADIE) bitini aktivləşdirin ki, analoqdan rəqəmsal çevrilmə tamamlandıqda bir kəsmə əmələ gətirə bilək.
- Kesintiləri təmin etmək üçün SREG -də I bitini təyin edin.
Təcrübə 1: Yuxarıdakı parametrlərin hər biri üçün məlumat cədvəlindəki müvafiq bölmələri oxuduğunuzdan əmin olun ki, nələrin baş verdiyini və alternativ parametrlərə dəyişdirsək nə olacağını başa düşəsiniz.
Addım 7: Kəsmə İşləyicisini yazın
Son addımda, PD2 -də aşkarlanan yüksələn bir kənarın PC0 -da rəqəmsal çevrilməyə bənzəyəcəyini tetikleyecek şekilde qurduğumuzu gördük və bu dönüşüm tamamlandıqda bir ADC Dönüşüm Tamamlandı ara verər. İndi bu fasilə ilə bir şey etmək istəyirik. Səhifə 65-də Cədvəl 12-6-ı araşdırsanız, mümkün fasilələrin siyahısını görəcəksiniz. Əvvəlki Dərsliklərdə 0x0000 ünvanında RESET və 0x0020 ünvanında Timer/Counter0 Overflow -un kəsilməsini artıq gördük. İndi 0x002A ünvanında cədvəldə gördüyümüz ADC fasiləsinə baxmaq istəyirik. Beləliklə, montaj dil kodumuzun əvvəlində oxuyan bir sətrə ehtiyacımız olacaq:
.org 0x002Arjmp ADC_int
ADC bir dönüşümü tamamladıqda ADC_int etiketli kəsmə işləyicimizə keçəcək. ADC -nin işləmə üsulu aşağıdakı hesablamanı yerinə yetirməkdir:
ADC = Vin x 1024 / Vref
Klaviaturadakı "yenidən yığ" düyməsini bassam nə olacağını görək. Bu vəziyyətdə PC0 -dakı gərginlik 1,52V deyək və Vref 5V -də olduğu üçün bir dəyərə dəyişəcək:
ADC = (1.52V) x 1024 / 5V = 311.296
və buna görə 311 olaraq görünəcək. Bunu geriliyə çevirmək istəsək, hesablamanı tərsinə çevirərdik. Faktiki gərginliklər aralarındakı fərqlə maraqlanmadığımız üçün buna ehtiyacımız olmayacaq. Dönüşüm başa çatdıqda, nəticə ADCH və ADCL qeydlərində yerləşdirilən 10 bitlik bir nömrədə saxlanılır və bunun "sola tənzimlənməsinə" səbəb olduq ki, bu da 10 bitin ADCH-nin 7-ci bitindən başlayaraq aşağıya enməsi deməkdir. ADCL bit 6 (bu iki qeyddə cəmi 16 bit var və onlardan yalnız 10 -dan istifadə edirik, yəni 1024 kanal). ADMUX reyestrində ADLAR bitini silmək istəsək nəticəni "sağa düzəldə bilərik". Sola tənzimlənməsini seçməyimizin səbəbi, siqnallarımızın kifayət qədər uzaq olması və kanal nömrəsinin son iki rəqəminin uyğun olmamasıdır. yəqin ki, sadəcə səs -küydür, buna görə də düymələri yalnız yuxarı 8 rəqəmdən istifadə edərək ayıracağıq, başqa sözlə desək, hansı düymənin basıldığını anlamaq üçün ADCH -ə baxmalıyıq. qeydiyyatdan keçin, bu nömrəni klaviatura dəyərinə çevirin və sonra bu dəyəri qeyd analiz cihazımızın LED -lərinə göndərin ki, "9" yazmağının "00001001" ə uyğun olan LED -lərin yanmasına səbəb olacağını yoxlaya bilək. Müxtəlif düymələri basdığımızda ADCH -də nələrin göründüyünü əvvəlcə görməliyik. ADCH məzmununu analizator ekranına göndərən sadə bir kəsmə işləyicisi yazaq.
ADC_int: lds analizatoru, ADCH; ADCH dəyərini analizatorumuza yüklə EIFR, 0; yenidən kəsilməyə hazır olması üçün xarici kəsmə bayrağını silin
İndiyə qədər 5 -ci dərslikdəki analizatorumuzdan kodu kopyalaya və bu kəsilməni və keçid parametrlərini əlavə edib işə salmalısınız. Məşq 2: Kodu yazın və işlədin. Analizatorunuzun ekranında ADCH göstərməsini əldə etdiyinizə baxın. Eyni düyməni bir neçə dəfə basmağa çalışın. ADCH -də həmişə eyni dəyəri alırsınız?
Addım 8: Düymələrin dəyərlərini xəritəyə salın
İndi etməmiz lazım olan şey, ADCH -dəki dəyərləri basılan düyməyə uyğun rəqəmlərə çevirməkdir. Bunu hər düyməni basmaq üçün ADCH -in məzmununu yazaraq sonra şəkildəki kimi ondalık bir rəqəmə çevirərək edirik. Fasilə idarə etmə rutinimizdə, hər bir düyməni basmağa uyğun bir dəyər aralığını nəzərdən keçirəcəyik ki, ADC bu aralığdakı hər hansı bir şeyi bir düyməni basaraq eşleyecek.
Məşq 3: Bu xəritəni edin və sonra ADC ara vermə rejiminizi yenidən yazın.
Mənim üçün aldığım budur (çox güman ki, sizinki fərqli olacaq). Diqqət yetirin ki, hər düyməni basmaq üçün bir sıra dəyərlər təyin etdim.
ADC_int:; Xarici müdaxilə işçisi analizatoru; yeni nömrə düymələrinə hazırlaşınH, ADCH; ADCH, clccpi buttonH, 240brlo PC+3 oxunduqda ADC yeniləyir; ADCH daha böyükdürsə, bu 1ldi analizatorudur, 1; 1rjmp qaytarma ilə analizatoru yükləyin; və clccpi düyməsini qaytarınH, 230; ADCH daha böyükdürsə, 2brlo PC+3ldi analizatoru, 2rjmp clccpi düyməsi H, 217brlo PC+3ldi analizatoru, 3rjmp qayıt clccpi düyməsiH, 203brlo PC+3ldi analizatoru, 4rjmp qayıt clccpi düyməsiH, 187brlo PC+3ldi analizatoru, 5rjmp qayıt clccpi düyməsi 155brlo PC+3ldi analizatoru, 6rjmp qaytar clccpi düyməsiH, 127brlo PC+3ldi analizatoru, 255; flaşı bütün onrjmp qaytar clccpi düyməsiH, 115brlo PC+3ldi analizatoru, 7rjmp qayıt clccpi düyməsiH, 94brlo PC+3ldi analizatoru, 8rjmp qayıt clccpi düyməsiH, 62brlo PC+3ldi analizatoru, 9rjmp clccpi düyməsiH, 37brlo PC+3ldi analizatoru, 0b11110000; ulduz üst yarısı onrjmp qaytar clccpi düyməsiH, 28brlo PC+3ldi analizatoru, 0rjmp qayıt clccpi düyməsiH, 17brlo PC+3ldi analizatoru, 0b00001111; hash işarəsi alt yarım onrjmp qayıt clccpi düyməsiH, 5brlo PC+3ldi analizatoru, 0b11000011; yenidən zəng yuxarı 2 alt 2rjmp geri ldi analizatoru, 0b11011011; əks halda xəta baş verdi: reti
Addım 9: Versiya 1 üçün Kod və Video
Klaviatura sürücüsünün bu ilk versiyası üçün kodumu əlavə etdim. Bu vəziyyətdə, ADC -nin klaviaturadan girişi oxumasına səbəb olmaq üçün düyməni və sonra düyməni basmalısınız. İstədiyimiz heç bir düymə deyil, bunun yerinə çevrilmə siqnalı düymənin özündən gəlir. Təlim 3: Bu kodu yığın və yükləyin və sınayın. Müxtəlif çevrilmə həddlərini, ehtimal ki, mənimkindən fərqli olduğu üçün düymələrinizin gərginliyinə uyğun olaraq dəyişdirməli ola bilərsiniz. Düymənin əvəzinə həm ADC0 üçün, həm də xarici kəsmə pimi üçün klaviatura girişindən istifadə etməyə çalışsanız nə olar? Mən də düymə sürücüsünün bu ilk versiyasının işinin videosunu əlavə edəcəyəm. kodumda Stack Pointer başlatan bir bölmə var. Dəyişənləri manipulyasiya edərkən yığını basmaq və çıxartmaq istəyə biləcəyimiz müxtəlif qeydlər var və nəyi yox, sonra da saxlamaq və bərpa etmək istəyə biləcəyimiz qeydlər var. Məsələn, SREG, fasilələr arasında qorunmayan bir qeyddir, buna görə bir şeyin ortasında bir kəsilmə baş verərsə əməliyyatlar nəticəsində qurulan və təmizlənən müxtəlif bayraqlar dəyişdirilə bilər. Buna görə, SREG -ni bir kəsmə işləyicisinin əvvəlində yığın üzərinə itələsəniz və sonra kəsmə işləyicisinin sonunda yenidən açsanız yaxşı olar. Bunu necə başladığını göstərmək və sonra necə ehtiyacımız olacağını əvvəlcədən bilmək üçün kodu yerləşdirdim, amma kodumuzdakı fasilələr zamanı SREG -in nə olacağına əhəmiyyət vermədiyimiz üçün bunun üçün yığını istifadə etmədim. başlatma zamanı qeydlərdə müxtəlif bitləri təyin etmək üçün shift əməliyyatından istifadə etdiyimi. Məsələn, sətirdə:
ldi tempi, (1 <
Yuxarıdakı kodun ilk sətrindəki "<<" əmri bir keçid əməliyyatıdır. Əsasən 0b00000001 olan ikili nömrəni alır və ISC01 sayının miqdarı ilə sola keçir. Bu, EICRA reyestrində ISC01 adlı bitin mövqeyidir. ISC01 bit 1 olduğundan 1 nömrəsi 0b00000010 olmaq üçün sol 1 mövqeyə keçir. Eynilə ikincisi, ISC00, EICRA -nın 0 bitidir və buna görə də 1 rəqəminin dəyişməsi sola sıfır mövqedir. İlk təlimatda yüklədiyiniz və o zamandan bəri evrr istifadə etdiyiniz m328Pdef.inc faylına bir daha nəzər salsanız, bunun ".equ" ifadələrinin uzun bir siyahısı olduğunu görəcəksiniz. ISC01 -in 1 -ə bərabər olduğunu görəcəksiniz. Assembler heç bir şey yığmağa başlamazdan əvvəl onun hər nümunəsini 1 ilə əvəz edir. İnsanlar bizə kodu oxumaq və yazmaqda kömək etmək üçün qeydiyyat bitlərinin adlarıdır. İndi yuxarıdakı iki növbə əməliyyatı arasındakı şaquli xətt məntiqi "və ya" əməliyyatdır. Budur tənlik:
0b00000010 | 0b00000001 = 0b00000011
və tempə yüklədiyimiz budur ("ldi" istifadə edərək). İnsanların bu metodu istifadə edərək dəyərləri bir reyestrə yükləməsinin səbəbi, bir ədədin yerinə bitin adını istifadə etməsinə imkan verməsi və kodu oxumağı çox asanlaşdırmasıdır. İstifadə etdiyimiz digər iki üsul da var. "Ori" və "andi" təlimatlarından istifadə edirik. Bunlar, reyestrdəki digər bitləri dəyişdirmədən sırasıyla bitləri SET və TEMİZLƏMƏ imkan verir. Məsələn, istifadə edərkən
ori temperatur, (1
0b00000001 ilə bu "və ya" tempi sıfır bitinə 1 qoyur və qalanını dəyişməz qoyur. Həm də yazanda
andi tempi, 0b11111110
bu sıfır tempini sıfıra dəyişir və qalanını dəyişməz qoyur.
Məşq 4: Kodu keçməlisiniz və hər sətri başa düşdüyünüzdən əmin olmalısınız. Bir şey etmək üçün daha yaxşı üsullar tapmaq və daha yaxşı bir proqram yazmaq maraqlı ola bilər. Şeyi kodlaşdırmağın yüz yolu var və əminəm ki, mənimkindən daha yaxşı bir yol tapa bilərsiniz. Səhv və nöqsanları da (cənnətdən qorusun!) Tapa bilərsiniz. Bu vəziyyətdə, düzəltmək üçün onlar haqqında eşitmək istərdim.
Tamam, indi baxaq görək o artıq düymədən necə qurtula bilərik …
Addım 10: Versiya 2 üçün kod
Düymədən qurtulmağın ən sadə yolu, onu tamamilə silmək, PB2 girişini unutmaq və sadəcə ADC -ni "Sərbəst Çalışma Rejiminə" keçirməkdir.
Başqa sözlə, sadəcə ADCSRB qeydini dəyişdirin ki, ADTS2, ADTS1 və ADTS0 hamısı sıfırdır.
Sonra ADCSRA -da ADSC bitini ilk çevrilməyə başlayacaq 1 olaraq təyin edin.
İndi mikrokontrolörünüzə yükləyin və düyməni basarkən və yalnız düyməni basarkən ekranda doğru nömrənin gəldiyini görəcəksiniz. Bunun səbəbi, ADC -nin davamlı olaraq ADC0 portundan nümunə götürməsi və dəyəri göstərməsidir. Barmağınızı düymədən çıxardığınız zaman "düymə sıçrayışı" bir neçə təsadüfi dəyərin çox tez meydana gəlməsinə səbəb olacaq və sonra yenidən 0V girişinə yerləşəcək. Kodumuzda bu 0V 0b11011011 olaraq görünür (çünki "0" düyməsini basmaq artıq 0b00000000 ekran dəyərindən istifadə edir)
Bu iki səbəbdən istədiyimiz həll yolu deyil. Əvvəlcə düyməni basıb saxlamaq istəmirik. Bir dəfə basmaq və nömrəni göstərmək istəyirik (və ya sonrakı bir dərsdə bəzi yeni kodlarda istifadə olunur). İkincisi, ADC0 -dan davamlı olaraq nümunə götürmək istəmirik. İstəyirik ki, bir dəfə oxunsun, çevrilsin və sonra yeni bir düyməni basaraq yeni bir çevrilməyə səbəb olana qədər yatsın. Pulsuz işləmə rejimi, mikrokontrolörün etməsini istədiyiniz yeganə şey, hər hansı bir analoq girişi mütəmadi olaraq oxumaqdır - məsələn, real vaxt temperaturlarını və ya başqa bir şeyi göstərmək istəsəniz.
Beləliklə, başqa bir həll yolu tapaq …
Addım 11: Düymədən Necə qurtulmalıyıq? Versiya 3
Davam edə biləcəyimiz bir çox yol var. Əvvəlcə düyməni qurtarmaq üçün hardware əlavə edə bilərik. Məsələn, düymənin çıxış xəttində bir cərəyana tranzistor qoymağa cəhd edə bilərik ki, çıxışdan kiçik bir cərəyan alsın və PD2 kəsmə pininə 5V bir nəbz göndərsin.
Bununla birlikdə, bu, ən azından çox gürültülü olardı və ən pis halda, dəqiq bir düyməni basmaq üçün kifayət qədər vaxt verməzdi, çünki klaviaturanın gərginlik çıxışı ADC oxunuşu çəkilməzdən əvvəl sabitləşməyə vaxt tapmayacaq.
Buna görə bir proqram həllini tapmağı üstün tuturuq. Etmək istədiyimiz şey, PD2 pininə bir kəsmə əlavə etmək və bunun üçün klaviatura pininin tək oxunmasını tələb edən bir kəsmə işləyicisi yazmaqdır. Başqa sözlə, ADC -dən autotrigger fasiləsindən xilas oluruq və ADC -ni içəriyə çağıran xarici bir kəsmə əlavə edirik. Bu şəkildə ADC oxumaq siqnalı, PD2 siqnalı artıq meydana gəldikdən sonra gəlir və bu, PC0 pininin oxunub çevrilməsindən əvvəl dəqiq bir gərginliyə sabitlənmək üçün kifayət qədər vaxt verə bilər. Hələ də nəticəni analizatorun ekranına çıxaran bir ADC tamamlama fasiləsi olardı.
Mənasızdır? Yaxşı, bunu edək …
Əlavə edilmiş yeni koda baxın.
Aşağıdakı dəyişiklikləri görürsünüz:
- INT0 xarici kəsilməsini idarə etmək üçün.org 0x0002 ünvanına bir rjmp əlavə etdik
- INT0 pinində kəsmək istədiyimizi bildirmək üçün EIMSK reyestrini dəyişdirdik
- Avtomatik yükləməni aradan qaldırmaq üçün ADCSRA qeydindəki ADATE pinini dəyişdirdik
- ADATE söndürüldükdə əlaqəsi olmadığı üçün ADCSRB parametrlərindən qurtulduq
- Xarici tətik bayrağını yenidən sıfırlamaq məcburiyyətində deyilik, çünki INT0 ara vermə proseduru tamamlandıqda bunu avtomatik olaraq yerinə yetirir - əvvəllər ara vermə prosedurumuz yox idi, sadəcə ADC -ni həmin pində bir siqnalın söndürülməsinə səbəb olmuşduq. o bayrağı əllə sil.
İndi kəsmə işləyicisində sadəcə ADC -dən tək bir dönüşüm çağırırıq.
Məşq 5: Bu versiyanı işə salın və nə baş verdiyini görün.
Addım 12: İşçi versiyası üçün kod və video
Son versiyada gördüyümüz kimi, düymə kəsmə çox yaxşı işləmir, çünki kəsmə PD2 -ni bağlamaq üçün yüksələn bir kənarda tetiklenir və sonra kəsmə işçisi ADC çevrilməsini çağırır. Bununla birlikdə, ADC sabitləşmədən əvvəl gərginlik oxunuşunu alır və buna görə də cəfəngiyat oxuyur.
Bizə lazım olan şey PD2 -də kəsilmə ilə PC0 -da ADC oxunması arasında gecikmə yaratmaqdır. Bunu bir taymer/sayğac, sayğac daşması kəsilməsi və gecikmə rutini əlavə edərək edəcəyik. Xoşbəxtlikdən, bunu Tutorial 3 -dən necə edəcəyimizi artıq bilirik! Beləliklə, yalnız oradan müvafiq kodu kopyalayıb yapışdıracağıq.
Nəticədə kodu və işlək vəziyyətdə olduğunu göstərən bir video verdim.
Oxumaların gözlədiyiniz qədər dəqiq olmadığını görəcəksiniz. Çox güman ki, bu bir çox mənbədən qaynaqlanır:
- PC0 -da oxunuşa təsir edən PD2 -ni işə salmaq üçün klaviaturanın gərginlik çıxışından vururuq.
- Ən yaxşı oxumaq üçün tətikdən sonra nə qədər gecikməli olduğumuzu bilmirik.
- ADC dönüşümünün tamamlanması üçün bir neçə dövr lazımdır ki, bu da klaviaturada sürətli atəş aça bilməyəcəyimiz deməkdir.
- yəqin ki, klaviaturanın özündə səs -küy var.
- və s…
Beləliklə, klaviaturanı işə salmağı bacarsaq da, indi onu analizator ekranına çıxarmaq əvəzinə düymələri başqa bir şəkildə istifadə edərək tətbiqlərdə istifadə edə bilsək də, bu çox dəqiq deyil və çox əsəbidir. Bu səbəbdən klaviatura ilə əlaqə qurmağın ən yaxşı yolunun, klaviaturadan çıxan hər şeyi fərqli bir porta yapışdırmaq və hansı düymələrin hansı gərginlik gördüyünə qərar vermək olduğunu düşünürəm. Bu asan, çox sürətli və çox dəqiqdir.
Əslində, klaviaturanı burada etdiyimiz kimi idarə etmək istəməsinin yalnız iki səbəbi var:
- Mikro nəzarətçimizdəki 8 yox, yalnız 2 sancaqdan istifadə edir.
- ADC-nin mikrokontrolördə fərqli cəhətlərini göstərmək üçün əla bir layihədir ki, orada tapa biləcəyiniz standart şeylərdən fərqli olaraq temperatur oxunuşları, potansiyometrləri çevirmək və s. Tətik edilmiş tək oxunuşlar və xarici pin avtomatik tetikleme nümunəsi istədim. yalnız pulsuz çalışan CPU-gobbling rejimi deyil.
Hər halda, sizin üçün son bir neçə məşq var:
Məşq 6: Axtarış Cədvəlindən istifadə etmək üçün ADC çevrilməsinin tam kəsmə işləyicisini yenidən yazın. Yəni Beləliklə, analoq dəyərini cədvəldəki ilk maddə ilə sınayır və daha böyükdürsə, kəsilmədən geri qayıdır, əgər deyilsə, Z -ni cədvəldəki növbəti maddəyə artırır və yenidən testə qayıdır. Bu, kodu qısaldır və fasilə rejimini təmizləyəcək və daha gözəl görünəcək. (Növbəti addım olaraq mümkün bir həll verəcəyəm) Məşq 7: Klaviaturanızı mikrokontrolörün 8 sancağına bağlayın və bunun üçün sadə sürücünü yazın və nə qədər gözəl olduğunu yaşayın. Metodumuzun daha yaxşı işləməsi üçün bir neçə yol düşünə bilərsinizmi?
Hamısı bu dərs üçün. İşarələrlə son versiyanı əlavə etdim. Son hədəfimizə yaxınlaşdıqca, yeddi seqmentli ekranın necə idarə olunacağını göstərmək üçün (və telefon klaviaturasındakı əlavə düymələrdən istifadə edən maraqlı bir şey qurmaq üçün) Tutorial 9 -da bir dəfə də klaviaturadan istifadə edəcəyik. Bunun əvəzinə düymələri basaraq hər şeyi idarə etməyə keçin (çünki bu metod bu dərsliklər üzərində qurduğumuz son məhsula daha uyğun gəlir) və biz sadəcə klaviaturanı rəfə qoyacağıq.
Gələn dəfə görüşənədək!
Tövsiyə:
AVR Assembler Dərsliyi 1: 5 Addımlar
AVR Assembler Dərsliyi 1: Arduinoda istifadə olunan mikro nəzarətçi olan Atmega328p üçün montaj dili proqramlarının necə yazılacağına dair bir sıra dərsliklər yazmağa qərar verdim. İnsanlar maraqlanmağa davam edərlərsə, tükənənə qədər həftədə bir dəfə çıxarmağa davam edəcəyəm
AVR Assembler Dərsliyi 6: 3 Addımlar
AVR Assembler Tutorial 6: Tutorial 6 -ya xoş gəldiniz! Bugünkü dərsimiz, bir atmega328p ilə digərini birləşdirən iki portdan istifadə edərək məlumat ötürmək üçün sadə bir üsul hazırlayacağımız qısa bir dərs olacaq. Daha sonra Tutorial 4 və Register -dən zar silindrini götürəcəyik
AVR Assembler Dərsliyi 8: 4 Addımlar
AVR Assembler Tutorial 8: Tutorial 8 -ə xoş gəldiniz! Bu qısa dərsdə, prototipləşdirmə komponentlərimizi ayrı bir "çapa" necə köçürməyimizi göstərmək üçün montaj dili proqramlaşdırmasının yeni aspektlərini təqdim etməkdən bir az yayınacağıq. dövrə lövhəsi
AVR Assembler Dərsliyi 9: 7 Addımlar
AVR Assembler Tutorial 9: Tutorial 9.-a xoş gəldiniz Bu gün ATmega328P və AVR montaj dil kodumuzdan istifadə edərək həm 7 seqmentli ekranı, həm də 4 rəqəmli ekranı necə idarə edəcəyimizi göstərəcəyik. Bunu edərkən yığını necə istifadə edəcəyimizə dair fikirlərimizi dəyişməliyik
AVR Assembler Dərsliyi 11: 5 Addımlar
AVR Assembler Tutorial 11: Tutorial 11 -ə xoş gəldiniz! Bu qısa dərsdə, nəhayət, son layihəmizin ilk hissəsini hazırlayacağıq. Etməli olduğunuz ilk şey bu təlimatın son mərhələsinə keçmək və videoya baxmaqdır. Sonra bura qayıt. [sən durarkən