Merhabalar! PIC18 Assembly programlama konusunda biraz Türkçe kaynak kıtlığı olduğunu farkettim. Kaynaklar çok az veya olanlar oldukça basit seviyede. Biraz daha ilerlemek isterseniz artık Türkçe kaynak konusunda yolun sonuna vardığınızı farkedersiniz. Türkçe kaynaklara küçük de olsa katkı sağlamak amacıyla kurgusal bir motor kontrol senaryosu içeren bu yazıyı hazırladım.
Bu uygulamanın amacı mükemmel bir motor kontrol devresi ve yazılımı yapmak değil, tamamen PIC18 Assembly dili ile programlama pratiği yapmaktır. Dolayısıyla bu haliyle profesyonel amaçlara hizmet etmez fakat yine de bir başlangıç noktası olarak kullanılabilir.
Amacımız; birkaç giriş ve birkaç çıkışı kontrol eden bir mikrodenetleyiciyi istediğimiz bir senaryoya göre koşullandırıp çalışmasını sağlamak. Amacımız çok basit olsa da bunu gerçekleştirmek o kadar basit olmayacaktır. Çünkü çalışacağımız mikrodenetleyici olan PIC18F2550 gelişmiş ve biraz daha karmaşık bir yapıya sahip bir yongadır. Buna Assembly programlamanın da zorluğunu eklersek... Neyse biz zorluğa değil çözüme odaklanalım.
Büyük bir sorun çözmesi zor bir sorundur. Büyük bir sorunu olabildiğince küçük parçalara ayırıp öyle ele almak işimizi kolaylaştırır. Nitekim biz de burada böyle yapacağız. Bu yüzden yazımız biraz uzun ama, herbir çözüm aşaması katedişimizde buna değeceğini göreceksiniz.
Bu yazıyı uygulamalı bir şekilde bitirdiğinizde şunları yapabiliyor olacaksınız:
555 Entegresini kararsız kipte istenen frekansta yapılandırma.
CD4026 entegresi ile bir sayısal sayaç devresi kurma ve kontrol etme. Hatta kaskat bağlantı yaparak sayı hanelerini artırma.
PIC18 mikrodenetleyici modellerini PIC18 Assembly ile programlama.
Osilatör yapılandırması.
Portların giriş ve çıkış yapılandırmaları.
Harici kesmelerin kurulumu ve kullanımı.
Yazılımsal gecikmeler yazma.
Timer0 yazmacını istenen zaman gecikmesi için yapılandırma.
Timer0 kesmesi kullanarak zamanlama.
CD4026 gösterge sürücü entegresini kontrol etme.
Devrenin Çalışması
Not
Vidyoyu kaydettikten bu yana yazılım içinde birkaç iyileştirme yaptım. Bu yüzden devre denendiğinde videodaki çalışma şeklinden biraz daha farklı olabilir.
Devreye enerji verildiğinde, Kontrol devresi kullanıcının BAŞLA butonuna basmasını bekler.
Kullanıcı başla butonuna bastığında;
1. Motor devreye girer,
Ardından gösterge etkinleşir,
Timer0 etkinleşir ve 10 saniye için gösterge saymaya başlar.
10 saniyenin dolması beklenir.
10 saniye dolunca, 2. motor devreye girer
Sayaçlar sıfırlanır ve 30 saniye için kurulur.
Gösterge 30 saniye saymaya başlar.
Ancak 1. motor 10sn çalıştıktan ve 2. motor da 30sn çalıştıktan sonra devre DUR butonuyla durdurulabilir. Bu süreden önce DUR butonu işlevsizdir.
Süreler dolunca DUR butonuna basıldığında önce 2. motor durur. Dur butonuna ikinci kez basıldığında ise tüm devre durur ve kullanıcıdan gelecek başlatma komutunu bekler.
Herhangi bir esnada RE3/MCLR/VPP bacağına bağlı sıfırlama butonuna basıldığında devre ilk konumuna geri döner ve kullanıcıdan BAŞLAT komutunu vermesini bekler.
Hata Durumu
Güç devresinde bir aşırı yüklenme ya da başka bir hata dolayısıyla AAR1(Aşırı Akım Rölesi) ve AAR2 girişlerinden bir hata bilgisi geldiğinde şu senaryolar gerçekleşecektir:
Eğer 1. motor 10sn dolmadan önce hata verirse:
Motor-1 durdurulur.
Göstergeler kapanır ve sıfırlanır.
Timer0 durdurulur ve sıfırlanır.
Motor-1 hata göstergesi yanıp sönmeye başlar.
Güç devresindeki hatanın giderilmesi beklenir.
Ardından hata düzeltme onay butonuna basılması beklenir.
Yukarıdaki işlemler tamamlandığında motor-1 yeniden 10sn çalıştırılmak üzere yazılım içinde kurulur ve ardından motor-1'e yeniden çıkış verilir.
Sonra göstergeler etkinleşir ve 10sn için sayar.
Eğer 1. motor 10sn dolduktan sonra hata verirse ve 2. motor çalışıyorsa ama 30sn dolmamışsa:
Motor-1 durdurulur.
Göstergeler kapanır.
Timer0 durdurulur.
Motor-1 hata göstergesi yanıp sönmeye başlar.
Hatanın giderilip hata düzeltme onay butonuna basması beklenir.
Motor-2 çalışıyor olduğu için motor-1'in yeniden 10sn çalışmasına gerek yoktur. Bu yüzden sayaçlar sıfırlanmaz.
Motor-1'e yeniden çıkış verilir.
Sayaç 30sn bitirmek için kaldığı yerden saymaya devam eder.
Eğer 1. motor 10sn ve 30sn süreleri dolduktan sonra hata verirse:
- Motor-1 durdurulur.
- Göstergeler kapanır.
- Timer0 durdurulur.
- Motor-1 hata göstergesi yanıp sönmeye başlar.
- Hatanın giderilip hata düzeltme onay butonuna basması beklenir.
- Motor-2 çalışıyor olduğu için motor-1'in yeniden 10sn çalışmasına gerek yoktur. Bu yüzden sayaçlar sıfırlanmaz.
- Motor-1'e yeniden çıkış verilir.
- Sayaç sistemi etkinleştirilmez çünkü sayma işlemleri bitmiştir.
Eğer 2. motor 30sn dolmadan hata verirse:
- Motor-2 durdurulur.
- Göstergeler kapanır ve sıfırlanır.
- Timer0 durdurulur ve sıfırlanır.
- Motor-2 hata göstergesi yanıp sönmeye başlar.
- Hatanın giderilip hata düzeltme onay butonuna basması beklenir.
- Sayaçlar sıfırlanır ve yeniden kurulur.
- Motor-1 durdurulur ve yeniden 10sn çalışması için kurulur.
- Motor-1 yeniden devreye alınır.
- Timer0 yeniden kurulur ve etkinleştirilir.
- Göstergeler etkinleştirilir ve 10sn için saymaya başlar.
Eğer 2. motor 30sn dolduktan sonra hata verirse:
- Motor-2 durdurulur.
- Göstergeler kapanır.
- Timer0 durdurulur.
- Motor-2 hata göstergesi yanıp sönmeye başlar.
- Hatanın giderilip hata düzeltme onay butonuna basması beklenir.
- Motor-2'ye yeniden çıkış verilir.
- Sayaç sistemi etkinleştirilmez çünkü sayma işlemleri bitmiştir.
Donanım
Mikrodenetleyici Bağlantıları
Kontrol devresi şekilde de görüldüğü gibi bir sıfırlama (RESET) girişi, 2 motorun denetimini yapan 1-başlat, 1-durdur buton girişi, Aşırı Akım Rölesinden (AARx) gelen iki sinyal bilgisi girişi, 2 hata düzeltildi onay butonu girişi, 2 adet Motor1 ve Motor2 çıkışı, 2 hata göstergesi çıkışı ve sayaç devresini süren 3 uçtan oluşmaktadır. 6-harici giriş, 4-harici çıkış ve 3-dahili çıkış olmak üzere toplam 13 adet giriş-çıkış ucu kullanılmıştır.
Sayaç devresi de 1Hz saat darbesi üreteci, 2x7-Parçalı LED gösterge, göstergeleri süren 2xCD4026 7-Parçalı gösterge sürücü entegresinden oluşmaktadır. Gerekirse entegrelerin LED sürücü uçlarına direnç bağlanabilir.
Bu örnek devrede Timer0 ve kesme donanımlarının PIC18 Assembly içinde nasıl düzenlenip programlanabileceği ve işletilebileceği açıklanmıştır. Ayrıca harici bir sayaç devresi ve 1Hz/s'lik bir saat kaynağı devresi kullanılmıştır. Bu sayede 7 parçalı (burada ortak katot kullanılmıştır) göstergelerin CD4026 ile nasıl sürülebileceği ve 555 entegresi ile nasıl bir saat darbesi kaynağı oluşturulabileceği de görülecektir. Devre bredboard üzerinde kurulmuş ve denenmiştir.
Aşağıda PIC18F2550 mikrodenetçisinin bacak düzeni ve ardından kontrol devresinin giriş-çıkış uçlarının işlevleri verilmiştir:
| Sıra | Pin | Yön | Açıklama |
|---|---|---|---|
| 1 | RA1 | giriş | Motor-1 için hata düzeltildi onay butonu girişi. |
| 2 | RA2 | giriş | Motor-2 için hata düzeltildi onay butonu girişi. |
| 3 | RA3 | çıkış | 4026 Entegresinin Gösterge Etkinleştirme / Display Enable In (DEI) ucunu denetler. |
| 4 | RA5 | çıkış | 4026 Entegresinin Saat Engelleme / Clock Inhibit (INH) ucunu denetler. |
| 5 | RB1 | giriş | 1. Motorun aşırı akım rölesi kontak bilgisi girişi ve 1. harici kesme ucudur. |
| 6 | RB2 | giriş | 2. Motorun aşırı akım rölesi kontak bilgisi girişi ve 2. harici kesme ucudur. |
| 7 | RB3 | giriş | BAŞLA butonu giriş ucudur. |
| 8 | RB4 | giriş | DUR butonu giriş ucudur. |
| 9 | RC0 | çıkış | 4026 Entegresinin Sıfırlama / Reset (MR) ucunu denetler. |
| 10 | RC1 | çıkış | Motor-1 için hata göstergesi çıkışı. |
| 11 | RC2 | çıkış | Motor-2 için hata göstergesi çıkışı. |
| 12 | RC6 | çıkış | 1. Motoru süren uçtur. |
| 13 | RC7 | çıkış | 2. Motoru süren uçtur. |
Osilatör kaynağı olarak mikrodenetleyicinin dahili 8Mhz'lik osilatör kaynağı kullanılmıştır. Bu kaynak yazılım içinde 1MHz hızda çalışacak şekilde ayarlanmıştır. Bu sayede osilatör giriş ve çıkış pinleri özgür bırakılmış olup, dijital giriş-çıkış olarak kullanılabilecektir.
Sürevci (zamanlayıcı) olarak 18F2550 denetleyicisinin dahili Timer0 donanımı kullanılmıştır. Yazılım bölümünde Timer0'ın hesaplamaları verilecektir.
Sayaç devresinin saat kaynağı olarak; saniyede yaklaşık 1Hz'lik darbe üreten bir 555 devresi kullanılmıştır. Ancak istenildiği takdirde saat üreteci olarak yeterli donanıma sahipse, kullanılan mikrodenetleyiciden de yararlanılabilir. Benim vidyoda kullandığım 555 entegreli devrede saat darbeleri tam olarak her 1sn'de bir üretilmez ancak burada çok hassas zamanlı bir proje yapmadığımız için bu durum göz ardı edilebilir. Uygulamada kullandığım 555 saat üreteci devresi ve eleman değerleri aşağıda görülmektedir.
Uygulamada 555 entegresinin çıkış bacağı olan 3. bacak ve R10 arasından bir kablo ile 1. haneyi süren 4026 entegresinin 1. bacağına (Clock) bağlayın. Böylece sayaç saat kaynağını sağlamış olursunuz.
Donanım ayrıntıları ve hesaplamalarıyla ilgilenmiyorsanız Yazılım bölümüne atlayabilirsiniz.
555 Sinyal Üreteci
555 Entegresi burada kararsız (astable) kipinde çalışmaktadır. Devreye eneji verildiğinde C2 kondansatörü R8 ve R9 üzerinden dolmaya başlar. C2 uygulanan gerilime tamamen dolduğunda, R9 ve 7.bacak üzerinden 555 entegresi içinde bulunan bir boşaltma transistörü üzerinden şaseye batırılır ve bu yol üzerinden boşalmaya başlar. C2 artı kutbundaki gerilim uygulama geriliminin 1/3 düzeyine gelince 555, 3 numaralı bacağından yüksek çıkış verebilmek için 2 numaralı bacağından gerekli tetiklemeyi almış olur ve ardından 555 çıkışı lojik 1 ya da yüksek seviyededir. Sonra kondansatör R8 ve R9 dirençleri üzerinden yeniden dolmaya başlar. C2 uygulama geriliminin 2/3 düzeyine dolduktan sonra 555 tetikleme durumundan çıkar ve çıkışı lojik 0 ya da düşük seviyeye çeker. İşte kondansatörün dirençler üzerinden dolup, yine direnç ve entegre üzerinden boşalırken geçen zaman T süresini verir ve oluşturduğu testere dişi sinyal, 555 tarafından kare dalga sinyale dönüştürülür. Oluşan bu sinyal bizim gösterge devresi için kullanacağımız saat sinyalidir.
Yukarıdaki şekilde boşaltma (discharge) direnç(R9) değeri 14,7k (10k ve 4,7k iki direncin seri bağlanmasıyla oluşturuldu) kullanılmıştır. Dilenirse 14,7k direnç yerine 50k bir potansiyometre bağlanıp gereken değere ayarlanarak 1 saniyeye daha yakın bir süre elde edilebilir. Kondansatör dolarken 1k + 14,7k dirençleri üzerinden dolmakta, boşalırken de 14,7k direnci boyunca 555'in 7. (discharge) ucu aracılığıyla boşalmaktadır. Bu da %50'ye yakın bir görev çevrimi/duty cycle oranı vermektedir (tam oran = %51,13647).
Bu değerlerle 555 entegresinin veribetinde (datasheet) verdiği süre formülünü kullanarak hesaplayacak olursak:
T = 0,693 x (R8 + 2 x R9) x C2
T = 0,693 x ([1x103] + 2 x [14,7x103]) x (47x10-6)
T = 0,693 x (1000 + [2 x 14700]) x 0,000047
T = 0,693 x 30400 x 0,000047
T = 0,9901584 saniye (1 saniyeden 9,8416 milisaniye eksik :) )
Yukarıdaki sonuca göre frekansı bulmak istersek şu formülle hesaplayabiliriz:
f = 1 / t
f = 1/0,9901584 = 1,009939419793843Hz
Sayaç Devresi
Sayaç devresi 2x7-parçalı (7-segment) LED göstergeleri ve bu göstergeleri süren 2 x CD4026 birimlerinden oluşur. 10 ve 30 saniyelik süreler mikrodenetleyicinin dahili sürevcisinde üretilir ve bu süreler boyunca gösterge devresi 4026 entegresinin denetim esnekliğinin olması sayesinde; mikrodenetleyicinin RA3, RA5 ve RC0 uçları tarafından denetlenir.
RA3 (çıkış): 4026 Entegresinin Gösterge Etkinleştirme Girişi/Display Enable In (DEI) ucunu denetler.
RA5 (çıkış): 4026 Entegresinin Saat darbesi Engelleme / Clock Inhibit (INH) ucunu denetler.
RC0 (çıkış): 4026 Entegresinin Sıfırlama / Reset (MR) ucunu denetler.
7 Parçalı Ortak Katod Gösterge
Donanım bölümünde son olarak 7-parçalı ortak katot LED göstergenin şeklini ve iç yapısını paylaşacağım:
Bu yapıya göre 4026 entegresinin "a,b,c,d,e,f,g" uçları göstergenin karşılık gelen "a,b,c,d,e,f,g" uçlarına dirençler aracılığıyla ya da doğrudan bağlanabilir.
Eğer daha güvenli olması açısından direnç bağlamaya karar verilirse 7 adet 220 ohm değerinde direnç bağlanabilir.
Yazılım
Yazılımda kullanılan neredeyse tüm yazmaçların, etiket ve komutların Türkçe açıklamaları yapılmıştır. Burada kesmelerin ve Timer0 sürevcisinin hazırlanması, Timer0 hesabı, yazılım bayrakları ve yazılım sayaçlarının yapılandırılıp kullanılması açıklanmaktadır.
Timer0'ın Yapılandırılması
Timer0 önce 10 saniye sonra da 30 saniyelik süreleri üretmesi için kullanılmıştır. PIC18F2550'de Timer0'ın önölçekçisi (prescaler) PIC16 serisinde olduğu gibi WatchDog Timer ile paylaştırılmamıştır. Önölçekçi yalnızca Timer0'a aittir. Ayrıca Timer0 ya 8-bit ya da 16-bit kipinde çalışma özelliğine sahiptir. Aşağıda Timer0'ın 8-bit kipinde blok diyagramı görülüyor.
Timer0 ile ilgili düzenlemeler T0CON yazmacı üzerinden yapılır. T0CON yazmacı ile Timer0 blok diyagramına biraz konsantre olursanız Timer0 donanımının T0CON denetim yazmacı üzerinden yüklediğiniz değere göre nasıl denetlediğinin mantığını az çok kavrayabilirsiniz.
T0CON Yazmacının Yapılandırılması
T0CON (Timer0 Control Register): Timer0 Denetim Yazmacı
| TMR0ON | T08BIT | T0CS | T0SE | PSA | T0PS2 | T0PS1 | T0PS0 |
|---|---|---|---|---|---|---|---|
| Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
- Bit 7 TMR0ON: Timer0 On/Off Control Bit / Timer0 Aç / Kapa Denetim Biti
- 1 = Timer0'ı etkinleştirir
- 0 = Timer0'ı durdurur
- Bit 6 T08BIT: Timer0 8-Bit/16-Bit Control Bit / Timer0 8-bit / 16-bit Denetim Biti
- 1 = Timer0 8-bit kipinde çalışır
- 0 = Timer0 16-bit kipinde çalışır
- Bit 5 T0CS: Timer0 Clock Source Select Bit / Timer0 Saat Kaynağı Seçim Biti
- 1 = Saat kaynağı T0CKI bacağından alınır
- 0 = Saat kaynağı dahili komut çevrimi sinyalinden gelir (1/Fosc)
- Bit4 T0SE: Timer0 Source Edge Select Bit / Timer0 Saat Kaynağı Kenarı Seçim Biti
- 1 = T0CKI bacağına uygulanan her düşen kenarda artar
- 0 = T0CKI bacağına uygulanan her yükselen kenarda artar
- Bit 3 PSA: Timer0 Prescaler Assignment Bit / Timer0 Önölçekçi Atama Biti
- 1 = Önölçekçi atanmaz, Timer0 saati önölçekçiden tamponlanarak verilir
- 0 = Önölçekçi atanır, Timer0 saati önölçekçinin çıkışından verilir
- Bit 2-0 T0PS2:T0PS0: Timer0 Prescaler Select bits / Timer0 Önölçekçi Oranı Seçim Bitleri
- 111 = 1/256 Önölçekleme oranı
- 110 = 1/128 Önölçekleme oranı
- 101 = 1/64 Önölçekleme oranı
- 100 = 1/32 Önölçekleme oranı
- 011 = 1/16 Önölçekleme oranı
- 010 = 1/8 Önölçekleme oranı
- 001 = 1/4 Önölçekleme oranı
- 000 = 1/2 Önölçekleme oranı
Yazılımda Timer0 aşağıdaki şekilde programlanmıştır:
- Timer0 8-bit kipinde,
- Timer0 saat kaynağı dahili osilatörden,
- Timer0 saat kaynağı düşen kenar,
- Timer0 önölçekçi atanmış
- Önölçekleme oranı = 1:256 olacak şekilde programlanmıştır.
Bu düzene göre Timer0 taşma ve yazılım sayaçlarının değerleri şöyle hesaplanır;
Dahili komut çevirimi frekansı (Fkomut):
Fosc = 1MHz = 1000000Hz
Fkomut = Fosc/4 = 1000000/4 = 250000Hz = 250KHz
Dahili komut çevrimi süresi (Tkomut):
Tkomut = 1/Fkomut = 1/250000 = 0,000004 saniye = 4 mikrosaniye
Timer0 sayma aralığı süresi (T0sas):
T0sas = Tkomut x önölçekçleme oranı
T0sas = 4us x 256 = 1024us
Yani Timer0, her 1024us'de bir, TMR0L yazmacının değerini bir artırır.
Timer0 kesme gecikmesi (T0kesme):
T0kesme = T0sas x (256 – Timer0 öndeğer) (burada öndeğer kullanılmıyor = 0)
T0kesme = 1024us x 256 = 262144us = 262,144ms
Yani her 262,144 milisaniyede bir TMR0L yazmacı 256'dan 0'a yuvarlanacak. 256'dan 0'a her yuvarlanışında bir taşma oluşacak ve bu taşma bir Timer0 kesmesi üretecek.
10 saniyelik süre üretmesi için yazılım sayacına yüklenecek desimal değerin hesabı:
10 saniye = 10000 milisaniye
Sayaç10 = 10000ms / 262,144ms
Sayaç10 = 38,14697265625
Aşağı yuvarlarsak; yazılım içinde SAY10 sayaç yazmacına yüklememiz gereken desimal değer 38.
30 saniyelik süre üretmesi için yazılım sayacına yüklenecek desimal değerin hesabı:
30 saniye = 30000 milisaniye
Sayaç30 = 30000ms / 262,144ms
Sayaç30 = 114,44091796875
Biz bunu 115'e yuvarlayalım 30s'den bir kaç ms fazla saysın sorun değil; öyleyse yazılım içinde SAY30 sayaç yazmacına yüklememiz gereken desimal değer 115.
İşte Timer0 donanımını ve asıl süreleri sayacak olan değişkenleri hazırladık. Sonraki aşamada kesmeleri hazırlayacağız.
Kesmelerin Yapılandırılması
PIC18 serisi kesmeleri 2 kademe önceliklendirebilecek şekilde tasarlanmıştır. Yani kesmeler Yüksek Öncelikli ve Düşük Öncelikli olarak yetkilendirilebilir. PIC12 ve PIC16 serilerindeki yalnızca bir tane INT kesmesinin aksine; INT0, INT1 ve INT2 olmak üzere toplam üç tane INT kesmesiyle donatılmıştır.
Şimdi kesmeleri düzenlerken kullandığımız kesme denetim yazmaçlarını inceleyelim. Burada yalnızca programda kullanacağımız yazmaçların ve denetim bitlerinin açıklamasını vereceğim. Bu yazmaçlarla ilgili daha ayrıntılı bilgiler için ürünün veribetine başvurabilirsiniz. Bu uygulama her ne kadar profesyonel amaçlara hizmet etmese de, senaryoyu olabildiğince gerçeğe yakın tutmaya çalıştığımdan önemli olayları saptamak ve zaman takibi yapmak için kesmelerden yararlanacağız. Bu yüzden motorlarla ilgili hata sinyallerini INT1 ve INT2 harici kesmelerini kullanarak saptayacağız. Motor hatalarını kritik olarak değerlendirdiğimiz için ilgili kesmeleri yüksek öncelikli olarak yapılandıracağız.
Bununla birlikte 10 ve 30 saniyelik zamanların takibini yapmak için Timer0 kesmesinden yararlanacağız. Bu uygulamada zamanlamayı çok kritik olarak değerlendirmediğimiz için ise Timer kesmesi düşük öncelikli olacak.
Bu kesme yapılandırmaları sonrasında INT1 ve INT2 yüksek öncelikli kesmeleri için kesme vektörü 0x8, Timer0 düşük öncelikli kesmesi için kesme vektörü 0x18 olacaktır.
PIC18 mikrodenetleyicilerinin sağladığı öncelikli kesme özelliğinden yararlanmak için RCON yazmacını yapılandırmalıyız. Bu yazmaçtaki IPEN bitini 1 yapmamız gerekir.
RCON Yazmacının Yapılandırılması
RCON (Reset Control Register): Sifirlama Denetim Yazmacı
| IPEN | SBOREN | - | RI | TO | PD | POR | BOR |
|---|---|---|---|---|---|---|---|
| Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
- Bit 7 IPEN: Interrupt Priority Enable Bit / Kesme Öncelik Etkinleştirme Biti
- 1 = Kesmelerde öcelik düzeylerini etkinleştir
- 0 = Kesmelerde öncelik düzeylerini etkisizleştir.
Bu yazmaçtan sadece kesme öceliği özelliğini etkinleştireceğiz. Bunun için yapmamız gereken IPEN bitini 1 yapmaktır.
INTCON Yazmacının Yapılandırılması
INTCON (Interrupt Control Register): Kesme Denetim Yazmacı
| GIE/GIEH | PEIE/GIEL | TMR0IE | INT0IE | RBIE | TMR0IF | INT0IF | RBIF |
|---|---|---|---|---|---|---|---|
| Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
Bit 7 GIE/GIEH: Global Interrupt Enable High priority / Yüksek öncelikli Kesmeleri Etkinleştirme Biti
IPEN = 0 iken (Kesme önceliği etkisizken):
- 1 = Maskelenmemiş tüm kesmeleri etkinleştirir
- 0 = Tüm kesmeleri etkisizleştirir
IPEN = 1 iken (Kesme önceliği etkinken):
- 1 = Tüm yüksek öncelikli kesmeleri etkinleştirir
- 0 = Tüm yüksek öncelikli kesmeleri etkisizleştirir
Bit 6 PEIE/GIEL: Global Interrupt Enable Low priority / Düşük öncelikli Kesmeleri Etkinleştirme Biti
IPEN = 0 iken (Kesme önceliği etkisizken):
- 1 = Maskelenmemiş tüm çevresel kesmeleri etkinleştirir
- 0 = Tüm çevresel kesmeleri etkisizleştirir
IPEN = 1 iken (Kesme önceliği etkinken):
- 1 = Tüm düşük öncelikli kesmeleri etkinleştirir
- 0 = Tüm süşük öncelikli kesmeleri etkisizleştirir
- Bit 5 TMR0IE: TMR0 Overflow Interrupt Enable Bit / TMR0 Taşma Kesmesi Etkinleştirme Biti
- 1 = Timer0 taşma kesmesi etkin
- 0 = Timer0 taşma kesmesi etkisiz
- Bit 2 TMR0IF: Timer0 Overflow Interrupt Flag Bit / Timer0 Taşma Kesmesi Bayrak Biti
- 1 = Timer0 taşma kesmesi oluştu (bu bayrak yazılımda temizlenmeli)
- 0 = Timer0 taşma kesmesi oluşmadı
Hatalı kesme oluşmasını önlemek için kesme bayraklarını sıfırlamak doğru bir tercih olur. Ardından INTCON yazmacından, yüksek ve düşük öncelikli kesmeleri GIEH ve GIEL bitlerini kurarak (lojik 1 yaparak) etkinleştirelim. Sonra TMR0IE bitini de kurarak Timer0 kesmesini etkinleştirelim.
Kesme yetki önceliği ve Timer0 düzenlemelerinin yapılması için yazmaçların nasıl programlanması gerektiğini gördük. Şimdi yüksek öncelikli kesme yetkisi olan INT1 ve INT2 harici kesmelerinin nasıl kurulacağını görelim. Bununla ilgili kullandığımız yazmaçlar ve açıklamaları şöyle:
INTCON2 Yazmacının Yapılandırılması
INTCON2 (Interrupt Control Regi̇ster 2): Kesme Denetim Yazmacı 2
| RBPU | INTEDG0 | INTEDG1 | INTEDG2 | - | TMR0IP | - | RB0IP |
|---|---|---|---|---|---|---|---|
| Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
- Bit 7 RBPU: PORTB Pull-Up Enable Bit/PORTB (dahili) Pull-up (dirençlerini) Etkinleştirme Biti
- 1 = Tüm PORTB Pull-up'ları etkisizleştirilir
- 0 = PORTB pull-up'ları bireysel port mandal (latch) değerlerine göre etkinleştirilir
- Bit 6 INTEDG0: External Interrupt 0 Edge Select Bit / Harici Kesme 0 Kenar Seçim Biti
- 1 = Yükselen kenarda kesme
- 0 = Düşen kenarda kesme
- Bit 5 INTEDG1: External Interrupt 1 Edge Select Bit / Harici Kesme 1 Kenar Seçim Biti
- 1 = Yükselen kenarda kesme
- 0 = Düşen kenarda kesme
- Bit 4 INTEDG2: External Interrupt 2 Edge Select Bit/Harici Kesme 2 Kenar Seçim Biti
- 1 = Yükselen kenarda kesme
- 0 = Düşen kenarda kesme
- Bit 2 TMR0IP: Timer0 Overflow Interrupt Priority / Timer0 Taşma Kesmesi Önceliği
- 1 = Yüksek öncelik
- 0 = Düşük öncelik
- Bit 0 RBIP: RB Port Change Interrupt Priority / RB Port Değişim Kesmesi Önceliği
- 1 = Yüksek öncelik
- 0 = Düşük öncelik
Burada dahili PortB pull-up dirençlerini kullanmadığımız için etkisizleştiriyoruz. INTEDG1 ve INTEDG2 bitlerini 0 yaparak INT1 ve INT2 kenarlarını düşen kenar yapıyoruz. Son olarak TMR0IP bitini Timer0 kesme önceliğini Düşük Öncelik yaptık.
INTCON3 Yazmacının Yapılandırılması
INTCON3 (Interrupt Control Regi̇ster 3): Kesme Denetim Yazmacı 3
| INT2IP | INT1IP | - | INT2IE | INT1IE | - | INT2IF | INT1IF |
|---|---|---|---|---|---|---|---|
| Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
- Bit 7 INT2IP: INT2 External Interrupt Priority Bit / INT2 Harici Kesme Önceliği Biti
- 1 = Yüksek Öncelik
- 0 = Düşük Öncelik
- Bit 6 INT1IP: INT1 External Interrupt Priority Bit / INT1 Harici Kesme Önceliği Biti
- 1 = Yüksek Öncelik
- 0 = Düşük Öncelik
- Bit 4 INT2IE: INT2 External Interrupt Enable Bit / INT2 Harici Kesme Etkinleştirme Biti
- 1 = INT2 harici kesmesi etkin
- 0 = INT2 harici kesmesi etkisiz
- Bit 3 INT1IE: INT1 External Interrupt Enable Bit / INT1 Harici Kesme Etkinleştirme Biti
- 1 = INT1 harici kesmesi etkin
- 0 = INT1 harici kesmesi etkisiz
- Bit 1 INT2IF: INT2 External Interrupt Flag Bit / INT2 Harici Kesme Bayrak Biti
- 1 = INT2 harici kesmesi oluştu (yazılımda temizlenmeli)
- 0 = INT2 harici kesmesi oluşmadı
- Bit 0 INT1IF: INT1External Interrupt Flag Bit / INT1 Harici Kesme Bayrak Biti
- 1 = INT2 harici kesmesi oluştu (yazılımda temizlenmeli)
- 0 = INT2 harici kesmesi oluşmadı
Burada ise INT1 ve INT2 kesmelerini yüksek öncelikli yapmak için INT1IP ve INT2IP bitlerini 1 yapıyoruz. Kesmeleri etkinleştirmeden önce INT1IF ve INT2IF kesme bayraklarını, olası istenmeyen kesmeleri önlemek için sıfırlıyoruz. Sonra sırasıyla INT1IE ve INT2IE bitlerini 1 yaparak bu iki kesmeyi etkinleştiriyoruz.
Assembly Kodu
; Copyright (c) 2017 Kozmotronik (İsmail Sahillioğlu)
;
; Permission is hereby granted, free of charge, to any person obtaining a copy
; of this software and associated documentation files (the "Software"), to deal
; in the Software without restriction, including without limitation the rights
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
; copies of the Software, and to permit persons to whom the Software is
; furnished to do so, subject to the following conditions:
;
; The above copyright notice and this permission notice shall be included in
; all copies or substantial portions of the Software.
;
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
; SOFTWARE.
;*********1_BASLAT_1_DUR_TUSUYLA_2_MOTORUN_KOSULLU_DENETIMI**********
LIST P=18F2550
#include "p18F2550.inc"
;********************DUZENLEME_BITLERI***********************
; CONFIG1L
CONFIG PLLDIV = 1 ; PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
CONFIG CPUDIV = OSC1_PLL2 ; System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
CONFIG USBDIV = 1 ; USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)
; CONFIG1H
CONFIG FOSC = INTOSC_XT ; Oscillator Selection bits (Internal oscillator, XT used by USB (INTXT))
CONFIG FCMEN = OFF ; Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
CONFIG IESO = OFF ; Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)
; CONFIG2L
CONFIG PWRT = ON ; Power-up Timer Enable bit (PWRT enabled)
CONFIG BOR = ON ; Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled))
CONFIG BORV = 3 ; Brown-out Reset Voltage bits (Minimum setting 2.05V)
CONFIG VREGEN = OFF ; USB Voltage Regulator Enable bit (USB voltage regulator disabled)
; CONFIG2H
CONFIG WDT = OFF ; Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
CONFIG WDTPS = 32768 ; Watchdog Timer Postscale Select bits (1:32768)
; CONFIG3H
CONFIG CCP2MX = ON ; CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
CONFIG PBADEN = OFF ; PORTB A/D Enable bit (PORTB<4:0> uclari sifirlama (reset) sonrasında dijital giris-cikis olacak sekilde duzenlendi)
CONFIG LPT1OSC = OFF ; Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
CONFIG MCLRE = ON ; MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
; CONFIG4L
CONFIG STVREN = ON ; Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
CONFIG LVP = OFF ; Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
CONFIG XINST = OFF ; Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
; CONFIG5L
CONFIG CP0 = OFF ; Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
CONFIG CP1 = OFF ; Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
CONFIG CP2 = OFF ; Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
CONFIG CP3 = OFF ; Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)
; CONFIG5H
CONFIG CPB = OFF ; Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
CONFIG CPD = OFF ; Data EEPROM Code Protection bit (Data EEPROM is not code-protected)
; CONFIG6L
CONFIG WRT0 = OFF ; Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
CONFIG WRT1 = OFF ; Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
CONFIG WRT2 = OFF ; Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
CONFIG WRT3 = OFF ; Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)
; CONFIG6H
CONFIG WRTC = OFF ; Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
CONFIG WRTB = OFF ; Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
CONFIG WRTD = OFF ; Data EEPROM Write Protection bit (Data EEPROM is not write-protected)
; CONFIG7L
CONFIG EBTR0 = OFF ; Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
CONFIG EBTR1 = OFF ; Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
CONFIG EBTR2 = OFF ; Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
CONFIG EBTR3 = OFF ; Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)
; CONFIG7H
CONFIG EBTRB = OFF ; Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)
;**********-------TANIMLAMA_VE_ATAMALAR--------**************
WREG_GC EQU 0X00 ;Kesmelerde eger gerekirse WREG ve STATUS yazmaclarinin yedeklenmesi
STAT_GC EQU 0X01 ;icin dosyalar.
SUREV_BYRK EQU 0X02 ;Surelerin doldugunu gosteren bayraklari tutan dosya.
ON EQU 1 ;10 saniye bayrak biti.
OTUZ EQU 2 ;30 saniye bayrak biti.
DON0 EQU 0X03 ;ARK gecikmesi icin tutma dosyasi.
DON1 EQU 0X04 ;ARK gecikmesi icin tutma dosyasi.
SAY10 EQU 0X05 ;10 saniye icin yazilim sayaci dosyasi.
SAY30 EQU 0X06 ;30 saniye icin yazilim sayaci dosyasi.
AAR_SR_SIFIRLA EQU 0X07 ;Motorlarin gereken calisma surelerini doldurmadan hata vermeleri durumunda
AAR1_SR EQU 1 ;kurulcak bayraklari tutacak dosya.
AAR2_SR EQU 2
;Her bir Portun giris cikis islevine ozel, program icinde kullanmak ve
;giris-cikislari daha kolay anımsayabilmek icin bir ad veriliyor.
#DEFINE M1HONAY PORTA,1 ;Motor-1 Hata (Duzeltildi) butonu girisi.
#DEFINE M2HONAY PORTA,2 ;Motor-2 Hata (Duzeltildi) butonu girisi.
#DEFINE DEI PORTA,3 ;Sayac gosterge etkinlestirme (Display Enable In) denetim cikisi.
#DEFINE INH PORTA,5 ;Sayac saat darbelerini engelleme (Clock Inhibit) denetim cikisi.
#DEFINE AAR1KES PORTB,1 ;Yuksek oncelikli Asiri Akim Rolesi-1 harici kesme giris ucu.
#DEFINE AAR2KES PORTB,2 ;Yuksek oncelikli Asiri Akim Rolesi-2 harici kesme giris ucu.
#DEFINE B PORTB,3 ;Baslatma butonu giris ucu.
#DEFINE DUR PORTB,4 ;Durdurma butonu giris ucu.
#DEFINE RST PORTC,0 ;Sayac sifirlama (reset) denetim cikisi.
#DEFINE M1HATA PORTC,1 ;Motor-1 Hata gosterge cikisi (LED).
#DEFINE M2HATA PORTC,2 ;Motor-2 Hata gosterge cikisi (LED).
#DEFINE M1 PORTC,6 ;Motor-1 surme cikis ucu.
#DEFINE M2 PORTC,7 ;Motor-2 surme cikis ucu.
;------------------------------------------------------------
ORG 0x0000 ;Baslangic adresine yonel
BRA GIRIS
ORG 0x0008 ;Yuksek oncelikli Hata kesme program adresine yonel
BRA DENET
ORG 0x0018 ;Dusuk oncelikli Timer0 kesme program adresine yonel
BRA SUREV
;-------------------------------------------------------------
;*********************ANA_PROGRAM*****************************
GIRIS
CLRF PORTC ;Tum PORTlari temizle/sifirla
CLRF PORTB ;
CLRF PORTA ;
CLRF SUREV_BYRK ;Sure durum bayraklarini tutan dosyayi temizle.
CLRF AAR_SR_SIFIRLA ;Motorlarda hata oldugunda sure sifirlama bayraklarini tutan dosyayi temizle.
CLRF INTCON ;Baslangicta veya herhangi bir RESET durumunda
CLRF INTCON2 ;istenmeyen kesmelerin olusmamasi icin
CLRF INTCON3 ;INTCONx ve T0CON yazmaclarini temizle.
CLRF T0CON ;Timer0 Denetim yazmacini ve ayarlarini temizle.
CLRF UCON ;RC4 ve RC5 bacaklarini I/O olarak sorunsuz
BSF UCFG, UTRDIS ;kullanabilmek icin gerekli islem (istege bagli).
CLRF PIE1 ;RESET sonrası hatali kesmelere gitmemesi icin
CLRF PIE2 ;yapilması gerekli işlem.
MOVLW 0X0E
MOVWF ADCON1 ;Analog girisler etkisiz; PORTA-B dijital giris-cikis.
MOVLW 0X80
MOVWF RCON ;Kesme onceligi etkin IPEN=1 (Interrupt Priority Enable).
MOVLW 0X4F ;Sistem Saati Kaynagi: Dahili 8MHz Osilator (SCS<1:0> = 11)
MOVWF OSCCON ;Dahili osilator hizi=1MHz (IRCF<2:0> = 100)
;Ben fazla osilator hizi gerekmedigi icin 1MHz olarak belirledim. Bu hiz duzenegin tutarli
;islemesi icin oldukca yeterlidir. Buna gore CPU saati Fosc/4 oldugundan; 250KHz olacaktir.
;Yani bir komutu isleme (execute) suresi T=1/F, T=1/250000, T = 4us (mikrosaniye) olur.
;Ayrintili osilator ayarlari icin urunun veribetinin (datasheet) 52. sayfasina bakiniz.
MOVLW 0X00
MOVWF TRISC ;C portu tumden cikis.
MOVLW 0XFF
MOVWF TRISB ;B portu tumden giris.
MOVLW 0XD7
MOVWF TRISA ;PORTA 5 ve 3 = cikis, 2 ve 1 = giris
BCF DEI ;Gostergeyi etkisizlestir.
BCF INH ;Saat darbelerini askiya al.
BSF RST ;Sayaci RESET/Sifirlama durumunda tut.
;
MOVLW 0XE0 ;Kuresel Kesmeler (GIEL), Cevresel Kesmeler (PEIE)
MOVWF INTCON ;ve Timer0 Kesmesi (TMR0IE) etkin
;
MOVLW 0XC0 ;PortB Pull-up direncleri etkisiz, AAR kesmeleri (INTEDG1, INTEDG2)
MOVWF INTCON2 ;dusen kenar tetikemeli, Timer0 kesme onceligi (TMR0IP): dusuk.
;
MOVLW 0XC8 ;AAR kesmeleri onceligi (INT2IP, INT1IP): yuksek. AAR1 kesmesi (INT1IE)etkin.
MOVWF INTCON3
;
MOVLW 0X57 ;PIC18F2550'de Timer0 ya 8-bit ya da 16-bitlik sayici/zamanlayici olarak kullanılabilir.
MOVWF T0CON ;Burada 8-bitlik kipte (modda) kullanilmistir (T08BIT=1). Timer0 saat kaynagi (T0SE): Dahili saat kaynagi
;Ayrica bu aygitta Onolcekci (Prescaler) yalnizca Timer0 icin kullanilmaktadir.
;Onolcekci (prescaler) oranı: 1/256 (T0PS<2:0> = 111)
MOVLW .38
MOVWF SAY10 ;10 saniye icin yazilim sayaci dosyasi; desimal 38 ile onyukle.
MOVLW .115
MOVWF SAY30 ;30 saniye icin yazilim sayaci dosyasi; desimal 115 ile onyukle.
; ANA PROGRAM BASLANGICI
BASLAT ;0X00
BTFSS B ;Baslat butonu basılı mı?
GOTO BASLAT ;Hayir, oyleyse bailana dek denetlemeyi surdur (BASLAT'a git)
CALL ARK ;Evet, oyleyse buton arkini onlemek icin yaklasik 50ms bekle
BSF M1 ;Motor-1'i calistir.
NOP ;Islem yok
BSF DEI ;Sayac gostergesini etkinlestir.
NOP ;Islem yok.
BCF RST ;Sayaci (CD4026x2) etkinlestir.
NOP ;Islem yok.
BSF T0CON, TMR0ON ;Timer0'i etkinlestir.
BASLAT2
BTFSS SUREV_BYRK, ON ;10 saniyenin dolmasini bekle
GOTO BASLAT2 ;10 saniye dolana kadar dongude kal.
BCF DEI ;Gostergeyi kapat.
NOP
BSF RST ;Sayicilari sifirla
CLRF AAR_SR_SIFIRLA ;AAR kesmesinin AAR sure sifirlama bayraklarını temizle
BSF INTCON3, INT2IE ;M2 calismadan once AAR2 (koruma/hata) kesmesini etkinlestir
BSF M2 ;M2 yi calistir.
CALL ARK ;50ms gecik.
BSF DEI ;Gostergeyi yeniden ac.
NOP
BCF RST ;Sayicilari sifirlama durumundan cikar.
M2_BEKLE
BTFSS SUREV_BYRK, OTUZ ;30 saniyenin dolmasini bekle
GOTO M2_BEKLE ;30 saniye dolana dek dongude kal.
BCF DEI ;Gstergeleri kapat
CALL ARK ;Gecikme
BSF RST ;Sayma islemleri bitti, Sayicilari sifirla
NOP
DURM2 BTFSC DUR ;Durdurma butonu basili mi?
GOTO DURM2 ;Hayir, oyleyse basilana kadar durumu koru ve dongude kal.
CALL ARK ;Evet, buton arkini onlemek ici gecikme alt progamini cagir.
BCF INTCON3, INT2IE ;AAR2 kesmesini etkisizlestir.
BTFSC INTCON3, INT2IE ;AAR2 kesmesinin etkisiz oldugundan emin ol
BRA $-2 ;Hala etkisiz degilse etkisizlestirmek icin 2 adim geriye git.
BCF M2 ;Etkisizlestirildiyse once Motor2'yi durdur.
CALL ARK
CALL ARK
CALL ARK ;Yaklasik 150ms bekle
DURTUM
BTFSC DUR ;Durdurma butonu yeniden basili mi?
GOTO DURTUM ;Hayir, oyleyse basilana kadar dongude kal.
CALL ARK ;Evet, ark gecikmesi.
RESET ;Tum duzenegi sifirla (resetle).
; YAKLASIK 50ms'LIK GECIKME ALT PROGRAMI
ARK
MOVLW .65
MOVWF DON0
ARK1 MOVLW .255
MOVWF DON1
ARK2 DECFSZ DON1, 1
GOTO ARK2
DECFSZ DON0, 1
GOTO ARK1
RETURN
;**********************ASIRI_AKIM/YUK/HATA_KESME_SERVIS_RUTINI****************************
DENET ;Kesme kayanagini belirle
CLRF INTCON ;Kesmeleri etkisizlestir
BCF T0CON, TMR0ON ;Timer0 i kapat
BCF DEI ;Gostergeyi kapat
NOP
BSF INH ;Sayicinin saat darbelerini engelle.
BTFSC INTCON3, INT1IF ;AAR1 kesmesi mi?
GOTO AAR1 ;Evet, AAR1 kesme servisine git
BTFSC INTCON3, INT2IF ;Hayir, AAR2 kesmesi mi?
GOTO AAR2 ;Evet, AAR2 kesme servisine git
BRA AAR_SON ;Hayir, ikisinden hiç biri dgilse kesmeyi sonlama servisine git
; ASIRI AKIM/YUK/HATA-1 KESME ALT PROGRAMI
AAR1
BCF M1 ;M1 i durdur
AAR1_1
BTG M1HATA ;M1 icin hata gostergesinden sinyal ver
CALL ARK ;Gecikme
BTFSS M1HONAY ;Hata duzeltme onaylandi mi?
GOTO AAR1_1 ;Hayir, hata sinyali vermeyi surdur (AAR1_1'e geri don)
BTFSS AAR1KES ;Evet, hata duzeltildi mi?
GOTO AAR1_1 ;Hayir, hata sinyali vermeyi surdur (AAR1_1'e geri don)
BTFSS SUREV_BYRK, ON ;Evet, 1. Motor 10s calisti mi?
CALL AAR1_SR_SIFIRLA ;Hayir, oyleyse yeniden 10 sn saymak icin alt programi cagir.
BTFSS AAR_SR_SIFIRLA, AAR1_SR ;Evet, 1. Motor 10s calismadan durdu mu?
CALL M2BEKLE_KUR ;Hayir, o zaman yeniden 30sn calismasi icin alt prgrmi cagir.
BTFSS AAR_SR_SIFIRLA, AAR1_SR ;Evetse, 1. motor yeniden kurudu mu?
BSF M1 ;Evetse, bu komutu atla cunku zaten 1. motor BASLAT2_KUR alt programında devreye alınacak.
;Hayirsa, bu komutu isle ve 1. Motoru calistir.
BCF M1HATA ;M1 Hata gostergesini kapat
BRA AAR_SON ;Kesme sonlama servisine git
; ASIRI AKIM/YUK/HATA-2 KESME ALT PROGRAMI
AAR2
BCF M2 ;Motor-2 yi durdur.
AAR2_1
BTG M2HATA ;M2 icin hata sinyali ver
CALL ARK ;Gecikme
BTFSS M2HONAY ;Hata duzeltme onaylandi mi?
GOTO AAR2_1 ;Hayirsa, hata sinyali dongusunde kal.
BTFSS AAR2KES ;Evetse, Hata duzeltildi mi?
GOTO AAR2_1 ;Hayirsa, hata sinyali dongusunde kal.
BTFSS SUREV_BYRK, OTUZ ;Evetse, 2. motor 30s calisti mi?
CALL AAR2_SR_SIFIRLA ;Hayirsa, 2. motoru yeniden 30s calistirma alt prg cagir.
BTFSS AAR_SR_SIFIRLA, AAR2_SR ;Evetse, 2. motor yeniden calistirilmis mi?
BSF M2 ;Hayirsa 2. motoru calistir. Evetse burayı atla.
BCF M2HATA ;Evetse, Hata sinyali vermeyi durdur.
; ASIRI AKIM/YUK/HATA KESME SERVIS RUTINI SONLAMA ALT PROGRAMI
AAR_SON ;Kesme surec ve islemlerinin sonlandirildigi kesme alt program yigini
BCF RST ;Sayaclari sifirlama durumundan cikar.
BCF INTCON3, INT1IF ;AAR1 kesme bayragini temizle.
BCF INTCON3, INT2IF ;AAR2 kesme bayragini temizle.
;Kesme bayraklarini temizleme isi cok onemli. Eger kesmeden cikmadan temizlenmezse hatali kesmeler
;olusabilir. O yuzden bu bayraklarin temizlendiginden emin olduktan sonra kesmeden cikacagiz.
BTFSC INTCON3, INT1IF ;AAR1 kesme bayraginin temizlendiginden emin ol.
BRA AAR_SON ;Temizlenmemisse temizleme islemini yeniden yapmak icin AAR_SON a geri git.
BTFSC INTCON3, INT2IF ;AAR2 kesme bayraginin temizlendiginden emin ol.
BRA AAR_SON ;Temizlenmemisse temizleme islemini yeniden yapmak icin AAR_SON a geri git.
MOVLW 0XE0 ;Bayraklarin temizlendiginden emin olduktan sonra buradan devam et.
MOVWF INTCON ;INTCON kesme denetim yazmacina yeniden normal degerleri yukle.
BTFSC AAR_SR_SIFIRLA, AAR1_SR ;10s dolmadan 1. motorda hata oldu mu?
BRA BASLAT2_KUR ;Evetse 1. motoru yeniden kurmak icin BASLAT2_KUR alt prg dallan.
BTFSC AAR_SR_SIFIRLA, AAR2_SR ;Hayirsa, 2. motorda 30s dolmadan hata oldu mu?
BRA BASLAT2_KUR ;Hata olduysa (evetse), 1. ve 2. motoru yeniden kurmak icin BASLAT2_KUR alt prg dallan.
BTFSS SUREV_BYRK, OTUZ ;Hayirsa, 30 saniye bayragi = 1 mi?
BSF T0CON, TMR0ON ;30s bayragi = 1 Degilse, Timer0 i yeniden saymasi icin etkinlestir.
BTFSS SUREV_BYRK, OTUZ ;30s bayragi = 1 ise Timer0 i etkinlestirmeyi atla ve bu bayragi yeniden denetle.
BSF DEI ;Bayrak 1 ise, sayma islemi bitti, o yuzden Sayac gostergesini etkinlestirmeyi atla.
;Bayrak 0 ise sayma islemi suruyor, bu yuzden gostergeyi etkinlestir.
BCF INH ;Sayac saat darbesini askiya almayi durdur.
RETFIE ;Kesmeden cik.
AAR1_SR_SIFIRLA ;1. Motor gereken sure (10saniye) doluncaya dek calismadiysa buradaki komutlar islenir.
BTFSS AAR_SR_SIFIRLA, AAR2_SR ;2. Motor erken durdu bayragi kurulmussa, bir alttaki komutu atla.
BSF AAR_SR_SIFIRLA, AAR1_SR ;1. Motor 10s calisamadan durdu, erken durma bayragini kur.
BTFSC M2 ;2. Motor calisiyor mu?
CALL M2BEKLE_KUR ;Evetse 1. motor sureden bagimsiz yeniden calistirilabilir cunku 2. motor zaten devrede.
;Bu yuzden her seyi normale donderip 2. motorun en az 30s calismasını beklemek icin M2BEKLE_KUR alt prg cagir.
BSF RST ;2. Motor calismiyorsa, sayicilari yeniden sayma icin sifirla,
CLRF TMR0L ;1. Motoru yeniden 10s calistirmak icin Timer0 i sifirla.
MOVLW .38 ;Yeniden 10s saymak icin,
MOVWF SAY10 ;SAY10 dosyasina ondegerini yeniden yukle.
RETURN ;Cagirildigin yere geri don.
AAR2_SR_SIFIRLA ;2. Motor gereken sure (30saniye) doluncaya dek calismadiysa buradaki komutlar islenir.
BSF AAR_SR_SIFIRLA, AAR2_SR ;2. Motor 30s calismadan durdu, erken durma bayragini kur.
CLRF SUREV_BYRK ;10s ve 30s bayraklarini temizle (cunku sayma yeniden baslayacak)
BCF M1 ;1. Motoru durdur, cunku 2. Motorun yeniden calisabilmesi icin 1. Motor yeniden 10s calismali.
CALL AAR1_SR_SIFIRLA ;Simdi 1. motoru yeniden kurmak icin AAR_SR_SIFIRLA alt prg cagir.
MOVLW .115 ;Yeniden 30 s saymak icin,
MOVWF SAY30 ;SAY30 dosyasina ondegerini yeniden yukle.
RETURN ;Cagirildigin yere geri don.
BASLAT2_KUR ;Motorlarin herhangi birinde basladiktan sonra ve sureleri dolmadan once hata olursa buradaki komutlar islenir.
BSF M1 ;1. Motoru yeniden caistir.
BCF INH ;Sayicilarin saat darbesini engellemeyi kaldir.
BSF DEI ;Sayici gostergelerini etkinlestir.
BSF T0CON, TMR0ON ;Timer0 i yeniden etkinleştir.
BCF RST ;Sayicilari sifirlama durumundan cikar
BRA BASLAT2 ;BASLAT2 etiketine dallan.
M2BEKLE_KUR ;Eger 1.motor 10s calistiktan sonra hata vermis ve 2. motor calismaya baslamissa buradaki komutlar islenir.
BCF INTCON3, INT1IF ;AAR1 kesme bayragini temizle
BCF INTCON3, INT2IF ;AAR2 kesme bayragini temizle
BTFSC INTCON3, INT1IF ;
BRA M2BEKLE_KUR
BTFSC INTCON3, INT2IF ;
BRA M2BEKLE_KUR ;Bayraklarin temizlendiginden emin olana kadar dongude kal.
MOVLW 0XE0
MOVWF INTCON ;INTCON kesme denetim yazmacini yeniden normal degerleriyle yukle.
BTFSS SUREV_BYRK, OTUZ ;2. Motor 30s calisti mi?
CALL SAYAC_KUR ;Evetse, burayı atla, hayırsa sayaci yeniden kurmak icin alt prgm cagir.
BRA M2_BEKLE ;M2_BEKLE etiketine dallan.
SAYAC_KUR
BSF T0CON, TMR0ON ;Timer0 i yeniden etkinlestir.
BSF DEI ;Gostergeleri yeniden etkinlestir.
BCF INH ;Saat darbesini engellemeyi kaldir.
BCF M1HATA ;1. Motor hata gostergesini temizle.
BSF M1 ;1. Motoru calistir.
RETURN
;***********************ZAMANLAMA_KESME_SERVIS_RUTINI***************************
SUREV ;Kac saniye sayilacaginin belirlendigi bolum.
BCF INTCON, TMR0IE ;Timer0 kesmesini etkisizlestir.
BTFSC M2 ;2. Motor calismiyorsa,
GOTO SUREV2 ;Bu komutu atla.
DECFSZ SAY10,F ;10s icin yazilim sayacını 1 eksilt ve dosyaya sakla.
GOTO BITTI ;SAY10 = 0 ise bu komutu atla. Degilse kesmeden cikmak icin BITTI etiketine git.
BSF SUREV_BYRK, ON ;SAY10 = 0 ise 10s doldu, 10s bayragini kur.
SUREV2 ;30s sayim isleminin yapildigi bolum.
DECFSZ SAY30,F ;30s icin yazilim sayacını 1 eksilt ve dosyaya sakla.
GOTO BITTI ;SAY30 = 0 ise bu komutu atla. Degilse kesmeden cikmak icin BITTI etiketine git.
BSF SUREV_BYRK, OTUZ ;SAY30 = 0 ise 30s doldu, 30s bayragini kur.
BITTI ;Timer0 kesmesinden cikis yapilan bolum.
BCF INTCON, TMR0IF ;Timer0 kesme bayragini temizle.
BSF INTCON, TMR0IE ;Timer0 kesmesini yeniden kur
RETFIE ;Timer0 kesmesinden cik.
BITIR
GOTO BITIR ;Program sonu
ENDDevre tasarımı ve yazılımı iyi bir pratik ve uygulama olması açısından bizzat bana aittir. Yanlızca anlatımda kullanılan resimler google aramaları ve ürünlerin veribetlerinden (datasheet) elde edilmiştir.
Bu uygulamanın kodları MIT lisansı altında paylaşılmaktadır.