Merhaba Forumdaşlar;
Yaşadığım bir problem ve çözümü hakkında paylaşımda bulunmak istedim.
CCS de Delay fonksiyonunu hepimiz biliyoruz. ms ve saykıl gecikmeler yapabiliyoruz. Mümkün olduğunca bu fonk. kullanmayın. Hatta hiç kullanmayın.
Herşey yolunda gözüken program
@Allegro hocamın önerdiği elektromanyetik röle testinde programın kilitlenmelerine yol açtı. Basit sayaçlar ile yaptığım aynı gecikmelerde ise hiçbir sıkıntı yaşamadım.
Bilginize
Not: Programınız bittikten sonra test için; bobini yük çeken bir röleyi işlemcinize yakınlaştırarak aynı besleme ile bobini sürekli tetikleyerek işlemcinizi gözlemleyin.
Sevgi ile kalın
Sorunun çözümü olan kodları paylaşırmısınız
Test yontemini anlayamadim. Biraz aciklayabilirmisin. Bobini yuk ceken derken kontaklarina mi yuk baglayacaz.
Kartla bobini ayni kaynaktan mi besleyecez
ne alakasi var, diye dusundun mu?
delay fonksiyonu ne kadar nop eklersem bu gecikmeyi elde ederim diye calismiyor mu? nasil oluyorda bu fonksiyon islemcini gurultude tikiyor? senin islemci normaldede tikaniyor olabilir mi?
Alıntı yapılan: izturk - 14 Şubat 2018, 19:56:11
Test yontemini anlayamadim. Biraz aciklayabilirmisin. Bobini yuk ceken derken kontaklarina mi yuk baglayacaz.
Kartla bobini ayni kaynaktan mi besleyecez
Elbette
Bobini kalın bir röle bul, rölenin bobinlerine birkaç metre kablo bağla. Bobinlerini Çalışan Sistemin beslemesine sürekli temas ettir, Röle işlemciye yakın olsun. Şenliği seyret.
Sistemin Doğrudan 5 volt besleme ise işlemcin zarar görebilir dikkat et. 12V beslemeli sistem daha sağlıklı gözlemleniyor.
Alıntı yapılan: OptimusPrime - 14 Şubat 2018, 20:05:20
ne alakasi var, diye dusundun mu?
delay fonksiyonu ne kadar nop eklersem bu gecikmeyi elde ederim diye calismiyor mu? nasil oluyorda bu fonksiyon islemcini gurultude tikiyor? senin islemci normaldede tikaniyor olabilir mi?
C.1.Düşündüm ve çok şaşırdım.
C.2.evet öyle olması gerekirdi.
C.3.Bende anlamadım.
C.4.İlk yazdıklarımı tekrar oku.
Not: Test basit denemesi bedava
dusundun, cok sasirdin, isin icinden cikamayinca delay fonksiyonuna faturayi kesip gonderdin, gibi geliyor bana. anlattiklarina bakilirsa. oyle bir denk gelmis sansa duzeltmis olabilirsin.
Alıntı yapılan: OptimusPrime - 14 Şubat 2018, 22:23:30
dusundun, cok sasirdin, isin icinden cikamayinca delay fonksiyonuna faturayi kesip gonderdin, gibi geliyor bana. anlattiklarina bakilirsa. oyle bir denk gelmis sansa duzeltmis olabilirsin.
Sana nasıl geldiği kimin umurunda. Ben tecrübemi yazmışım. Elektromanyetik Gürültüde kodunu test etmek isteyen eder. Sen etmez çalıştığı şekilde yürür gidersin.
dusundun, sasirdin, sende anlamadin (C1, C3) ama tecrube olarak yazdin. olsun, iyi yapmissin canim ellerine saglik. ;D
sinirlenmeye gerek yok. ;)
Elektromanyetik Gürültüde kilitlenme donanımsal oluyor. Kod ile düzeltmek keşke mümkün olsa? Watchdog da işe yaramıyor.
1 ay kadar önce bahsetmiştik latch up denen olay. Delay yerine başka fonksiyon yazmakla düzelmezzz!
Alıntı yapılan: OptimusPrime - 14 Şubat 2018, 20:05:20
ne alakasi var, diye dusundun mu?
delay fonksiyonu ne kadar nop eklersem bu gecikmeyi elde ederim diye calismiyor mu?
Sorduğun soru bilginin ne kadar engin olduğunu kanıtlıyor. Senin anladığın dilden cevap veriyorum. Daha önce led yakmaktan başka bir program yazdığını zannetmiyorum ama al bir röle ile deneme yap. Röleyi nasıl kullanacağını bilmiyorsan İstanbul Bostancıdayım özelden telefon vereyim gel öğreteyim sana evlat.
Bencede şansa düzelmiş,
problemin veya çözümün
delay fonksiyonuyla alakası olması çok düşük.
Kilitlenmeyi biliyoruz. Görüyoruz.ispata gerek yok. Röle, trafo, bobin.. biz de başarıyla kilitleyebiliyoruz.
Çözüm nedir? Delay yerine bin tane nop yazmak çözmez ki.
Eminseniz sorunlu kodu ve çözümlü kodu paylaşın. İnceleyelim.
delay fonksiyonu ne kadar nop eklersem bu gecikmeyi elde ederim diye calismiyor mu? diye soran arkadaş iyi okusun.
Burada CCS gibi bir derleyicinin bug ıını felan bulma gayreti içinde değilim. Ayrıca kimseye birşey ispat etmek durumunda hiç değilim. Sadece bir tecrübe paylaşmak istedim ama belliki bu yazdıklarım CCS ye laf kondurmayan veya birşeyler ispat etmek isteyen arkadaşların ağırına gitmiş:) İyi veya kötü bir tecrübeden faydalanıp testi denemek yerine klavye başında ahkam kesen bu tipler malesef elektroniğe başlamamı sağlayan bu foruma hiç yakışmıyor.
Ayrıca Şans ile hiç program çalıştırmadım. Böyle birşey nasıl oluyor onada inanmam. Şans ile program yazıldığına inannan tipler uzak dursun...
Neyse sıkıntının kaynağını merak edenler için uzun lafın kısası gelelim varsaydığım CCS nin otomatik gecikme alt programına,
CCS de İki farklı Gecikme kodu her ikiside 20 ms ( Yorumlar kodların içinde)
1.si CCS nin kendi otomatik gecikme fonksiyonu;
.................... #use delay(internal=16MHz) // Delay_ms() fonksiyonu ile derleyici tarafından tasarlanan Alt Program
058F: MOVLW 20
0590: MOVWF 05
0591: MOVLW 68
0592: MOVWF 04
0593: MOVF 00,W
0594: BTFSC 03.2
0595: GOTO 5A4
0596: MOVLW 05
0597: MOVWF 78
0598: CLRF 77
0599: DECFSZ 77,F
059A: GOTO 599
059B: DECFSZ 78,F
059C: GOTO 598
059D: MOVLW 2E
059E: MOVWF 77
059F: DECFSZ 77,F
05A0: GOTO 59F
05A1: GOTO 5A2
05A2: DECFSZ 00,F
05A3: GOTO 596
.................... delay_ms( 20 );// İle Delay_ms() alt program çağırılıyor.
058C: MOVLW 14
058D: MOVLB 01
058E: MOVWF 38
diğeri basit ve sade kullanıcı tanımlı yani benim tanımladığım bir delay
.................... for(DUMMYSAYAC=0;DUMMYSAYAC!=8000;DUMMYSAYAC++){;}// 16MHZ -> 8000 x 0,25 ins.cy = 20 ms DELAY
0C6C: MOVLB 01
0C6D: CLRF 32
0C6E: CLRF 31
0C6F: MOVF 31,W
0C70: SUBLW 40
0C71: BTFSS 03.2
0C72: GOTO 477
0C73: MOVF 32,W
0C74: SUBLW 1F
0C75: BTFSC 03.2
0C76: GOTO 47B
0C77: INCF 31,F
0C78: BTFSC 03.2
0C79: INCF 32,F
0C7A: GOTO 46F
Şimdi bu Disassembly list i neden paylaştın diyecek olursanız. İşte Burada ASM + PIC16 ve PIC18 mimarisi devreye giriyor. ASM de 1K üzeri Programı olan 16F lerden başlamak üzere, 16F MIDRANGE ki bu benim şu an kullandığım ve 18F lerde KESMElerde, bol STACKlı alt program çağırmalarında VEKTOR ler, PAGE ler arası ve varsa BANK lar arası uzun dallanmalarda kesinlikle goto komutu tavsiye edilmez. Onun yerine branch komutu yani BRA kullanılır. Goto ile hata mesajı almaksızın programın 8 bit üzeri adres yollarında farklı saçma sapan yerlere dallanması muhtemeldir.
Bir diğer önemli husus ise yukarıda saydığım durumlarda Alt Program çağırmaları mutlaka CALL, LCALL , CALLW gibi Komutlar ile yapılır.
Zor koşullarda Besleme gerilimi ani düşüş/yükseliş eğilimlerinde aynı anda yukarıda saydığım durumlar esnasında program dallanmalarında, alt program çağırım ve geri dönüşlerde doğru komut çalışmaz ise problem yaşanmayacağını kim garanti edebilir ? ASM yazarken 16f midrange ve 18F lerde asla goto kullanmadım. Tüm Listeyi incelediğimde goto lar Page ve Vektör değişikliğinden sonra opcode adresi kısaltılarak dallanmış. Alt program çağırmalarında Call kullanılmış ama delay fonksiyonunda böyle bir komut yok. Call komutu çağrıldığında stack bilgisini hafızada tutar, return ile geri döndiğinde çağrıldığı yere sağlıklı dönüşünü sağlar.
Son olarak; ilk yazımda çalışan denenmiş, bilgisayar ortamında ve çeşitli iç/dış ortamlarda test edilmiş, (defalarca simüle edildiğinden bahsetmiyorum bile) programım, kendi beslemesiyle yoğun elektromanyetik gürültüye maruz kalmasından doğan sorunun delay fonk. kullanmayarak çözdüğümden bahsettim.
CCS nin delay fonk. hatalıdır diye bir iddiam yok, hiç te olmadı. Kodlarını Bu test ile denemekte herkes özgürdür.
Yoğun elektronik gürültüde o işlemcinin çalışacağını kim söyledi ki size?
Onu Şans ile kod çalıştıranlara sormak lazım.
En zor koşulda çalışması için kod yazılır. Yok yazdım çalışıyo yeterli diyende var elbette. Onlara lafım yok.
Hiç yoğun gürültü altında çalışacak elektronik teçhizat içeren makine panosu açtınız mı bilmiyorum,
Seksen tane filtre, koruma, şok bobini ıvır zıvır tertibat var,
Aynı kod bir pcb de çalışıyorken diğer pcb de çalışmayabilir,
Bu noktada sizin tasarımınız nedir, bu noktalara baktınız mı bakmadınız mı anlattıklarınızdan belli olmuyor,
O sebepten boyle yetersiz test ile ne CCS e, ne PIC MCU ya ne de bir başka şeye suç atmamalısınız,
Ayrıca,
Diyelim ki elektromanyetik röle testi yaptınız,
İşlemciniz kilitlendi,
Sebebi nedir?
Yüksek ihtimal mclr ucunda artan voltaj işlemciyi programlama moduna soktu,
Şimdi burada suç işlemci üreticisinin mi? yazılımcının mı?
Siz buna benzer bir durumu yazılıma takla attırarak çözebilirsiniz ama o akını b.kuna denk düşürmek olur,
Doğrusu işlemciyi o duruma ne sokuyor, onu çözmektir,
Alıntı yapılan: esensoy - 15 Şubat 2018, 09:36:37
Aynı kod bir pcb de çalışıyorken diğer pcb de çalışmayabilir,
Bu noktada sizin tasarımınız nedir, bu noktalara baktınız mı bakmadınız mı anlattıklarınızdan belli olmuyor,
O sebepten boyle yetersiz test ile ne CCS e, ne PIC MCU ya ne de bir başka şeye suç atmamalısınız,
Yeterli gördüğünüz bir test öneriniz varsa memnuniyet ile yapmak isterim.
Alıntı yapılan: esensoy - 15 Şubat 2018, 09:36:37
Doğrusu işlemciyi o duruma ne sokuyor, onu çözmektir,
Kullandığım 16F Midrange diye tabir edilen yeni nesil 16F işlemcimde Kesme için ayrıca tanımladığım spesifik delay fonk. olmasına rağmen alt stacklarda 1 saykıllık gecikme yaptığım testte program kritik hata verdi. Sildim düzeldi. Zaten bunu anlatmaya çalıştım.
Alıntı yapılan: Pyrodigy - 15 Şubat 2018, 01:00:15
...
Şimdi bu Disassembly list i neden paylaştın diyecek olursanız. İşte Burada ASM + PIC16 ve PIC18 mimarisi devreye giriyor. ASM de 1K üzeri Programı olan 16F lerden başlamak üzere, 16F MIDRANGE ki bu benim şu an kullandığım ve 18F lerde KESMElerde, bol STACKlı alt program çağırmalarında VEKTOR ler, PAGE ler arası ve varsa BANK lar arası uzun dallanmalarda kesinlikle goto komutu tavsiye edilmez. Onun yerine branch komutu yani BRA kullanılır. Goto ile hata mesajı almaksızın programın 8 bit üzeri adres yollarında farklı saçma sapan yerlere dallanması muhtemeldir.
Bir diğer önemli husus ise yukarıda saydığım durumlarda Alt Program çağırmaları mutlaka CALL, LCALL , CALLW gibi Komutlar ile yapılır.
Zor koşullarda Besleme gerilimi ani düşüş/yükseliş eğilimlerinde aynı anda yukarıda saydığım durumlar esnasında program dallanmalarında, alt program çağırım ve geri dönüşlerde doğru komut çalışmaz ise problem yaşanmayacağını kim garanti edebilir ? ASM yazarken 16f midrange ve 18F lerde asla goto kullanmadım. Tüm Listeyi incelediğimde goto lar Page ve Vektör değişikliğinden sonra opcode adresi kısaltılarak dallanmış. Alt program çağırmalarında Call kullanılmış ama delay fonksiyonunda böyle bir komut yok. Call komutu çağrıldığında stack bilgisini hafızada tutar, return ile geri döndiğinde çağrıldığı yere sağlıklı dönüşünü sağlar.
Son olarak; ilk yazımda çalışan denenmiş, bilgisayar ortamında ve çeşitli iç/dış ortamlarda test edilmiş, (defalarca simüle edildiğinden bahsetmiyorum bile) programım, kendi beslemesiyle yoğun elektromanyetik gürültüye maruz kalmasından doğan sorunun delay fonk. kullanmayarak çözdüğümden bahsettim.
CCS nin delay fonk. hatalıdır diye bir iddiam yok, hiç te olmadı. Kodlarını Bu test ile denemekte herkes özgürdür.
BANK uzun dallanma diye bir şey yoktur,
PAGE ve BANK kavramlarını karıştırıyorsunuz,
Vektör dallanma zaten programcının değil
MCU nun kesme vs. durumda kendi yaptığı dallanma,
buna müdahale zaten edilemez ancak
vektör dallanmadan dönüşün doğru yere olması için önlem alınır,
1k değil, 2k dan sonra (önlem alınmazsa) problem çıkar
16F de GOTO veya CALL komutu 11 bit adresleme yapar, 8 bit değil,
(BRA ise bulunulan adresten +1023 -1024 komut atlayabilen
relative address atlama komutudur)
LCALL dediğiniz bir OPCODE değildir,
derleyici komutudur,
LCALL kullanılırsa; CALL komutundan önce
gerekli PAGE ayarını programcının yerine derleyici yapar,
aynı şekilde çalışan LGOTO da var.
Örnek konu:
https://www.picproje.org/index.php?topic=58682.0 (https://www.picproje.org/index.php?topic=58682.0)
Alıntı yapılan: Pyrodigy - 15 Şubat 2018, 08:19:08
...
En zor koşulda çalışması için kod yazılır.
...
Tamamen katılıyorum.
Pyrodigy, Sizin işlemci, Delay Fonksiyonundan dolayı sapıttığını sanmıyorum.
Arkadaşlar da bunu belirtmişler.
Çok Şiddetli Radio Dalgaları,İşlemci beslemesi üzerinde olabilecek Ripiller
İşlemcinin Sapıtmasına Sebep olabilir.
Sanırım Sizin işlemicde olan durum şu.Fail Safe Clock
Bobin Testi yaptığınızda İşlemci Clock Fazı kayıyor yada çok kısa bir süreliğine
kapanıp açılıyor.Bazı işlemcilerde bunun için özel önlemler var.
Sizin hatanın sebebi budur diye tahmin ediyorum.
İşlemci delay fonksiyonu çalışırken dahili RC osc kullanılıyor, kod ile yapılırsa kristal osc kullanılıyor olabilir mi?.
Bu osc lerin parazite karşı duyarlılığı farklıysa, bir durumda kilitlenir diğerinde kilitlenmeyebilir.
CCS C de delay fonksiyonu kullanırken
#USE DELAY (restart_wdt)
opsiyonunu kullanırsanız ve programınız EMC problemlerinden kitlenirse WDT işe yaramıyor. Ama bu opsiyonu kullanmassanız delay fonksiyonu rahatlıkla kullanabilirsiniz. Program kitlense bile WDT sistemi resetler ve kitlenmeyi önler.
EMC problemlerinde(latch up) WDT işe yaramıyor.
WDT ı programınızın uygun yerinde kullanırsanız ve tüm programda 1 kez kullanırsanız kesinlikle işe yarıyor. Dediğiniz durumda WDT kullanılamayacak olsa başka ne işe yararki. Programın içine 3-5 tane restart_wdt() serpiştirirseniz dediğiniz doğru. Kitlenmeden kurtulmuyor.
https://www.picproje.org/index.php/topic,71734.msg550584.html#msg550584
İlgili testi çalışan programına uygulayabilecek ve gözlemleyen varsa çok sağlıklı ilerlenebilir. Maksat üzüm yemek. Varsayımlar ile biryere varılmıyor.
Ben bu testi 16F1526 işlemci kullanarak 16MHZ dahili OSC ile Kesmeli çift donanımsal UART dan (rs485) 19200bps hızda 1000 byte Loopback test ve aynı anda 8 kanal yazılımsal SPI dan 48 adet Led ve Buton testini CCS nin delay fonk.suz başarılı şekilde çalıştırdım. 3 adet Timer, Button kesmesi de vardı.
Aynı test altında Herbir kesme için ayrı Delay fonk. tanımlamama rağmen bu fonk. kullandığımda program resetsiz kilitleniyordu.
Sizlerde farklı işlemciler ile test edip durumu paylaşırsanız sevinirim. Özellikle Kesme ve kesme içi alt programlarında Delay Fonk. çok dikkat edelim.
Evet CcsC nin delay fonksiyonu çok tehlikeli gözüküyor:
delay esnasında kesme gelirse ve
FSRh FSRL BSR INDF 0x70~0x7F arası registerlar
kesme girişinde yedeklenip, çıkışında geri yüklenmezse
kesme içindede bu registerlar değişirse programın çakılması içten işten bile değil.
Ama bu MCU da "automatic context saving" var,
yani bahsi geçen registerları kesme durumunda kendi yedeklerinden geri yüklüyor,
bir sıkıntı göremedim,
garip.
.................... #use delay(internal=16MHz) // Delay_ms() fonksiyonu ile derleyici tarafından tasarlanan Alt Program
058F: MOVLW 20
0590: MOVWF 05 ;FSR0H a 0x20 yükle
0591: MOVLW 68
0592: MOVWF 04 ;FSR0L a 0x68 yükle, yani FSR0 0x2068 memory adresini gösteriyor
0593: MOVF 00,W ;INDF0 dan W ye al, yani biraz önce FSR ile gösterilen 0x2068 memory adresini W ye al, "MOVF dikkat"
0594: BTFSC 03.2 ;MOVF ile aktarılan sayı 0 ise STATUS,Z(03.2) biti 1 olur
0595: GOTO 5A4 ;0x2068 memory adresindeki değer 0 ise 0x05A4 memory adresine atla """Bir çıkış burası"""
"""""""Aslında burada bir TRİK var erişilen yer aslında BANK1 deki 0x38 RAM adresindeki değer,
16F15xx in 'Linear Data Memory Map' özelliği kullanılmış. """""""""""
0596: MOVLW 05 ;
0597: MOVWF 78 ;0x78 RAM adresine(değişken yani) 05 yükle
0598: CLRF 77 ;0x77 RAM adresini(demek 16 bit değişken) temizle sıfırla ''bekleme rutini iç döngü değer yükleme yeri''256 yüklenmiş gibi olur
0599: DECFSZ 77,F ;0x77 RAM adresindeki değişkeni 1 azalt 0 ise alt satırdaki komutu atla
059A: GOTO 599 ;üst adıma git
059B: DECFSZ 78,F ;0x78 RAM adresindeki değişkeni 1 azalt 0 ise alt satırdaki komutu atla
059C: GOTO 598 ;bekleme iç döngü değerini tekrar yüklemeye git
059D: MOVLW 2E ;bekleme döngüsü tamamlanınca bu satıra varılır
059E: MOVWF 77 ; 0x77 RAM adresine 0x2E yükledi
059F: DECFSZ 77,F ;0x77 RAM adresindeki değişkeni 1 azalt 0 ise alt satırdaki komutu atla
05A0: GOTO 59F ;bir üst satıra git
05A1: GOTO 5A2 ;0x05A2 program memory adresine git (Saçma demi, ne yaparsın makina işte, belkide 2 komut çevrimi geçsin diye uğraşıyordur)
05A2: DECFSZ 00,F ;INDF0 ın (FSR0 ın gösterdiği yerdeki değer) i 1 azalt, 0 oluyorsa alt satırdaki komutu atla
05A3: GOTO 596 ;yok, yeterince milisaniye bu döngü tekrarlanmamış, tekrarlamaya devama git
----burada 05A4: delay rutininden dönüşü sağlayacak birşey olması lazım, RETURN veya PAGE ayarlayıp dönen bir yere GOTO olabilir.
.................... delay_ms( 20 );// İle Delay_ms() alt program çağırılıyor.
058C: MOVLW 14
058D: MOVLB 01 ;BSR Bank Slect register a 1 yükle, BANK 1 seçildi, hangi RAM bankı kullanılacak seçiliyor
058E: MOVWF 38 ;BANK1 0x38 RAM Adresine 0x14=20desimal yükle
0x70~0x7F arası Common RAM yani bank ayırt etmeksizin erişilebilir.
Bugün farklı bir programın bulunduğu Master cihazı daha test ettim. Aynı işlemci ve 6k üzeri kod var.
Aynı test işleminde delay fonksiyonu varken cihaz saçmalarken, aynı kodların ama bu fonksiyondan arındırılmış gecikmeli programlı olan hiç hata vermedi.
@RaMu güzel çalışma yapmışsın müsayit zamanda inceleyeceğim. İlk dikkatimi çeken bu fonksiyon çağrılırken seninde dikkat ettiğin üzere call ve return komutu göremedim.
Bunlarsız alt program çağırmak çok tehlikeli.
Kaydedilen değişkenlerin geri yüklenmesi retlew, return gibi komutları bekler.
Sonradan fark ettim,
altprogram değil direk inline kullanmış
delay fonksiyonunu,
return olmaması doğal.
ccs Delay fonksiyonunu FSR registerleri kullaranarak indirect adresleme ile çağırıyor.
1– Indirect adreslemeyi hangi kafa ile yaptığını incelemek gerekli. Lineer mi yoksa geleneksel mi bilmiyorum. FSRH ı incelemek lazım.
Lineer değil ise 80 byte üzeri blok atama veya erişimlerde problem yaşatır.
2– Bir diğer husus ise Kesme içinde bu tarz çağırımlardan geriye dönüşlerde otomatik kaydedilen çekirdek registerlar eğer yine 1.maddede gibi lineer indirect adresleme kullanılmamış ise restore edilmeme durumu yaşanabilir.
1-İndirect adreslemeyi Lineer yapmış
2-Otomatik Restore edilenleri yukarıda yazdım,
0x70~0x7F arası önemli RAM alanı otomatik restore edilmiyor,
ekstra kod eklemiş mi koddan incelemek lazım,
ama sanmıyorum.
Problem 0x70~0x7F arası registerlar dan kaynaklanıyor muhtemelen,
0x77 ve 0x78 delay rutininde kullanılmış,
bunlar güzel registerlar, muhtemelen kesme içindede kullanılmışlardır.
İmkanın olursa, CcsC delay fonksiyonunu kullanan versiyonda,
kesme girişinde 0x70~0x7F arası registerları yedekleyip
kesme çıkışında geri yükleyerek deneyebilirsen netleştirebiliriz.