10 bit veri ile desimal bulma işlemi....

Başlatan SpeedyX, 28 Ağustos 2004, 23:59:33

SpeedyX

ben adc ile veri okuyorum (16f818) ve bunu adresl ve adresh adlı registerlara yazıyor.
normalde 8bitlik verilerle işlem yaparken kullandığım desimal bul ma prosedürüm vardı.. (display,lcd için.)
bunu 10 bitlik sistemde değiştirmeliyim...
ama nasıl yapacağımı düşünemedim. bir türlü...

eski desimal bul u yolluyorum.. yardımcı olursanız sevinirim. (asm)

desimalbul
		movwf	sayac1
		bsf	status,0
		clrf	yuzler
		clrf	onlar
		clrf	birler
		goto	yuzlerbul
yuzlerbul
		movlw	d'100'
		subwf	sayac1,1
		btfsc	status,0
		incf	yuzler,1
		btfsc	status,0
		goto	yuzlerbul
		addwf	sayac1,1
		bsf	status,0
		goto	onlarbul
onlarbul
		movlw	d'10'
		subwf	sayac1,1
		btfsc	status,0
		incf	onlar,1
		btfsc	status,0
		goto	onlarbul
		addwf	sayac1,1
		bsf	status,0
		goto	birlerbul
birlerbul
		movlw	d'1'
		subwf	sayac1,1
		btfsc	status,0
		incf	birler,1
		btfsc	status,0
		goto	birlerbul
		addwf	sayac1,1
		bcf	status,0
		bsf	yuzler,4
		bsf	yuzler,5
		bsf	onlar,4
		bsf	onlar,5
		bsf	birler,4
		bsf	birler,5
		return


lütfen bana yardımcı olunuz... teşekkürler
(değişiklik : code tagları arasına aldım kodları)

DumrulBey

Merhaba,

Öncelikle aramıza yeni katılan arkadaşımıza ufak bir mesaj:
Hoş geldin "SpeedyX"  ;)

Benzer bir konu aşağıdaki örnekle irdelenmişti. Süleyamn ismindeki yeni bir üyemiz 32 bitlik bir sayı basamaklarına bölmek istiyordu. Sen de 10 bitlik bir sayı için bunu yapmak istiyorsun.

for (i=0;i<10;i++) { 
  c[i]=b%10;  //(b MOD 10), c[i] = kalan
  b=b-c[i];   //(b - kalan),
  b=b/10;     //(b DIV 10)
}

Şimdi öncelikle bir karar verelim. Bunu Assembly kullanarak mı, yoksa C kullanarak mı yapacaksın? Aslında her iki yöntemde de sayıyı kalanlı bölerek (MOD ile bölme) rakamları sayıdan ayırman olacak. Eğer bu mantığı uygularsan kaç bit olduğu senin için farketmez. Sadece 8 bitlik mimaride işlem yaptığımız için daha çok değişken kullanacağız, hepsi bu kadar.

Başarılar...
Bilgi paylaştıkça bir bakmışız; kar topu olmuş ve çığ gibi üzerimize geliyor...:)

SpeedyX

arkadaşım. öncelikle bana yardımcı olduğun için sana çok teşekkür ederim.

ben bu işlemi assembly ile yapmak istiyorum.
aslında c ile yapmak isterdim fakat programın tamamı assembly ile...

bu bir volt/amper metre...
önceden ben bunula max 25 v okuyordum.
fakat şimdi 40v a çıktı ve bundan dolayı iki adc registerınıda kullanmalıyım..
bunu nasıl yapacağım.? bir türlü aklında düşünemedim.
8bitlik kolaydı ama...

10bitlik için yardımcı olursan sevinirim (asm ile)

ben artık c öğreniyorum, geliştirdim sayılır...
yakında tamamen c ye geçeceğim.
bu asm ile son projelerimden biri diyebilirim.
-------------
tekrar teşekkürler.

psikokabus

Alıntı yapılan: "SpeedyX"arkadaşım. öncelikle bana yardımcı olduğun için sana çok teşekkür ederim.

ben bu işlemi assembly ile yapmak istiyorum.
aslında c ile yapmak isterdim fakat programın tamamı assembly ile...

bu bir volt/amper metre...
önceden ben bunula max 25 v okuyordum.
fakat şimdi 40v a çıktı ve bundan dolayı iki adc registerınıda kullanmalıyım..
bunu nasıl yapacağım.? bir türlü aklında düşünemedim.
8bitlik kolaydı ama...

10bitlik için yardımcı olursan sevinirim (asm ile)

ben artık c öğreniyorum, geliştirdim sayılır...
yakında tamamen c ye geçeceğim.
bu asm ile son projelerimden biri diyebilirim.
-------------
tekrar teşekkürler.

10 bite gectiginde sayinin decimal karsılıgında binler basamagıda oluyor
aynı rutinleri yazarak binler basamagını da ekle...  (10 bit 1023 e kadar cevrim yapar) bilmem hala bu konuyla ilgileniyor musun :?:

SpeedyX

Alıntı yapılan: "psikokabus"10 bite gectiginde sayinin decimal karsılıgında binler basamagıda oluyor
aynı rutinleri yazarak binler basamagını da ekle...  (10 bit 1023 e kadar cevrim yapar) bilmem hala bu konuyla ilgileniyor musun
anlatımın hiç yeterli değil bence,çünkü binler basamağı dediğin şey de var tabi de adresh ve adresl gibi 2reg den okuyorsun. senin anlatımından kimse birşey anlar mı bilemem,ben anlamadım.

Erol YILMAZ

Zannedersem ben biraz anladim :)
1023 rakaminin. 102.3 Volta denk geldigini varsayalim.
Biz de 1 adet 3 lu 7 segment display kullanalim. Boylece 99.9 Volta kadar gosterim yapaabiliriz. Bir de ampermetre si olursa 9.99 Amper e kadar guzel bir calisma olur değil mi?
Simdi Speedyx sen diyorsun ki  372 rakamindan  3 7 ve diger 2yi nasil ayiracagiz?


     gerilim=gerilim_adc;

    //----------------------------------------------DISPLAYLERE BOLME
    gerilim_display[2]=0;
    while(gerilim>=100)  {  gerilim_display[2]++; gerilim -= 100;   }
    gerilim_display[1]=0;
    while(gerilim>=10)   {  gerilim_display[1]++; gerilim -= 10;    }
    gerilim_display[0]=0;
    while(gerilim>=1)    {  gerilim_display[0]++; gerilim -= 1;  }


Bu kod bu isi yapiyor. gerilim_display[2]   en yuksek degerli displayin sayisi, gerilim_display[1] ortadakinin , gerilim_display[0] ise en dusuk degerli displayin sayisi. yani ondalikli gosterimde.

Ampermetre kismini nasil yaptin? Kac ampere kadar olcuyor? Istedigin gibi oldu mu? 0 akimda senin alette 0 gosteriyor mu? Stabilite iyi mi? Kipirdama yapiyor mu?

Kolay Gelsin...

elektromer

Alıntı yapılan: "SpeedyX"......

eski desimal bul u yolluyorum.. yardımcı olursanız sevinirim. (asm)

...... teşekkürler

Merhaba SpeedyX,
Aynı soruyu PicProje Forum Ana Sayfası -> --PIC Assembly-- -> 10 bit veri ile desimal bulma işlemi.... başlığı altında sormuştun ve ASM kodları adı geçen sayfada yanıtlamıştım.

Sayfanın linki :
https://www.picproje.org/index.php/topic,23030#23030

Saygılarımla...
Her şey gönlünüzce olsun..

SpeedyX

Alıntı yapılan: "Erol"Ampermetre kismini nasil yaptin? Kac ampere kadar olcuyor? Istedigin gibi oldu mu? 0 akimda senin alette 0 gosteriyor mu? Stabilite iyi mi? Kipirdama yapiyor mu?
ampermetre kısmı : güç kaynağının (-) çıkışına seri bir 0.5ohm 5W direnç bağladım, bu dirence paralel bir çok turlu pot, potun orta ucunuda adc'ye verdim. birde o pinden şaseye bağlı bir adet 100nF var.
4A e kadar ölçüyor
(Voltmetre ise 55V a kadar)
evet akım 0 iken benim alette 0 gösteriyor.
stabilite de iyi bence.
kıpırdanma yapıyor malesef, 100nF ı o yüzden koydum zaten ama sadece azaltabildim kıpırdanmayı.

ayrıca cihaza birde ntc koydum ve sabit bir sıcaklık değerinde ntcden okunan değeri aldım ve program ile onu karşılaştırdım, eğer o değerden büyük ise daha fazla ısınmasına izin vermemesi için. bir derece ölçümü yok,zaten tablo yapmam gerek, o şekilde işimi gördü benim.

arkadaşlar aslında ben bu soruyu asm için sormuştum ama ozamanki acemiliğimden olsa gerek pic c ye yazmışım :)

@elektromer verdiğin kod işime yaramadı.ben daha farklı bir şekilde yaptım. ama aynı programı c de de yazmak isterim şimdi.
@Erol, hocam c de verdiğin koda gerek kalmıyor ben lcd ye yazdığım için printf ile işimi görüyor fakat mantık olarak anlaşılabilir ama oradaki değişkenin 16bitlik ve ben 2tane 8bitlik değişken ile uğraştığım için anlamadım olayı.
benim bilmediğim konu adresh ve adresl den tek bir sayı üretmek idi. aslında tam olarak da kavrayabilmiş değilim.hep araya başka şeyler girdi ve ilgilenemedim bir türlü.

Saygılar.

Erol YILMAZ

Alıntı yapılan: "SpeedyX"
ampermetre kısmı : güç kaynağının (-) çıkışına seri bir 0.5ohm 5W direnç bağladım, bu dirence paralel bir çok turlu pot, potun orta ucunuda adc'ye verdim. birde o pinden şaseye bağlı bir adet 100nF var.
4A e kadar ölçüyor
(Voltmetre ise 55V a kadar)
evet akım 0 iken benim alette 0 gösteriyor.
stabilite de iyi bence.
kıpırdanma yapıyor malesef, 100nF ı o yüzden koydum zaten ama sadece azaltabildim kıpırdanmayı.

100 nF yetmez uF cinsinden birseyler koyman lazim. Ve 1 LSB degisimi displaya direkt yansiyorsa kipirdanma illa ki olur bence. Gerilimde ayni sekilde.

Ayrica I^2 x R  hesabina gore ve dedigin max akim 4 amper oldugunda 8 Watt lik bir enerji kaybi oluyor 0.5 ohm luk direnc uzerinde. Ayrica bu direnc bu akimlarda calisiyorsa baya bir isiniyordur ve direnc degeride degisiyordur. Onun yerine 10-20 mOhm luk bir sont kullansan cok daha iyi olur. Tabii gerilimi iyi bir opamp ile katlaman gerekir.



cikistaki 22 uF kondansator saniyedeki 5 kerelik guncelleme icin yeterli sonuc veriyor. Yani daha azini kullanmanin bir k^ari yok.

SpeedyX

Selamlar. projeyle ilgili birkaç resim yolladım.


@Erol 0.5'lik direnç'i 3A çekebilecek şekilde ayarladım,çünkü devrenin güçkaynağı max 3A veriyor. 4A'i gösterecek şekilde de tasarladım.

inşallah vakit bulduğum zaman c ile yazacağım yeni programını ve rs-232 de ekleyeceğim.ilginç özellikler eklemeyi düşünüyorum.aklımda çok iyi fikirler var.

Saygılar.

psikokabus

asm de 16 bitlik sayıları kullanman mümkün değil sayac diye tanimladıgın bir registerin adresidir ve tüm registerler 8 bittir . saniyorum adresl u sayac1 e atıyorsun sonrada decimale cevirmek için bu programı kullanıyorsun . adresh ya da sayac2 de sayac2 nin üst 6 bitini maskele(and le 0x03 ile) sonra adresh ve adresl u sırasıyla 0x03 ve 0xE7 oldumu diye kontrol et bu sayı hex 1000 e karsılık gelir. zaten tek bulabilecegin binler basamagı 1 dir.(cevrim sonucu max decimal 1023)

anlatıma gelince erol bey dogru anlamıs 8 bit max 255 cevrim sonucu gonderir.(0xFF)

ayrıca kodunda adresh ve adresl u nasil okudugunu ve sonra ne yaptıgını göremiyorum...

simdi oldu mu :?:

SpeedyX

Alıntı yapılan: "SpeedyX"oradaki değişkenin 16bitlik ve ben 2tane 8bitlik değişken ile uğraştığım için anlamadım olayı. benim bilmediğim konu adresh ve adresl den tek bir sayı üretmek idi.
Alıntı yapılan: "psikokabus"asm de 16 bitlik sayıları kullanman mümkün değil sayac diye tanimladıgın bir registerin adresidir ve tüm registerler 8 bittir

Selamlar. size benim kendi çevrim kodumu gönderiyorum.
decbul
   clrf     birler
   clrf     onlar
   clrf     yuzler
   movfw    voltajl
   movwf    tdeger
   bsf      STATUS,c
yuzlerb
   movlw    d'100'
   subwf    tdeger,f
   btfsc    STATUS,c
   incf     yuzler,f
   btfsc    STATUS,c
   goto     yuzlerb
   clrw
   subwf    voltajh,w
   btfsc    STATUS,z
   goto     gecis
   movlw    d'100'
   subwf    tdeger,f
   incf     yuzler,f
   decfsz   voltajh,f
   goto     $-4
gecis
   movlw    d'100'
   addwf    tdeger,f
   bsf      STATUS,c
onlarb
   movlw    d'10'
   subwf    tdeger,f
   btfsc    STATUS,c
   incf     onlar,f
   btfsc    STATUS,c
   goto     onlarb
   addwf    tdeger,f
   bsf      STATUS,c
birlerb
   movlw    d'1'
   subwf    tdeger,f
   btfsc    STATUS,c
   incf     birler,f
   btfsc    STATUS,c
   goto     birlerb
   addwf    tdeger,f
   bcf      STATUS,c
   bsf      yuzler,4
   bsf      yuzler,5
   bsf      onlar,4
   bsf      onlar,5
   bsf      birler,4
   bsf      birler,5
   return


bu da adc kısmı:
adcoku
      bsf   adcon0,6          ;ölçme araliğini ayarla (fosc/8)
      bsf   adcon0,0          ;a/d çalistir
      call  bekle10           ;bekle
      bsf   adcon0,2          ;a/d bitti bitini 1 yap
      btfsc adcon0,2          ;a/d bittimi bak
      goto  $-1               ;bitmediyse bekle
      movfw adresh            ;bittiyse adresh yi yazmaca al
      movwf voltajh
      movfw adresl            ;adresl yi yazmaca al
      movwf voltajl
      return                  ;ve geri dön


işlemlerin tamamı bu ve voltajı düzgün bir şekilde gösteriyor. ozaman bunu kendim yazdım ama aradan vakit geçince mantık gitti.
doğruluğu konusunda tartışalım lütfen.