İçindekiler:
- Adım 1: Bir Tuş Takımını Temizleme 1
- Adım 2: Bir Tuş Takımı 2'yi temizleyin
- 3. Adım: Bir Tuş Takımı 3'ü temizleyin
- Adım 4: Tuş Takımını Kablolayın
- Adım 5: Tuş Takımını Analizörünüze Bağlayın
- Adım 6: Hangi Geçiş Anahtarlarını Ayarlamalıyız?
- Adım 7: Kesinti İşleyicisini Yazın
- Adım 8: Tuşa Basma Değerlerinin Haritasını Çıkarın
- 9. Adım: Sürüm 1 için Kod ve Video
- Adım 10: Sürüm 2 için Kod
- Adım 11: Düğmeden Nasıl Kurtuluruz? Sürüm 3
- Adım 12: Çalışan Sürüm için Kod ve Video
Video: AVR Assembler Eğitimi 7: 12 Adım
2024 Yazar: John Day | [email protected]. Son düzenleme: 2024-01-30 13:16
Eğitim 7'ye hoş geldiniz!
Bugün ilk olarak bir keypad'in nasıl taranacağını göstereceğiz ve ardından keypad ile haberleşmek için Analog giriş portlarının nasıl kullanılacağını göstereceğiz. Bunu, giriş olarak kesmeler ve tek bir kablo kullanarak yapacağız. Tuş takımını, her tuşa basılan analog girişe, hangi tuşa basıldığını voltaj ile ayırt etmemizi sağlayacak benzersiz bir voltaj gönderecek şekilde bağlayacağız. Ardından, her şeyin olması gerektiği gibi olduğunu göstermek için basılan sayıyı kayıt analizörümüze göndereceğiz. ATmega328p'de Analogdan Dijitale Dönüştürücüyü (ADC) kullanırken karşılaşabileceğiniz bir takım tuzaklar vardır ve bu yüzden biz de yapacağız. Onları nasıl önleyeceğinizi bulmak için yolda birkaç aşamada bir şeyler alın. Mikrodenetleyicinizde daha az bağlantı noktası kullanmasına rağmen analogdan dijitale dönüştürücü kullanmanın neden bir tuş takımını kontrol etmenin en iyi yolu olmadığını da göreceğiz. Bu eğitimde şunlara ihtiyacınız olacak:
- bir tuş takımı. Bir tane satın alabilirsin ya da benim yaptığımı yapıp bir tane temizleyebilirsin.
- Tuş takımı için 2 dişi başlık (birini atıyorsanız)
- bağlantı telleri
- ekmek tahtası
- 4 1 Kohm dirençleri
- 1 15 Kohm direnci
- 1 3.3 Kohm direnci
- 1 180 ohm direnç
- 1 680 ohm direnç
- dijital multimetre
- Eğitim 5'teki analizörünüz
Zaten bir tuş takımınız varsa ve bir tane atmanız gerekmiyorsa, ilk birkaç adımı atlamak isteyebilirsiniz.
İşte AVR montajcı eğitimlerimin tam koleksiyonuna bir bağlantı:
Adım 1: Bir Tuş Takımını Temizleme 1
Uzun zaman önce, büyükanne ve büyükbabanız bile çocukken, insanlar birbirleriyle iletişim kurmak için duvara uzun kablolar takılı olan bu tuhaf görünümlü cihazları kullanırlardı. Bunlara "telefon" deniyordu ve genellikle biri sizi aradığında rahatsız edici bir ses çıkaran ucuz plastik şeylerdi (bugünkü "Justin Bieber" zil sesleri aynı derecede rahatsız edici değil). Her durumda, bu cihazların üzerlerinde çok basit kablolu ve bu nedenle temizlemesi kolay tuş takımları vardı ve üzerlerinde satın alabileceğiniz ve yeniden kullanmak isteyebileceğiniz tuş takımlarından 2 ekstra tuş ("tekrar arama" ve "flaş") var. "ok tuşları", "menü tuşları" veya başka bir şey olarak. Bu yüzden eski bir telefondan bir tuş takımını temizleyerek başlayacağız. Önce telefonu alın (resimde gösterildiği gibi bir GE kullanıyorum) ve kabloları ortaya çıkarmak için ayırın. Ardından bir keski alın ve tuş takımını tutan küçük plastik düğmeleri kırın ve tuş takımını çıkarın.
Adım 2: Bir Tuş Takımı 2'yi temizleyin
Şimdi bir PVC testere alın ve anahtar deliklerinin etrafındaki plastiği kesin ve ardından ince bir tuş takımı bırakarak derinliği elde etmek için kenardan kesin.
Ardından, son adımda üst kısımlarını kırptıktan sonra kalan küçük mandalları kullanarak tuş takımını tekrar açın ve bir havya kullanarak sıcak demiri her bir pim deliğine sokmak için plastiği eritecek ve üzerine yayacaktır. Tuş takımının alt kısmı, tuş takımını eskisi gibi yerinde tutacak yeni "düğmeler" oluşturur.
Üç hoparlörü ve belki de anahtarlar ve tahtada olmayanlar gibi diğer şeyleri temizlemeyi seviyorum. Ancak, şu anda başka hedeflerimiz olduğu için bu sefer anahtarları ve diğer şeyleri atmayacağım. Ayrıca, telefon zili olan bir TA31002 lineer IC vardır. Veri sayfası, pin çıkışı ve özellikleri vererek çevrimiçi olarak kolayca bulunur ve indirilir. Bu yüzden şimdilik tahtaya lehimli bırakacağım ve daha sonra onunla oynayacağım. Onu bir osiloskopa bağlamak ve ondan ne gibi harika sinyaller alabileceğimi görmek istiyorum. Belki ondan bir kapı zili bile yapabilirsin. Kim bilir.
Her neyse, telefonu imha etmeyi ve parçaları temizlemeyi bitirdikten sonra tuş takımımızı yapmayı bitireceğiz.
3. Adım: Bir Tuş Takımı 3'ü temizleyin
Bir lehim sökme fitili kullanın ve devre kartındaki deliklerin temiz olduğundan emin olarak tuş takımının altından şerit kabloları çıkarın ve ardından deliklerin bulunduğu panoya iki dişi başlık takın. Muhtemelen başlıklarınızı 4 pinli başlıklar olacak şekilde kırpmanız gerekecektir.
Artık başlıklar eklendiğine göre, onu bir devre tahtasına bağlayabilir, bir multimetre alabilir ve multimetreyi rastgele pimlere yapıştırarak ve direnci ölçerek tuşları test edebilirsiniz. Bu, tuşların haritasını çıkarmanıza izin verecektir. Devreye bakarak tuşların çıkışlara nasıl bağlandığını görmek zor ama multimetre kullanıyorsanız herhangi iki pinine takabilir ve ardından açık devre yerine ekranda bir sayı görene kadar butonlara basabilirsiniz.. Bu, o anahtarın pin çıkışı olacaktır.
Tüm anahtarları bu şekilde çıkış pinlerine eşleyin.
Adım 4: Tuş Takımını Kablolayın
Şimdi bağlantı şemasını takip edin ve tuş takımını breadboard'unuza bağlayın.
Bu nasıl çalışacak, sol tarafa 5V koyacağız ve sağ taraf GND'ye gidecek. Şemada sağdaki ilk pin, Atmega328p mikrodenetleyicideki analog pinlerimizin ilkine girer. Herhangi bir tuşa basılmadığında, sinyal 0V olacaktır ve farklı butonların her birine basıldığında, analog porta giriş, hangi tuşa basıldığına bağlı olarak farklı bir miktarda 0V ile 5V arasında değişecektir. Direnç değerlerini, her yolun diğerlerinden farklı bir direnç içermesi için seçtik. Mikrodenetleyici üzerindeki analog bağlantı noktası bir analog sinyali alır ve onu 0V ile 5V arasında 1024 farklı kanala böler. Bu, her kanalın 5V/1024 = 0,005 V/kanal = 5 mV/kanal genişliğine sahip olduğu anlamına gelir. Böylece analog port, 5 mV'den fazla farklılık gösterdikleri sürece giriş voltajlarını ayırt edebilir. Bizim durumumuzda direnç değerlerini seçtik, böylece herhangi iki tuşa basıldığında bundan daha fazla farklılık gösteren bir voltaj sinyali gönderecek, böylece mikrodenetleyici hangi tuşa basıldığına kolayca karar verebilmelidir. Büyük sorun, tüm sistemin çok gürültülü olmasıdır, bu nedenle her düğmeye basmak için bir dizi voltaj seçmemiz gerekecek - ancak buna biraz sonra gireceğiz.
Denetleyiciye yalnızca tek bir giriş hattı kullanarak 14 düğmeli bir tuş takımını kontrol edebildiğimize dikkat edin. Bu, analog girişlerin yararlı yönlerinden biridir.
Şimdi, tuş takımını kontrol etmek için ilk girişimimiz, bir tuşa basmanın kesintiye neden olmasını sağlamak olacak, kesme alt programı analog giriş portunu okuyacak ve hangi tuşa basıldığına karar verecek ve ardından bu numarayı kaydedecek olan kayıt analizörü alt rutinimize çıkaracaktır. Öğretici 5'te kurduğumuz 8 LED'imizde ikili olarak anahtar değer.
Adım 5: Tuş Takımını Analizörünüze Bağlayın
Resimler, çıktıyı analizör ekranımızda görebilmemiz için tuş takımını mikrodenetleyiciye nasıl bağlamak istediğimizi gösteriyor. Esasen, klavyeden çıktıyı ATmega328P'de ADC0 olarak da adlandırılan PortC pin 0'a bağlarız.
Ancak, birkaç ek şey daha var. Ayrıca PD2'ye bir düğme bağlayacağız. yani 5V rayınızdan bir düğmeye ve düğmenin diğer tarafından PD2'ye bir kablo alın ve son olarak, AREF pinini 5V rayımızdan ayırmak ve bunun yerine bağlantısız bırakmak istiyoruz. İstersek 0.1 mikrofarad dekuplaj kondansatörü ekleyebiliriz. Bu, üzerinde 104 yazan bir seramik kondansatördür. İlk iki hane sayıdır ve son hane 10'un kuvvetidir ve bunu picofarad cinsinden bir cevap elde etmek için çarparız (pico 10^-12 anlamına gelir), Yani 104, 10 x 10^4 pikofarad anlamına gelir, bu da aynı 100 nanofarad (nano, 10^-9 anlamına gelir), bu, 0,1 mikrofarad ile aynıdır (mikro, 10^-6 anlamına gelir). Her neyse, tüm bunlar, referans pinimiz olarak kullanabileceğimiz zaman AREF pinini stabilize etmektir.
Ayrıca PD2 ile toprak arasında 1 Mohm'luk bir direnç istiyoruz. PD2'yi 0V'da bir çıkış pini olarak ayarlayacağız ve o pinde pozitif bir kenarda tetikleyeceğiz. Düğmeyi bıraktığımızda kenarın hemen kaybolmasını istiyoruz, böylece bu "aşağı çekme" direncini yerleştireceğiz.
Düğmeyi istememizin nedeni, Analog-Dijital dönüştürücüyü, aynı zamanda PD2 olan çip üzerindeki INT0 pininden tetiklemek istememizdir. Sonunda, tuşa basmanın hem ADC'yi tetiklemesini hem de ayrı bir düğme olmadan girdinin dönüştürülmesini sağlamasını istiyoruz, ancak zamanlamanın çalışma şekli nedeniyle, ADC'yi tetiklemek için ayrı bir düğmeyle başlayacağız ve hepsini ütüledikten sonra Hataları giderin ve her şeyin düzgün çalıştığından eminiz, o zaman okumak istediğimiz aynı düğmeye basarak tetiklemeyle gelen gürültü ve zamanlama sorunlarını çözeceğiz.
Şimdilik çalışma şekli, bir tuşu basılı tutacağız, ardından ADC'yi tetiklemek için düğmeye basacağız ve sonra bırakacağız ve umarım bastığımız düğmenin ikili değeri analizörde görünecektir.
O halde bunu gerçekleştirecek bir kod yazalım.
Adım 6: Hangi Geçiş Anahtarlarını Ayarlamalıyız?
Önce bunu nasıl kodlayacağımızı düşünelim, böylece kontrolör tuş takımından girişi okuyabilir ve basılan düğmeye karşılık gelen sayısal bir değere çevirebilir. Analog-Dijital Dönüştürücüyü (ADC) kullanacağız. Bu, Atmega328p'de yerleşiktir. Referans voltajımız olarak AREF kullanacağız ve keypad çıkışımız PortC0 veya PC0'a bağlanacaktır. Bu pinin Analog-Dijital Dönüştürücü 0 için ADC0 olarak da adlandırıldığını unutmayın. Almadan önce ATmega328P için kesmeler hakkında Bölüm 12.4'ü ve ayrıca Analog-Dijital Dönüştürücü ile ilgili bölüm 24'ü okumanız iyi bir fikir olabilir. mikrodenetleyiciyi bir analog giriş sinyaliyle ne yapacağını ve programımızla nasıl etkileşime gireceğini bilecek şekilde ayarlamak için, önce çeşitli ADC'lerden birkaçını ayarlamalıyız. ilgili kayıt bitleri. Bunlar esasen ilk bilgisayarlardaki eski geçiş anahtarlarına eşdeğerdir. Bir anahtarı AÇIK veya KAPALI konuma çevirirsiniz ya da daha da geriye doğru bir çıkışla diğeri arasındaki kabloları takarsınız, böylece yoldaki çatala ulaşan elektronlar bir kapıyı kapalı ve diğerini açık bulsun ve bu labirentte farklı bir yola girmeye zorlarsınız. devreler ve böylece farklı bir mantıksal görev gerçekleştirir. Assembly dilinde kodlama yaparken, ilk etapta çekici şeylerden biri olan mikrodenetleyicinin bu işlevlerine yakın erişime sahibiz. Daha çok "uygulamalı" ve "perde arkasında" çok daha az şey oluyor. Bu yüzden bu kayıtları sıkıcı bir görev olarak ayarlamayı düşünmeyin. Assembly dilini ilginç yapan da budur! Çipin iç işleyişi ve mantığı ile çok kişisel bir ilişki kazanıyoruz ve tam olarak istediğimiz şeyi yapmasını sağlıyoruz - ne eksik ne fazla. Boşa saat döngüsü yok. İşte ayarlamamız gereken anahtarların bir listesi:
- PRR kaydının 0 biti olan Güç Azaltma ADC biti PRADC'yi kapatın, çünkü bu bit açıksa ADC'yi kapatacaktır. Güç azaltma kaydı, temel olarak, ihtiyacınız olmadığında güç kullanan çeşitli şeyleri kapatmanın bir yoludur. ADC'yi kullandığımız için bu şekilde devre dışı bırakılmadığından emin olmak istiyoruz. (Bkz. PRADC, sayfa 46)
- ADC Çoklayıcı Seçimi (ADMUX) kaydında (Bkz. tablo 24-4 sayfa 249) MUX3…0'ı kapatarak analog giriş kanalını ADC0 olarak seçin, bunlar varsayılan olarak zaten kapalıdır, dolayısıyla bunu gerçekten yapmamıza gerek yoktur. Ancak, ADC0 dışında bir bağlantı noktası kullanırsanız, bu anahtarları buna göre değiştirmeniz gerekeceğinden onu ekliyorum. MUX3, MUX2, MUX1, MUX0'ın çeşitli kombinasyonları, analog bağlantı noktalarından herhangi birini girişiniz olarak kullanmanıza izin verir ve aynı anda bir sürü farklı analog sinyale bakmak istiyorsanız bunları anında değiştirebilirsiniz.
- ADMUX kaydındaki REFS0 ve REFS1 bitlerini kapatın, böylece AREF'i dahili bir referans yerine referans voltajımız olarak kullanacağız (Bkz. sayfa 248).
- ADLAR bitini ADMUX'ta açın, böylece sonuç "sol ayarlı" olur, bu seçimi bir sonraki adımda tartışacağız.
- Dijital girişi PC0'a kapatmak için Dijital Giriş Devre Dışı Bırakma Kaydı'ndaki (DIDR0) ADC0D bitini ayarlayın. Bu portu analog giriş için kullanıyoruz, bu yüzden dijital girişi de devre dışı bırakabiliriz.
- Bir voltaj sinyalinin yükselen kenarında INT0 pinine (PD2) tetiklemek istediğimizi belirtmek için Harici Kesme Kontrol Kaydı A'da (EICRA) ISC0 ve ISC1'i ayarlayın, bkz. sayfa 71.
- Bu pin üzerinde kesme kullanmadığımızı belirtmek için Harici Kesme Maskesi Kaydı (EIMSK) içindeki INT0 ve INT1 bitlerini temizleyin. Bu pin üzerinde kesintileri etkinleştirecek olsaydık, 0x0002 adresinde bir kesme işleyicisine ihtiyacımız olurdu, ancak bunun yerine onu, bu pindeki bir sinyalin ADC dönüşümünü tetikleyeceği şekilde ayarlıyoruz, bunun tamamlanması ADC dönüşüm tamamlama kesmesi tarafından gerçekleştirilir. 0x002A adresi. 72. sayfaya bakın.
- ADC'yi etkinleştirmek için ADC kontrolünde ADC Etkinleştirme (ADEN) bitini (bit 7) ve durum kaydı A'yı (ADCSRA) ayarlayın. 249. sayfaya bakın.
- Analog sinyali her okumak istediğimizde ADC başlatma dönüştürme bitini (ADSC) ayarlayarak tek bir dönüştürme başlatabiliriz, ancak şimdilik, biri düğmeye bastığında otomatik olarak okumasını tercih ederiz, bu yüzden bunun yerine ADC'yi etkinleştireceğiz. Tetiklemenin otomatik olarak yapılması için ADCSRA kaydındaki Autotrigger Enable (ADATE) biti.
- Ayrıca ADPS2..0 bitlerini (AD Prescalar bitleri) 111'e ayarladık, böylece ADC saati CPU saatinin 128'e bölünmesiyle elde edilir.
- ADC tetiklemesinin kaynağını INT0 (Harici Kesinti İsteği 0) olarak da adlandırılan PD2 olarak seçeceğiz. Bunu, ADCSRB kaydındaki çeşitli bitleri değiştirerek yaparız (bkz. Tablo 24-6, sayfa 251). ADC'nin bu pimi tetiklemesi için ADTS0'ın kapalı, ADTS1'in açık ve ADTS2'nin kapalı olmasını istediğimizi tabloda görüyoruz. Analog bağlantı noktasını sürekli bir analog sinyal okuyormuş gibi (ses örnekleme veya başka bir şey gibi) sürekli olarak örneklemek istersek, bunu Serbest Çalışma Moduna ayarlayacağımızı unutmayın. PD2'de tetiklemeyi ayarlamak için kullandığımız yöntem, PC0 analog bağlantı noktasının bir kesintiye neden olmadan bir ADC okumasını tetikler. Kesinti, dönüştürme tamamlandığında gelecektir.
- ADCSRA kaydındaki ADC Interrupt Enable (ADIE) bitini etkinleştirin, böylece analogdan dijitale dönüştürme tamamlandığında, bir kesme işleyicisi yazabileceğimiz ve.org 0x002A'ya koyabileceğimiz bir kesme oluşturacaktır.
- Kesintileri etkinleştirmek için I bitini SREG'de ayarlayın.
Alıştırma 1: Neler olduğunu ve bunları alternatif ayarlara değiştirirsek ne olacağını anlamak için yukarıdaki ayarların her biri için veri sayfasındaki ilgili bölümleri okuduğunuzdan emin olun.
Adım 7: Kesinti İşleyicisini Yazın
Son adımda, PD2'de algılanan yükselen bir kenarın PC0'da bir analogdan dijitale dönüşümü tetikleyeceği ve bu dönüştürme tamamlandığında bir ADC Dönüşüm Tamamlama kesintisi oluşturacak şekilde ayarlamış olduğumuzu gördük. Şimdi bu kesme ile bir şeyler yapmak istiyoruz. Sayfa 65'teki Tablo 12-6'yı incelerseniz, olası kesintilerin bir listesini göreceksiniz. Daha önceki Öğreticilerde 0x0000 adresinde RESET kesmesini ve 0x0020 adresinde Zamanlayıcı/Sayaç0 Taşma kesmesini gördük. Şimdi tablodan gördüğümüz ADC kesmesine 0x002A adresinde bakmak istiyoruz. Bu nedenle, montaj dili kodumuzun başında şunu okuyan bir satıra ihtiyacımız olacak:
.org 0x002Arjmp ADC_int
bu, ADC bir dönüştürmeyi tamamladığında ADC_int etiketli kesme işleyicimize atlayacaktır. Peki kesme işleyicimizi nasıl yazmalıyız? ADC'nin çalışma şekli aşağıdaki hesaplamayı yapmaktır:
ADC = Vin x 1024 / Vref
Öyleyse, tuş takımındaki "tekrar ara" düğmesine basarsam ne olacağını görelim. Bu durumda PC0'daki voltaj bir değere değişecektir, diyelim ki 1.52V ve Vref 5V'da olduğu için elimizde:
ADC = (1,52V) x 1024 / 5V = 311.296
ve böylece 311 olarak ortaya çıkacaktı. Bunu tekrar bir gerilime dönüştürmek isteseydik, hesaplamayı tersine çevirirdik. Ancak, sadece aralarında ayrım yapmak için gerçek voltajlarla ilgilenmediğimiz için bunu yapmamız gerekmeyecek. Dönüştürme bittiğinde sonuç ADCH ve ADCL kayıtlarına yerleştirilen 10 bitlik bir sayıya kaydedilir ve bunun "sol ayarlı" olmasını sağladık, yani 10-bit ADCH'nin 7. bitinden başlayıp aşağı iner. ADCL'nin bit 6'sı (bu iki yazmaçta toplam 16 bit vardır ve bunlardan sadece 10 tanesini kullanıyoruz, yani 1024 kanal). ADMUX yazmacındaki ADLAR bitini temizleyerek istersek "sağa ayarlanmış" sonucunu alabiliriz. Sol ayarlı seçmemizin nedeni, sinyallerimizin yeterince uzakta olması ve kanal numarasının son iki hanesinin alakasız olmasıdır. muhtemelen sadece gürültüdür, bu yüzden sadece üst 8 haneyi kullanarak tuşa basışları ayırt edeceğiz, başka bir deyişle, hangi düğmeye basıldığını bulmak için sadece ADCH'ye bakmamız gerekecek. kayıt olun, bu sayıyı bir tuş takımı değerine dönüştürün ve sonra bu değeri kayıt analizörümüz LED'lerine gönderin, böylece "9" demeye bastığımızda "00001001"e karşılık gelen LED'lerin yanmasına neden olacağını doğrulayabiliriz. Yine de, çeşitli düğmelere bastığımızda ADCH'de neyin göründüğünü görmemiz gerekiyor. Öyleyse, ADCH'nin içeriğini analizör ekranına gönderen basit bir kesme işleyicisi yazalım. İşte ihtiyacımız olan şey:
ADC_int:lds analizörü, ADCH;ADCH değerini analizörlerimize yükleyinbi EIFR, 0; tekrar çalışmaya hazır olması için harici kesme bayrağını temizleyin
Şimdiye kadar, öğretici 5'teki analiz cihazımızdan kodu kopyalayabilmeli ve bu kesmeyi ve geçiş ayarlarını ekleyip çalıştırabilmelisiniz. Alıştırma 2: Kodu yazın ve çalıştırın. Analizör ekranınızda ADCH'nin görüntülendiğini görün. Aynı tuşa birden çok kez basmayı deneyin. ADCH'de her zaman aynı değeri mi alıyorsunuz?
Adım 8: Tuşa Basma Değerlerinin Haritasını Çıkarın
Şimdi yapmamız gereken, ADCH'deki değerleri basılan tuşa karşılık gelen sayılara dönüştürmektir. Bunu, her tuş basışında ADCH'nin içeriğini yazıp, resimde yaptığım gibi ondalık sayıya çevirerek yapıyoruz. Kesinti işleme rutinimizde, ADC'nin bu aralıktaki herhangi bir şeyi belirli bir tuşa basması için eşlemesi için her bir tuşa basışa karşılık gelen tüm bir değer aralığını dikkate alacağız.
Alıştırma 3: Bu eşlemeyi yapın ve ardından ADC kesme rutininizi yeniden yazın.
İşte benim için aldığım şey (sizinki büyük olasılıkla farklı olacak). Her tuşa basma için bir dizi değer ayarladığımı fark ettim.
ADC_int:; Harici kesme işleyicisiclr analizörü; yeni numaralar için hazırlanın buttonH, ADCH; ADCH okunduğunda ADC güncellemeleri clccpi buttonH, 240brlo PC+3; ADCH daha büyükse, bu bir 1ldi analizörüdür, 1; bu yüzden 1rjmp dönüşlü yük analizörü; ve geri dön clccpi buttonH, 230; ADCH daha büyükse 2brlo PC+3ldi analizörü, 2rjmp dönüş clccpi düğmesiH, 217brlo PC+3ldi analizörü, 3rjmp dönüş clccpi düğmesiH, 203brlo PC+3ldi analizörü, 4rjmp dönüş clccpi düğmesiH, 187brlo PC+3ldi analizörü, 5rjmp düğme dönüşü, cl 155brlo PC+3ldi analizörü, 6rjmp dönüş clccpi buttonH, 127brlo PC+3ldi analizörü, 255; tüm onrjmp dönüş clccpi buttonH, 115brlo PC+3ldi analizör, 7rjmp dönüş clccpi buttonH, 94brlo PC+3ldi analizör, 8rjmp dönüş clccpi buttonH, 62brlo PC+3ldi analizörü, 9rjmp dönüş clccpi buttonH, 37dibrlo PC+3l olarak flaş ayarlayacağız 0b11110000; yıldız işareti üst yarı onrjmp dönüş clccpi düğmesiH, 28brlo PC+3ldi analizörü, 0rjmp dönüş clccpi düğmesiH, 17brlo PC+3ldi analizörü, 0b00001111; karma işareti alt yarı onrjmp dönüş clccpi buttonH, 5brlo PC+3ldi analizörü, 0b11000011; tekrar arama üst 2 alt 2rjmp dönüş ldi analizörüdür, 0b11011011; aksi halde hata oluştu dönüş:reti
9. Adım: Sürüm 1 için Kod ve Video
Tuş takımı sürücüsünün bu ilk sürümü için kodumu ekledim. Bunda, ADC'nin tuş takımından girişi okumasını sağlamak için tuşa basmanız ve ardından düğmeye basmanız gerekir. Bizim tercih ettiğimiz şey bir düğme olmaması, bunun yerine dönüşüm yapmak için sinyalin tuşa basılmasının kendisinden gelmesi. Alıştırma 3: Bu kodu birleştirin ve yükleyin ve deneyin. Muhtemelen benimkinden farklı olduklarından, çeşitli dönüştürme eşiklerini tuşa basma voltajlarınıza karşılık gelecek şekilde değiştirmeniz gerekebilir. Bir düğme yerine hem ADC0 hem de harici kesme pimi için tuş takımından bir giriş kullanmaya çalışırsanız ne olur? Ayrıca tuşa basma sürücümüzün bu ilk sürümünün çalışmasının bir videosunu da ekleyeceğim. Bunu fark edeceksiniz. kodumda Yığın İşaretçisini başlatan bir bölüm var. Değişkenleri manipüle ederken yığından itmek ve çıkarmak isteyebileceğimiz çeşitli kayıtlar vardır ve ayrıca daha sonra kaydetmek ve geri yüklemek isteyebileceğimiz kayıtlar da vardır. Örneğin, SREG, kesmeler arasında korunmayan bir kayıttır, bu nedenle, bir şeyin ortasında bir kesinti meydana gelirse, işlemler sonucunda ayarlanan ve temizlenen çeşitli bayraklar değiştirilebilir. Bu nedenle, bir kesme işleyicisinin başlangıcında SREG'i yığına itmeniz ve ardından kesme işleyicisinin sonunda tekrar açmanız en iyisidir. Nasıl başlatıldığını göstermek ve daha sonra nasıl ihtiyacımız olacağını tahmin etmek için kodun içine yerleştirdim ancak kodumuzdaki kesintiler sırasında SREG'e ne olacağı umurumuzda olmadığı için yığını bunun için kullanmadım. Ayrıca dikkat edin başlatırken kayıtlardaki çeşitli bitleri ayarlamak için kaydırma işlemini kullandığımı. Örneğin satırda:
ldi sıcaklığı, (1<
Yukarıdaki kodun ilk satırındaki "<<" komutu bir kaydırma işlemidir. Esasen 0b00000001 olan ikili sayı 1'i alır ve ISC01 sayısı kadar sola kaydırır. Bu, EICRA kaydındaki ISC01 adlı bitin konumudur. ISC01 bit 1 olduğundan, 1 sayısı 0b00000010 olacak şekilde sol 1 konumuna kaydırılır. Benzer şekilde ikincisi, ISC00, EICRA'nın 0 bitidir ve bu nedenle 1 sayısının sola kayması sıfır konumundadır. İlk derste indirdiğiniz ve o zamandan beri evrr kullanmakta olduğunuz m328Pdef.inc dosyasına bir kez daha bakarsanız, bunun sadece uzun bir ".equ" deyimleri listesi olduğunu göreceksiniz. ISC01'in 1'e eşit olduğunu göreceksiniz. Montajcı herhangi bir şeyi birleştirmeye başlamadan önce onun her örneğini 1 ile değiştirir. Onlar sadece biz insanların kod okuyup yazmasına yardımcı olan kayıt bitlerinin isimleridir. Şimdi, yukarıdaki iki kaydırma işlemi arasındaki dikey çizgi, mantıksal bir "veya" işlemidir. İşte denklem:
0b00000010 | 0b00000001 = 0b00000011
ve temp'e ("ldi" kullanarak) yüklediğimiz şey budur. İnsanların bir kayıt defterine değerleri yüklemek için bu yöntemi kullanmalarının nedeni, sadece bir sayı yerine bitin adının kullanılmasına izin vermesi ve bu, kodun okunmasını çok daha kolay hale getirmesidir. Kullandığımız başka iki teknik daha var. "Ori" ve "andi" talimatlarını kullanıyoruz. Bunlar, bir kayıttaki diğer bitlerin hiçbirini değiştirmeden sırasıyla bitleri SET ve CLEAR yapmamıza izin verir. Örneğin, kullandığımda
ori sıcaklığı, (1
0b00000001 ile bu "veya" temp, sıfırıncı bit'e 1 koyar ve geri kalan her şeyi değiştirmeden bırakır. Ayrıca yazdığımızda
andi sıcaklığı, 0b11111110
bu, sıcaklığın sıfırıncı bitini 0 olarak değiştirir ve geri kalan her şeyi değiştirmeden bırakır.
Alıştırma 4: Kodu gözden geçirmeli ve her satırı anladığınızdan emin olmalısınız. Bir şeyler yapmak için daha iyi yöntemler bulmayı ve daha iyi bir program yazmayı ilginç bulabilirsiniz. Bir şeyleri kodlamanın yüzlerce yolu var ve benimkinden çok daha iyi bir yol bulabileceğinizden oldukça eminim. Ayrıca (Allah korusun!) hatalar ve eksiklikler de bulabilirsiniz. Bu durumda, düzeltilebilmeleri için onları duymak isterim.
Tamam, şimdi bakalım o gereksiz düğmeden kurtulabilecek miyiz…
Adım 10: Sürüm 2 için Kod
Düğmeden kurtulmanın en basit yolu, düğmeyi tamamen kaldırmak, PB2 girişini unutmak ve ADC'yi "Serbest Çalışma Moduna" geçirmektir.
Başka bir deyişle, ADCSRB kaydını, ADTS2, ADTS1 ve ADTS0'ın tümü sıfır olacak şekilde değiştirin.
Ardından, ADCSRA'daki ADSC bitini, ilk dönüştürmeyi başlatacak olan 1'e ayarlayın.
Şimdi mikrodenetleyicinize yükleyin ve düğmeye basarken ve sadece düğmeye basarken ekranda doğru sayının geldiğini göreceksiniz. Bunun nedeni, ADC'nin sürekli olarak ADC0 bağlantı noktasını örneklemesi ve değeri göstermesidir. Parmağınızı butondan çektiğinizde "buton sekmesi" çok hızlı bir şekilde birkaç rastgele değerin oluşmasına neden olacak ve ardından tekrar 0V girişine yerleşecektir. Kodumuzda bu 0V 0b11011011 olarak görünüyor (çünkü `0' tuşuna basıldığında zaten 0b00000000 ekran değeri kullanılıyor)
Bu iki nedenden dolayı istediğimiz çözüm değil. İlk önce düğmeyi basılı tutmak zorunda kalmak istemiyoruz. Bir kez basmak ve sayının görüntülenmesini (veya daha sonraki bir eğitimde bazı yeni kodlarda kullanılmasını) istiyoruz. İkincisi, sürekli olarak ADC0'ı örneklemek istemiyoruz. Tek bir okuma yapmasını, dönüştürmesini ve ardından yeni bir tuşa basılması yeni bir dönüşümü tetikleyene kadar uyumasını istiyoruz. Serbest çalışma modu, mikro denetleyicinin yapmasını istediğiniz tek şey sürekli olarak bazı analog girişleri okumaksa en iyisidir - örneğin gerçek zamanlı sıcaklıkları veya başka bir şeyi görüntülemek istiyormuşsunuz gibi.
O halde başka bir çözüm bulalım…
Adım 11: Düğmeden Nasıl Kurtuluruz? Sürüm 3
Devam edebileceğimiz sayısız yol var. İlk önce düğmeden kurtulmak için donanım ekleyebiliriz. Örneğin, tuşa basmanın çıkış hattındaki devreye bir transistör yerleştirmeyi deneyebiliriz, böylece çıkıştan küçük bir akım damlası alır ve kesme pimi PD2'ye 5V'luk bir darbe gönderir.
Bununla birlikte, bu muhtemelen en azından çok gürültülü olacaktır ve en kötü ihtimalle, tuş takımının voltaj çıkışının ADC okuması yakalanmadan önce stabilize etmek için zamanı olmayacağından, doğru bir tuşa basma okuması için yeterli zamana izin vermeyecektir.
Bu yüzden bir yazılım çözümü bulmayı tercih ederiz. Yapmak istediğimiz şey, PD2 pinine bir kesme eklemek ve bunun için keypad pininin tek bir okumasını çağıran bir kesme işleyicisi yazmak. Başka bir deyişle, ADC'den autotrigger kesmesinden kurtulur ve içindeki ADC'yi çağıran harici bir kesme ekleriz. Bu şekilde ADC'yi okuyacak sinyal, PD2 sinyali zaten oluştuktan sonra gelir ve bu, PC0 pini okunmadan ve dönüştürülmeden önce doğru bir voltaja stabilize etmek için yeterli zaman verebilir. Yine de, sonucu analizör ekranına sonunda veren bir ADC tamamlama kesintisine sahip olacaktık.
Mantıklı olmak? Peki yapalım…
Ekli yeni koda bir göz atın.
Aşağıdaki değişiklikleri görürsünüz:
- INT0 harici kesmesini işlemek için.org 0x0002 adresine bir rjmp ekledik
- INT0 pininde kesinti yapmak istediğimizi belirtmek için EIMSK kaydını değiştirdik
- Otomatik tetiklemeyi devre dışı bırakmak için ADCSRA kaydındaki ADATE pinini değiştirdik
- ADATE kapalıyken alakasız oldukları için ADCSRB ayarlarından kurtulduk.
- INT0 kesme rutini tamamlandığında bunu otomatik olarak yaptığı için artık harici tetik bayrağını sıfırlamamız gerekmiyor -- önceden bir kesme rutinimiz yoktu, sadece ADC'yi o pindeki bir sinyalden tetikledik, bu yüzden yapmak zorunda kaldık. o bayrağı elle temizle.
Şimdi kesme işleyicisinde ADC'den tek bir dönüşüm çağırıyoruz.
Alıştırma 5: Bu sürümü çalıştırın ve ne olduğunu görün.
Adım 12: Çalışan Sürüm için Kod ve Video
Son versiyonda gördüğümüz gibi, kesme, PD2 pinine yükselen bir kenarda tetiklendiğinden ve ardından kesme işleyicisi ADC dönüşümünü çağırdığından, düğme kesmesi çok iyi çalışmıyor. Bununla birlikte, ADC daha sonra voltaj okumasını stabilize etmeden önce alır ve bu nedenle anlamsız okur.
İhtiyacımız olan şey, PD2'deki kesinti ile PC0'daki ADC okuması arasında bir gecikme oluşturmaktır. Bunu bir zamanlayıcı/sayıcı, bir sayaç taşma kesmesi ve bir gecikme rutini ekleyerek yapacağız. Neyse ki bunu nasıl yapacağımızı Öğretici 3'ten zaten biliyoruz! Bu yüzden ilgili kodu oradan kopyalayıp yapıştıracağız.
Ortaya çıkan kodu ve çalıştığını gösteren bir video verdim.
Okumaların umduğunuz kadar doğru olmadığını fark edeceksiniz. Bu muhtemelen birkaç kaynaktan kaynaklanmaktadır:
- PC0'daki okumayı etkileyen PD2'yi tetiklemek için tuş takımının voltaj çıkışından dokunuyoruz.
- En iyi okumayı elde etmek için tetikleyiciden sonra ne kadar geciktireceğimizi gerçekten bilmiyoruz.
- ADC dönüşümünün tamamlanması birkaç döngü alır, bu da tuş takımında hızlı ateşleme yapamayacağımız anlamına gelir.
- muhtemelen tuş takımında gürültü var.
- vesaire…
Her ne kadar keypad'i çalıştırmayı başarmış olsak ve artık keypress değerlerini sadece analizör ekranına göndermek yerine başka bir şekilde kullanarak uygulamalarda kullanabilsek de, bu çok doğru değil ve çok can sıkıcı bir durum. Bu nedenle, tuş takımlarını kablolamanın en iyi yolunun, tuş takımından gelen her bir çıkışı farklı bir bağlantı noktasına yapıştırmak ve hangi bağlantı noktalarının voltaj gördüğüne hangi tuşa basıldığına karar vermek olduğunu düşünüyorum. Bu kolay, çok hızlı ve çok doğru.
Aslında, burada yaptığımız gibi bir tuş takımını kullanmak istemesinin sadece iki nedeni vardır:
- Mikrodenetleyicimizde 8 yerine sadece 2 pin kullanır.
- Sıcaklık okumaları, dönüş potansiyometreleri vb. gibi orada bulabileceğiniz standart şeylerden farklı olan ADC'nin farklı yönlerini mikrodenetleyici üzerinde göstermek harika bir proje. Tetiklenmiş tekli okumalar ve harici pin otomatik tetikleme örneği istedim. sadece serbest çalışan CPU silip süpürme modundan ziyade.
Her neyse, işte size son birkaç egzersiz:
Alıştırma 6: Bir Arama Tablosu kullanmak için ADC dönüştürme tamamlama kesme işleyicisini yeniden yazın. yani Böylece analog değeri tablodaki ilk öğe ile test eder ve daha büyükse kesmeden döner, değilse tablodaki bir sonraki öğeye Z'yi artırır ve tekrar teste dallanır. Bu, kodu kısaltacak ve kesme rutinini temizleyecek ve daha güzel görünmesini sağlayacaktır. (Bir sonraki adımda olası bir çözüm vereceğim)Alıştırma 7: Klavyenizi mikrodenetleyici üzerindeki 8 pin'e bağlayın ve bunun için basit sürücüyü yazın ve ne kadar güzel olduğunu deneyimleyin. Yöntemimizin daha iyi çalışmasını sağlamanın birkaç yolunu düşünebilir misiniz?
Hepsi bu eğitim için. Son sürümü işaretçilerle ekledim. Nihai hedefimize yaklaşırken, Öğretici 9'da klavyeyi onunla yedi segmentli ekranın nasıl kontrol edileceğini göstermek (ve telefon tuş takımındaki ekstra tuşları kullanan ilginç bir şey inşa etmek) için bir kez daha kullanacağız ve sonra bunun yerine şeyleri düğmelere basarak kontrol etmeye geçin (çünkü bu yöntem, bu öğreticilerle geliştirdiğimiz son ürüne daha uygundur) ve biz sadece tuş takımını rafa kaldıracağız.
Bir dahaki sefere görüşürüz!
Önerilen:
AVR Assembler Eğitimi 2: 4 Adım
AVR Assembler Eğitimi 2: Bu eğitim, "AVR Assembler Eğitimi 1" Öğretici 1'den geçmediyseniz, şimdi durmalısınız ve önce bunu yapmalısınız. Bu derste, atmega328p u'nun montaj dili programlaması çalışmamıza devam edeceğiz
AVR Assembler Eğitimi 1: 5 Adım
AVR Assembler Eğitimi 1: Arduino'da kullanılan mikrodenetleyici olan Atmega328p için Assembly dili programlarının nasıl yazılacağına dair bir dizi öğretici yazmaya karar verdim. İnsanlar ilgilenmeye devam ederse, tükenene kadar haftada bir tane çıkarmaya devam edeceğim
AVR Assembler Eğitimi 6: 3 Adım
AVR Assembler Eğitimi 6: Öğretici 6'ya Hoş Geldiniz! Bugünkü eğitim kısa olacak ve burada bir atmega328p ile diğerini birbirine bağlayan iki bağlantı noktası kullanarak veri iletmek için basit bir yöntem geliştireceğiz. Daha sonra Öğretici 4'ten ve Kayıt Defterinden zar silindirini alacağız
AVR Assembler Eğitimi 8: 4 Adım
AVR Assembler Eğitimi 8: Öğretici 8'e Hoş Geldiniz!Bu kısa eğitimde, prototipleme bileşenlerimizi ayrı bir "basılı"ya nasıl taşıyacağımızı göstermek için montaj dili programlamanın yeni yönlerini tanıtmaktan biraz sapacağız. devre kartı. NS
AVR Assembler Eğitimi 9: 7 Adım
AVR Assembler Eğitimi 9: Eğitim 9'a Hoş Geldiniz Bugün, ATmega328P ve AVR montaj dili kodumuzu kullanarak hem 7 segmentli hem de 4 basamaklı bir ekranın nasıl kontrol edileceğini göstereceğiz. Bunu yaparken yığının nasıl kullanılacağına dair saptırmalar yapmamız gerekecek