12f675 bsf bcf komutlarında sorun?

Başlatan camby, 15 Eylül 2009, 14:58:53

camby

12serisinde farklı bir sorunla karşılaştım

bsf    GPIO,0
bsf    GPIO,1
bsf    GPIO,2


bu durumda çıkışların alması gereken durumlar:
001
011
111
olmalıydı, yani portları teker teker açmak istiyorum.

Fakat ilk bsf komutundan sonra 2. bsf komutuna geçince 2.çıkışı açıyor fakat ilk satırda açtığı 1. çıkışı kapatıyor , yani şu şekilde oluyor:
001
010
100

ben bu sorunu kodları bu şekilde değiştirerek düzelttim
movlw    b'00000001'
mowf      GPIO
movlw    b'00000011'
movwf    GPIO
movlw    b'00000111'
movlw    GPIO


12 serisinde bsf bcf kullanımı diğer piclere göre farklılık mı gösteriyor gerçekten yoksa ben mi biyerde hata yapıyorum. Eğer ben hata yapmıyor isem Bu şekilde sinir bozucu ayrıntılar daha çok var mı 12 serisinde acaba?

XX_CİHAN_XX

Gerçekten ilginç.
Picte bir sorun mu var acaba  :?
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

camby

picte denemedim isisteki durum bu..

XX_CİHAN_XX

Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

Tagli

Bu durum çok normal. Sorun PIC'te register'larla işlem yapan komutların oku - değiştir - yaz şeklinde çalışıyor olması. BSF komutu önce PORT (veya GPIO, her neyse...) daki değeri okur, ilgili biti 1 yapar ve tekrar tamamını yerine yazar. Sorun şu ki ikinci BSF de önce PORT'u okur ama bu okuma gerçekte register'ı değil, porttaki fiziksel değeri okur. Bu kısa süre içinde de ilk BSF fiziksel etkisini göstermemiştir henüz. Haliyle ilk BSF'nin 1 yapması gereken bacak 0 olarak okunur, BSF gerekli biti 1 yapar ve hepsini olduğu gibi yeniden PORT'a yazar. Bunun doğrudan bir çözümü yok. Ama komutların arasına 1 - 2 us bekleme koyarsan sorun çözülür sanırım.

18 serisi PIC'lerde PORT register'larının yanısıra LAT register'ları da bulunur. Yazma işleminin LAT register'larına yapılması, okumaların da PORT register'larından yapılması bu sorunu kesin olarak çözer. Aslında LAT (latch) denilen şey 16 (ve diğer ilkel modellerde) serisinde de var ama doğrudan erişilemiyor. PORT'a yazılan şey aslında LAT'a giderken (ilk fırsatta fiziksel olarak bacakta gösterilebilmesi için), PORT'tan okunan değer bacaktaki fiziksel durumu oluyor. 18 serisinde LAT üzerinde uygulanacak okumalar bacağın fiziksel durumunu değil gerçek anlamda LAT'ı okuduğu için BSF'nin çalışmasını engellemiyor.
Gökçe Tağlıoğlu

XX_CİHAN_XX

Tagli tespitlerin doğru olmakla birlikte bu normal bir durum değil!
Alıntı Yap
Sorun şu ki ikinci BSF de önce PORT'u okur ama bu okuma gerçekte register'ı değil, porttaki fiziksel değeri okur. Bu kısa süre içinde de ilk BSF fiziksel etkisini göstermemiştir henüz. Haliyle ilk BSF'nin 1 yapması gereken bacak 0 olarak okunur, BSF gerekli biti 1 yapar ve hepsini olduğu gibi yeniden PORT'a yazar. Bunun doğrudan bir çözümü yok. Ama komutların arasına 1 - 2 us bekleme koyarsan sorun çözülür sanırım.
Böyle bir beklemeye isisi bilmem ama gerçekte gerek yok hatta burada ki amaca aykırı bir durum teşkil ediyor. Ayrıca bu olaylar zaten komutun işleniş süresinden çok daha kısa bir sürede oluyor. Bahsettiğiniz türden bir yanılgının olması normal şartlarda mümkün değil. 7 senedir pic kullanıyorum ilk defa böyle bir sorun duyuyorum. Bence bu tamamen isisin hatasıdır. Bu nedenle arkadaş programı gerçekte deneyince olayın daha net anlaşılması için karşılaştığı durumu buraya yazarsa sevinirim.

Ayrıca denediği isis dosyası ve programı burada paylaşırsa bende deneyip görmek isterim gerçekten merak ettim. Çok anormal bir durum :)
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

Tagli

camby, bunu fiziksel ortamda da deneyip sonucu yazarsan sevinirim. Benim tahminime göre 4 MHz ve daha düşük hızlarda sorun çıkmayacaktır ama sen 20 MHz ile bir dene.
Gökçe Tağlıoğlu

Tagli

XX_CİHAN_XX, bu sorun belki her zaman kendini göstermese de bilinen bir sorun. Microchip'in resmi dökümanlarında da bu durumdan bahsedilmiş. İlgili belgeye buradan erişebilirsin. Konu 2. sayfada "READ-MODIFY-WRITE INSTRUCTIONS ON PORT REGISTERS" başlığı altında açıklanmış.

Ayrıca, internette bulduğum bu kaynakta da konu güzel bir şekilde anlatılmış.
Gökçe Tağlıoğlu

XX_CİHAN_XX

Tagli bu güzel dökümanlar için teşekkür ederim. Olay şimdi anlaşıldı :)
Burada bahsedilen hata durumu pinlere kapasite bağlandığında oluşan bir durum.
Bir pinle şase arasına kapasite bağlandığında ilk anda kondansatör boşken kısa devre konumundadır (şarj olana kadar)
Bu süre zarfında picten o pine lojik "1" yollansa bile hemen şarj olamadığı için şarj olana kadar o pin lojik "0" da kalmaya devam eder.
Tabi bizde 1. pini set ettikten hemen sonra 2.pini set ettiğimizde 1. pin konumu kondansatörden dolayı henüz lojik "1" e çıkamadığı için 2. bitin set edilmesinden önce otomatik olarak yapılan port okuma işlemi bizi böyle bir hata ile karşı karşıya bırakıyor.

Bu durumda seninde dediğin gibi birkaç mikrosaniyelik gecikmeler koymak gerekir ama ben normal şartlara göre yorum yapmıştım. Pinlerde kapasitif etki yapan birşey olduğunda işler değişiyor elbette :)
Arkadaşımız şemasını ve programını gönderirse olay dahada netleşir. Benim dökümanlardan gördüğüm kadarıyla olay bundan ibaret.
Yani aslında bu durum PIC in hatası değil bu çok doğal birşey. Portlara kapasite koymadığınız zaman daha öncede dediğim gibi böyle bir sorunla karşılaşmazsınız.
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

hasangurlek

Dış kapasite kullanılmasa bile dahili/harici pull-up/down dirençleride bu probleme sebep olur. Proteus gibi simulasyon programlarında dirençler dijital olarak tanımlanabilse bile bunlar analog elemanlardır.

BSF komutu 2. saykılda registeri okur, okuduğu registerdeki ilgili biti 3.saykılda 1 yapar ve 4.saykılda yeniden yazar. Siz ikinci BSF komutunu verdiğinizde birinci BSF komutunun 4.saykılından sonra ikinci BSF komutunun registeri okuyacağı 2.saykıla kadar işlemcinin osilatöründe 1 periyod daha dolmamıştır. Bu süre ancak ikinci BSF komutunun 4.saykılında dolacağı halde siz 2.saykılda portu okumuş olursunuz. Bu nedenle yüksek hızlarda çalışabilen MCU larda LAT registerleri bulunur.

Dış kapasite kullanılır ise 25 ma max pin akımı, kapasite büyüklüğü ve pinin yapısına göre lojik seviyenin 1 kabul edileceği voltaj seviyesine kadar kondansotörün şarj olma süresini hesaplamanız ve ikinci BSF komutundan önce ilave olarak bu süreyide beklemeniz gerekir.
http://www.cyber-warrior.org, Although they like whiteness, sometimes twilight is required...  Hala evlilermi bilinmez ama kesinlikle artık uygun değiller !!!

XX_CİHAN_XX

Alıntı yapılan: "hasangurlek"Dış kapasite kullanılmasa bile dahili/harici pull-up/down dirençleride bu probleme sebep olur. Proteus gibi simulasyon programlarında dirençler dijital olarak tanımlanabilse bile bunlar analog elemanlardır.
Bence bunlar böyle bir hataya sebep olmaz. Zira şimdiye kadar olduğunuda görmedim. Pdf teki açıklamalarda hep kapasite üzerine yapılmış zaten. Kapisitf bir yük üzerinde böyle bir etki olmasıda gayet doğal.

Alıntı yapılan: "hasangurlek"
BSF komutu 2. saykılda registeri okur, okuduğu registerdeki ilgili biti 3.saykılda 1 yapar ve 4.saykılda yeniden yazar. Siz ikinci BSF komutunu verdiğinizde birinci BSF komutunun 4.saykılından sonra ikinci BSF komutunun registeri okuyacağı 2.saykıla kadar işlemcinin osilatöründe 1 periyod daha dolmamıştır. Bu süre ancak ikinci BSF komutunun 4.saykılında dolacağı halde siz 2.saykılda portu okumuş olursunuz.
Burasını oldukça karışık yazmışsınız ama yanlış anlamadıysam kısaca arka arkaya çalışan iki BSF komutundan birinci BSF henüz porta set bilgisini yazamadan ikinci BSF komutunun portu okuduğunu mu söylüyorsunuz?
Eğer öyleyse burada bir yanlış olmalı. Sebebide şu;
Picte her komut sıra ile çalışır birinci komut işletilirken ikincisine başlanmaz. Bunun en basit ispatinı komutların işlendiği sürelere bakarak gösterebiliriz. 4MHz için BSF komutu sizinde bahsettiğiniz gibi 4 saykılda işlenir ve toplamda 1uS de tamamlanır. Yani alt alta 2 BSF 2uS demektir. Buda BSF lerin biri bitip ondan sonra diğerinin çalıştırıldığını gösterir. Bu durumda portumuzda kondansatör yoksa hiçbir sorun çıkmadan peş peşe eklenen BSF ler çalışacaktır. Bunun güncel örneğini vermek gerekirse;
Ben 20MHz de 74hc595 i sorunsuz bir şekilde aynen şu şekilde kullanabiliyorum.
BSF   DATAPIN
BSF   CLOCKPIN
BCF   CLOCKPIN

Ve bunlar aynı port üzerinde...
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

hasangurlek

Alıntı yapılan: "XX_CİHAN_XX"4MHz için BSF komutu sizinde bahsettiğiniz gibi 4 saykılda işlenir ve toplamda 1uS de tamamlanır.

İşte problemde budur zaten. Birinci BSF komutunun 4.saykılından (yazma) ikinci BSF komutunun 2.saykılına (okuma) kadar 1 periyod tamamlanmamıştır. İkinci BSF komutu bu bir birimlik periyod tamamlanmadan 500 ns (4mhz de çalışan bir işlemci için 1 us'un yarısı) sonra okuma yapmış olur.

Alıntı yapılan: "XX_CİHAN_XX"Bence bunlar böyle bir hataya sebep olmaz. Zira şimdiye kadar olduğunuda görmedim. Pdf teki açıklamalarda hep kapasite üzerine yapılmış zaten.

Kapasite olarak sadece devre üzerindeki kondansatörleri düşünmemelisiniz. PCB hatlarınında yapısına ve konumuna göre değişen büyüklüklerde direnç ve/veya kapasite etkisi mevcuttur. (Bu arada aslında PCB diyip geçiyoruz ama dikkatle tasarlanması gereken en önemli unsurlardan biridir.) 48 mhz de çalışan bir MCU nun 1 saykılı 83.3 ns'dur. Küçük değerdeki bir up direnç hattın 0dan 1e çekilmesi durumunda faydalı olduğu halde hattın 1den 0 a çekilmesi durumunda kayba sebep olur. Direncin değerini büyükçe seçerseniz bu seferde tam tersi bir kayıp söz konusudur. Up/down dirençlerinin MCU pinine olan mesafesi, pcb üzerindeki hattın konumu ile uzunluğu ve genişliğide ayrı bir etki sebebidir. Pull up/down direnç değerlerinin yüksek hızlarda nelere sebep olabileceğini gerçek donanım üzerinde denemenizi tavsiye ederim.
http://www.cyber-warrior.org, Although they like whiteness, sometimes twilight is required...  Hala evlilermi bilinmez ama kesinlikle artık uygun değiller !!!

XX_CİHAN_XX

PCB hatlarınında kapasitif etkiye sebeb olacığı fikrinize katılıyorum.
Haklısınız sadece kondasatör bağlanması durumu burada söz konusu olmayabilir. Özellikle yüksek hızlı piclerde sıkıntı çıkarabilir. Ancak 20MHz lik picler bana göre okadarda yüksek hızlı sayılmazlar. Belkide bu nedenden dolayı hiç karşılaşmadım. Ama daha yukarı frekansta çalışan piclerde bahsettiğiniz durumların oluşması mümkündür. Zaten microchip  bunun önlemini yüksek hızlı picler için LATx, PORTx olayını çıkararak almış. 12 ve 16 serisi piclerde ise; kötü pcb koşullarını bilmiyorum ama kondansatör bağlamanın kesinlikle sorun çıkaracağı ortada. Belki dediğiniz gibi pcb çizimininde buna etkisi büyüktür ancak şuna katılmıyorum;
Normal bir pcb de sadece (dahili veya harici farketmez) PULL UP ve PULL DOWN gibi dirençler tek başına böyle bir etkiye sebep olmazlar buna eminim. Bizzat denedim çünkü.
Ve 1. komut işlemi bittikten (4 saykıllık periyodu tamamlandıktan) sonra  2. komutun işlemine başlanıyorsa, 1. komutun yazma işlemi bitmeden 2. komutun okuma işlemine nasıl geçildiğini hala anlayabilmiş değilim. Zaten bu şekilde dediğiniz gibi bir durum olsaydı arada bir değil her zaman, her pcbde, kapasite olsada olmasada bu sorunla karşılaşılması gerekirdi. Diye düşünüyorum.
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

camby

Aynı komutları 16f84 ile denediğimde sorun olmuyor. Çıkışlarda kondansatör değil sadece LED var. Her asm derdine yetişen tagliya ve diğer katılan arkadaşlara teşekkür ederim. İnternetim kesik olduğundan devreyi ve yazılımı paylaşamıyorum , datasheet indirmek için internet kafeye çıktım sadece:) Bu problem sayesinde kapasitif etkinin hız üzerindeki etkisini de görmüş oldum(k).

Aklıma takılan başka bir konu da bacakların direk kondansatör bağlandığı durumda (ve bu kondansatörün değeri çok küçük değilse) bahsettiğiniz gibi bacağa komutun gittiği t=0 anında kısa devre olduğundan akım 25ma'den (anlık da olsa) çok çok yüksek değerlerde olmaz mı? Bu pic'e zarar vermez mi?
Ben bunun için kondansatörlü çıkışlara , kondansatör bacak arası akım sınırlayıcı direnç koymayı düşündüm , fakat bu durumda şarj için gereken zaman sabiti çok uzadığından pic çıkışına udn28xx gibi bir sürücü (500ma her bacak) koymayı düşünüyorum , böylelikle 10ohm gibi bir dirençle hızlı bir şekilde kondansatörü şarj etmiş ,bsf bcf sorunlarından kurtulmuş, pic'e de zarar vermemiş olurum, ne düşünüyorsunuz?

Erol YILMAZ

Alıntı yapılan: "camby"
Aklıma takılan başka bir konu da bacakların direk kondansatör bağlandığı durumda (ve bu kondansatörün değeri çok küçük değilse) bahsettiğiniz gibi bacağa komutun gittiği t=0 anında kısa devre olduğundan akım 25ma'den (anlık da olsa) çok çok yüksek değerlerde olmaz mı? Bu pic'e zarar vermez mi?
Ben bunun için kondansatörlü çıkışlara , kondansatör bacak arası akım sınırlayıcı direnç koymayı düşündüm

Güzel bir noktaya değindiniz.
Evet bu konuda sınırlamalar var.
Bir şematik bulursam buraya koyacağım.