Şimdi Ara

PIC yardım lüften!!

Daha Fazla
Bu Konudaki Kullanıcılar: Daha Az
2 Misafir - 2 Masaüstü
5 sn
40
Cevap
2
Favori
3.648
Tıklama
Daha Fazla
İstatistik
  • Konu İstatistikleri Yükleniyor
0 oy
Öne Çıkar
Sayfa: 12
Sayfaya Git
Git
sonraki
Giriş
Mesaj
  • arkadaşlar pic işine yeni girdim şu anlık sadece karaşimşek ledlerle animasyon gibi ufak çaplı devreler yapabiliyorum ama aklımda bazı soru işaretleri var şimdi ;
    1-) pic ile lojik kapı işlemleri(and-xor vb.) işlemleri sonucu w registerinde mi yoksa başka bi yerde mi tutuluyor?
    2-) pic ile yapılan çıkarma toplama işşlemlerinin sonucu nerede tutuluyor ayrıca - sayı olunca hangi bit 1 oluyor?
    3-) benim elimde şu an 16f877a 16f84a 16f628a var ama ben sadece 16f84a yı programlayabiliyorum 16f877 ye analog girişi nasıl yaparım ve nasıl dijitale çeviririm komutları nasıl ayarlarım (option_rreg)
    4-) 16f84 veya 628 in timerlerini nasıl kullanırım yani şöyle dışardan bir butonla sürekli pals versem ona nasıl saydırırım daha açacak olursak şöyle yani dışardan (ra4 olduğunu biliyorum) buton ile 10 kere basınca şu olsun gibi yada her basışımda portbye nasıl aktarırım 1 kere bastım portbde 1 8 kere bastım portbde 8 polsun gibi nasıl yapabilirim?
    5-) ben sadece şu anlık assembler dili biliyorum yani asm dosyası oluşturup derleyip hex oluşturuyorum ama pic basic diliyle yazmış olsaydım nasıl derlemem gerekirdi?
    tabi bunları sordum ama hiç bilgim yok değil ben sadece 80c535 işlemcisini programlamayı biliyorum tabi o pahalı ve bulunması zor bir işlemci olduğu için ayrıca bulsak bile epromunu ramini hep kendimiz harici olarak bağlamamız gerektirdiğinden çok zor olur benmim için ben pic ile ilgilenmeye başladım ve yapabileceğime inanıyorum ama bu sorunları bir türlü çözemedim tabi temelim var sıfırdan başlamak gibi değilim neyse bu sorulara bir öneri getirirseniz çok sevinirim bi yardım eli uzatında başarayım şu işi arkadaşlar herkese şimdiden teşekkür ediyorum...



    < Bu mesaj bu kişi tarafından değiştirildi 41ugur41 -- 1 Mart 2010; 20:10:05 >







  • Öncelikle PIC için olan dillerden bahsetmek isterim, bunların en çok bilinenleri C, Basic ve Assembly'dir. Bu dillerin seviyeleri sırasıyla Basic, C ve Assembly olarak düşer. Peki seviye nedir dersek kısaca şu şekilde açıklayabiliriz, en üst seviyede sadece emir verirsin, en alt seviyede ise emirin kendisi olursun, yani örnek olarak eğer PIC'i bir arabaya benzetecek olursak: Basic'te arabayı otomatik viteste kullanıyorken, C'de manuel kullanır, Assembly'de ise vitesin kendisi oluruz. Sonuç olarak da sırasıyla performans artarken, kolaylık düşer. Ancak inan bana çoğu zaman Assembly'nin sağladığı performansa ihtiyaç duymazsın, Basic ve C uygulamaların gerçekten çok büyük bir kısmına yeterlidir.

    Sorduğun sorulara gelirsek, açıkçası uzun süredir Assembly ile uğraşmadığım için ilk iki soruna pek de iyi bir cevap verebileceğimi sanmıyorum, o yüzden 3.'den devam edeceğim. 16F877A'nın analog girişini kullanmak için tek yapman gereken ADCON0 ve ADCON1 register'larını düzenlemek, sonucu ise ADRESH ve ADRESL'den alabilirsin. 4 hakkında da pek bir fikrim yok ama en azından Basic'te veya C'de Byte tipinde bir değişken oluşturup "if...else" veya "select case" ile halledebilirsin. 5'e gelirsek kendi kullandığım derleyici olan Proton IDE'yi öneririm, Basic için olan diğer derleyiciler hakkında pek bir tecrübem yok, ancak proton'un beni gayet iyi bir şekilde tatmin ettiğini söyleyebilirim. Tek yapman gereken ise sol üst taraftaki "Compile", yani derle butonuna basmak, zaten gerisini o kendisi hallediyor, ASM'sini Hex'ini ne varsa istediğin klasör içine atıyor.

    Basic'ten bir örnek vermek gerekirse:

     
    Device 16F877A 'Kullanacağımız PIC'i seçiyoruz.
    XTAL=20 'Kullanacağımız saat hızı. (MHZ cinsinden)
    Input PORTD.0 'D portunun 1. bitini giriş yaptım.
    Output PORTB 'B portunu çıkış yaptım.
    Dim x as Byte '"x" adında Byte tipinde bir değişken oluşturduk, başka bir ad veya büyüklük de verebiliriz.
    x=0

    dongu: '"dongu" adında bir etiket oluşturduk.

    If PORTD.0=1 Then 'Eğer butona basılıp PORTD'nin 0 numaralı biti lojik 1 yapılırsa...

    x=x+1 'x i bir arttır
    PORTB=x 'PORTB'ye x'in değerini yükle

    tekrar: 'tekrar adlı etiket, bu etiketi bir anda değer uçmasın diye yaptım, çünkü bu döngüyü saniyede
    'binlerce kez tekrarlayabilir, sonuç olarak elimizin butona anlık dokunuşu bile 1 byte ı doldurmaya yeter,
    'o yüzden elimizi kaldırana dek bekliyoruz.

    If PORTD.0=1 Then Goto Tekrar 'Eğer PORTD'nin 1. biti hala lojik 1 ise "tekrar" adlı etikete git

    Else 'Eğer PORTD'nin 1. biti 0 sa dongu adlı etikete git (Buradaki Else 1. If dongusunun.).

    Goto dongu '"dongu" ye git

    Endif '"If" döngüsünü kapattık.

    Goto dongu '"dongu" ye git

    End 'Programı bitirmek için kullanılır.


    Aynı kod için Proton'unun hazırladığı Assembly:

     
    NOLIST
    #include "C:\PROGRAM FILES\PROTON\SAMPLES\PROJELER\DHICIN1.PBP"
    LIST

    _X = 32
    F2_SOF equ $ ; DHICIN1.PRP
    F2_EOF equ $ ; DHICIN1.PRP
    F1_SOF equ $ ; DHICIN1.BAS
    F1_000013 equ $ ; in [DHICIN1.BAS] Input PORTD.0 'D portunun 1. bitini giri. yapt.m.
    Bsf STATUS,5
    ram_bank = 1
    Bsf TRISD,0
    F1_000014 equ $ ; in [DHICIN1.BAS] Output PORTB 'B portunu ..k.. yapt.m.
    Clrf TRISB
    F1_000016 equ $ ; in [DHICIN1.BAS] x=0
    Bcf STATUS,5
    ram_bank = 0
    Clrf _X
    DONGU
    F1_000020 equ $ ; in [DHICIN1.BAS] If PORTD.0=1 Then 'E.er butona bas.l.p PORTD'nin 0 numaral. biti lojik 1 yap.l.rsa...
    set@page bc@LL2
    Btfss PORTD,0
    Goto bc@LL2
    F1_000022 equ $ ; in [DHICIN1.BAS] x=x+1 'x i bir artt.r
    Incf _X,F
    F1_000023 equ $ ; in [DHICIN1.BAS] PORTB=x 'PORTB'ye x'in de.erini y.kle
    Movf _X,W
    Movwf PORTB
    TEKRAR
    F1_000029 equ $ ; in [DHICIN1.BAS] If PORTD.0=1 Then GoTo tekrar 'E.er PORTD'nin 1. biti hala lojik 1 ise "tekrar" adl. etikete git
    set@page bc@LL4
    Btfss PORTD,0
    Goto bc@LL4
    F@Jump TEKRAR
    bc@LL4
    F@Jump bc@LL5
    bc@LL2
    F1_000031 equ $ ; in [DHICIN1.BAS] Else 'E.er PORTD'nin 1. biti 0 sa dongu adl. etikete git (Buradaki Else 1. If dongusunun.).
    F1_000033 equ $ ; in [DHICIN1.BAS] GoTo dongu '"dongu" ye git
    F@Jump DONGU
    F1_000035 equ $ ; in [DHICIN1.BAS] EndIf '"If" d.ng.s.n. kapatt.k.
    bc@LL5
    F1_000037 equ $ ; in [DHICIN1.BAS] GoTo dongu '"dongu" ye git
    F@Jump DONGU
    F1_000039 equ $ ; in [DHICIN1.BAS] End 'Program. bitirmek i.in kullan.l.r.
    Pb@lb7
    Sleep
    F@Jump Pb@lb7
    F1_EOF equ $ ; DHICIN1.BAS
    LIST
    END



    Bu da hex dosyasının içeriği:

     
    $00000 - $0000 $0030 $8A00 $0428 $8316 $0814 $8601 $8312
    $00008 - $A001 $8A11 $0A12 $081C $1928 $A00A $2008 $8600
    $00010 - $8A11 $0A12 $081C $1628 $8A01 $1028 $8A11 $0A12
    $00018 - $1B28 $8A01 $0928 $8A01 $0928 $6300 $8A01 $1D28



    Gördüğün gibi Assembly gerçekten büyük olmuş, bu da performansı düşürür, ama merak etme, performans'la ilgili en küçük birşey hissetmeyeceğine seni temin ederim. Bu tip farklar sadece yüksek performans gerektiren projelerde hissedilebilir, öbür türlü bunu anlamak için çok hassas bir cihazla bakman lazım.

    Umarım yazı yardımcı olmuştur, anlamadığın yerler varsa çekinmeden sor, kolay gelsin.




  • ömerege kardeşim yardımın için çok teşekkür ederim ama bişey daha sormak istiyorum mesela ben 877de analog veri girdim adcon dan ayarladım sonucu portb ye atmak istesem adresh ve adresl yi direk atsam sonucu görebilirmiyim? ayrıca bu and - xor gibi işlemler yada sub-add gibi işlemlerin sonucu nerede tutuluyor mesela ben toplama yada bi sayıdan bi sayıyı çıkarttım sonuc nerede? bu konudada aydınlatırsan çok sevinirim...
  • Kılavuza komut seti özetine bak. Mesela ANDWF f,d komutuna bakalım. W ile bir ram baytı (f adresinde) AND işleminden geçecek, sonuç d biti 0 ise W'ye 1 ise f'ye yazılacak.
  • tmm ama mesela b'00000101' (5) sayısı ile b'00000110' (6) sayısını and yaptık bu işlem sonucu nerede kaydolur? ayrıca add komutu ve sub komutuyla işlem yaptığımızdaki işlem sonucu nereye kaydediliyo yani şöyle söyleyeyim arkadaşlar ben 0101 ile 0110 sayısını toplasam sonuç 11 yani 1011 olur işte bunu nereye kaydolduğunu bilsem oradan çekip alacağım ve portb ye aktarıp ledlerde bu sayıya karşılık gelen ledleri yakacağım en basitinden yani ama bunu yapamıyorum çünkü sonuç nerede onu bilmiyorum yani sonucu nereden çekeceğim mesela arkadaşlar 8051 entegresinde sonuş aküde bulunur oradan alırız ama burda nerede??
  • Yukarida da belirtilmis ama okumadiniz sanirim.. Ornegin komutlar 16F877
    ADDWF --- Bu komut W'deki degerle F'deki degeri toplar
    Sozdizimi ----- ADDWF f,d
    burdaki f Bank'daki degerin adresi.. Akumulator yani W'ye yukledigin degerle belirttigin f register'indaki sayiyi toplar...
    Simdi burda d degerini 0 yaparsan sonuc W'ya atilir, eger ki d degerini 1 yaparsan sonuc f registerindaki yere yazilir...
    Sana tavsiyem ilk ogrenmek icin Assembly kullan, sonraki uygulamalarda cok karisir. C veya Basic dilini sec... Assembly komutlar icin de ilgili denetleyicinin Datasheet'ini incele.,
    Timer ile ilgili birseyler sormussun.. TMR0 kesmesini sayac olarak kullanip, disardan saat sinyali almasini saglarsin, yani dedigin gibi RA4, ve yukselen kenar veya da dusen kenar olarak secersin ( sinyalin nasilsa ).. O da 256'ya kadar sayar veya da once TMR0'a 246 yuklersin 10 kere sinyal alinca 256 olur ve tasma meydana gelir, eger kesmeleri acarsan bir alt yordama dallanir.. Ancak dedigin islem icin if else tarzi birsey kullansan daha mantikli.. Tabii bunlari Assembly'de yaparsan cok zaman harcarsin :) RA4'u kullanirsan dikkat etmen gerekir, cunku acik kollektor bir baglantidir ve pull-up etmen gerekir, kendi haline birakirsan sapitir...
    Picbasic ile derleme gayet basit, compile dersin, program sana hex kodunu olusturur..
    Sana tavsiyem C kullan...




  • Bir de ek olarak belirtmek isterim ADDLW, ANDLW gibi komutlar vardı, onlarda da işlem şu şekilde oluyordu W=W+k; örnek vermek gerekirse:

    ANDLW k

    W ile k AND'lenip, sonuç W içine yazılır. "k" nedir dersen kullandığın herhangi bir register.

    Bu arada negatif sonuç için ise STATUS'un Carry bitine bakarız, Carry 1 ise pozitif, Carry 0 ise negatifdir. Sonuç ise 256'nın tamlayanı şeklinde olur; örnek olarak: 8-14=250 çıkar ve Carry biti 0 olur.



    < Bu mesaj bu kişi tarafından değiştirildi omerege -- 1 Mart 2010; 23:34:36 >
  • Yapay Zeka’dan İlgili Konular
    Trojan acil yardım lütfen
    8 yıl önce açıldı
    Java kodu yardım lütfen
    3 hafta önce açıldı
    Daha Fazla Göster
  • arkadaşlar çok teşekkür ediyorum bütün herkese gerçekten şimdi bayağı işi anlamaya başladım çok güzel peki birde mesela dışardan clock verdiğimizde nasıl saydırırız yani şimdi option_reg byte ını ayarlıyorum yükselen kenar tetikleme yapıyorum daha sonra ne gibi işlemler yapmam gerekir? o saydıklarını nerede toplar he birde 877ye analog giriş yaptığımda ilk hangi komutları nasıl ayarlamam gerekir hadi onları bir şekilde yaparız ama mesela 0-5 v gerilimm girsek analog girişten bunu işte her bir değer artışı için pic digitale çevirse yani sayıya (0-255 arası) bizde bunu portbye atsak öylece yani potu ayarlarken değişimi gözlemek istesek ne yapmamız gerekir portbeye hangi byte ı yönlendirmemiz gerekir yani asıl sormak istediğim çevirici çevirdikten sonra nereye yazıyor sonucu? kusura bakmayın çok soru sordum ama bu işi yapmam gerekiyor çünkü gerçekten çok olumsuz koşullar altındayım ama bu işi yapabileceğime inanıyorum çünkü 80c535 i sorunsuz bir şekilde tıkır tıkır programlayabildiğime göre bunuda yapabilirim heralde diye düşünüyorum..




  • 16F877A bize A/D sonucunu toplam 10 bit şeklinde verir. Bunların 8'ini bir ADRES'e diğer 2'sini de diğer ADRES'e yazar, burada hangisine yazacağını biz kendimiz belirleriz. Ancak PORTB'ye bunları aktarırken yaşadığımız sorun bir portun sadece 8 bit desteklemesidir, bu da demek olur ki: ya biz sonucu 10 Bit'ten 8 Bit'e çevireceğiz ya ölçümün baştan veya sondan bir kısmını kaybedeceğiz (0-5V için bu 1V'a denk gelir, yani ya 0-4 arası ölçebiliriz, ya da 1-5 arası), ya da sırasıyla ilk önce bir kısmı, sonra da diğer kısmı göstereceğiz. ADCON0 ve ADCON1'e göz atmanı öneririm, bence 16F877A için en önemli register'lardan ikisi.
  • Yukarida da belirtilmis ama okumadiniz sanirim.. Ornegin komutlar 16F877
    ADDWF --- Bu komut W'deki degerle F'deki degeri toplar
    Sozdizimi ----- ADDWF f,d
    burdaki f Bank'daki degerin adresi.. Akumulator yani W'ye yukledigin degerle belirttigin f register'indaki sayiyi toplar...
    Simdi burda d degerini 0 yaparsan sonuc W'ya atilir, eger ki d degerini 1 yaparsan sonuc f registerindaki yere yazilir...
    Sana tavsiyem ilk ogrenmek icin Assembly kullan, sonraki uygulamalarda cok karisir. C veya Basic dilini sec... Assembly komutlar icin de ilgili denetleyicinin Datasheet'ini incele.,
    Timer ile ilgili birseyler sormussun.. TMR0 kesmesini sayac olarak kullanip, disardan saat sinyali almasini saglarsin, yani dedigin gibi RA4, ve yukselen kenar veya da dusen kenar olarak secersin ( sinyalin nasilsa ).. O da 256'ya kadar sayar veya da once TMR0'a 246 yuklersin 10 kere sinyal alinca 256 olur ve tasma meydana gelir, eger kesmeleri acarsan bir alt yordama dallanir.. Ancak dedigin islem icin if else tarzi birsey kullansan daha mantikli.. Tabii bunlari Assembly'de yaparsan cok zaman harcarsin :) RA4'u kullanirsan dikkat etmen gerekir, cunku acik kollektor bir baglantidir ve pull-up etmen gerekir, kendi haline birakirsan sapitir...
    Picbasic ile derleme gayet basit, compile dersin, program sana hex kodunu olusturur..
    Sana tavsiyem C kullan...




  • quote:

    Orijinalden alıntı: omerege

    16F877A bize A/D sonucunu toplam 10 bit şeklinde verir. Bunların 8'ini bir ADRES'e diğer 2'sini de diğer ADRES'e yazar, burada hangisine yazacağını biz kendimiz belirleriz. Ancak PORTB'ye bunları aktarırken yaşadığımız sorun bir portun sadece 8 bit desteklemesidir, bu da demek olur ki: ya biz sonucu 10 Bit'ten 8 Bit'e çevireceğiz ya ölçümün baştan veya sondan bir kısmını kaybedeceğiz (0-5V için bu 1V'a denk gelir, yani ya 0-4 arası ölçebiliriz, ya da 1-5 arası), ya da sırasıyla ilk önce bir kısmı, sonra da diğer kısmı göstereceğiz. ADCON0 ve ADCON1'e göz atmanı öneririm, bence 16F877A için en önemli register'lardan ikisi.


    Hocam bunların haricinde bir seçenekte A/D çözünürlüğünü 8 bit yapmaktır.




  • peki 10 bit olan sonucu 8bit nasıl yaparız ? ayrıca adreslere kaydediyor demişsiniz biz bunları hangi adrese kaydedeciğini nasıl belirleyeceğiz?
  • Hocam ingilizceniz varsa DAtasheet'de butun bu sorduklariniz yaziyor. Hatta yanlis hatirlamiyorsam 18f877 icin turkce datasheet de olmasi gerkiyor.. Hatta baktim varmis :) Bana mail adresinzii yazarsaniz size yollarim..
    Orda butun registerlar icin aciklama var, ne yapmaniz gerektigi bilgisine kolayca ulasabilirsiniz..
  • arkadaşlar bu adresh ve adresl registerlerini birek olarak portb ye yönlendirsem çıkışı görürmüyüm? yani portb 8 bit adresh 8 bitlik kayıt yapıyor o zaman adresl yi dikkate almayıp sadece bunu yönlendirsem olur mu? birde bu a/d modülü için saat sekimöi var ona nasıl bi ayar yapmamız gerekiyor?
  • quote:

    Orijinalden alıntı: 41ugur41

    arkadaşlar bu adresh ve adresl registerlerini birek olarak portb ye yönlendirsem çıkışı görürmüyüm? yani portb 8 bit adresh 8 bitlik kayıt yapıyor o zaman adresl yi dikkate almayıp sadece bunu yönlendirsem olur mu? birde bu a/d modülü için saat sekimöi var ona nasıl bi ayar yapmamız gerekiyor?


    Saat hızına şu an için bakmana gerek yok, genelde ben hep kendi iç ADC saatini kullanırım (RC). Register'ları da şöyle ayarlayabilirsin:

    ADCON0 = 11000001
    ADCON1 = 11001110

    Sonuç sağa dayalı bir şekilde olacak, yani ADRESL tam dolu, ADRESH'nin ise sadece ilk iki LSB biti dolu olacak. İstediğin herhangi bir adresi de doğrudan PORTB'ye gönderebilirsin.

    EDIT: Bu arada ölçüm PORTA.0'dan olacak. Ölçüm için ADCON0'ın 3. bitini 1 yapıp kendi kendine tekrar 0 atana kadar beklemen yeterli. 0 olduktan sonra sonucu ADRES'lerden alabilirsin. ADCON0'daki biti sürekli kontrol etmek istemiyorsan şöyle bir 1 ms.'lik bir bekleme yapman yeterli.



    < Bu mesaj bu kişi tarafından değiştirildi omerege -- 3 Mart 2010; 22:11:36 >




  • sayın ömerege trisa yı giriş olarak yani h'ff' sayısını yükledim giriş oldu. picin 2 nolu bacağına an0 seçtiğimiz için potun orta ucunu girdim direk dirençsiz şekilde sonra potun diğer uçları biri vdd biri vcc ye bağladım. sonra 20mhz kristal kullandım ve pice besleme verip adreshyide direk portbye gönderdim yani tanımlamalar hariç program şu ;

    CLRF PORTB
    BASLA MOVF ADRESH,W
    MOVWF PORTB
    GOTO BASLA

    END

    yazdım ama portbde hiç ledlerin yandığını görmedim öle sönük duruyolar ve portbyide çıkış ayarladım sonuç aynı :(
  • Bir de şunu deneyebilir misiniz, az önce yazdım, proteus'ta sorunsuz çalıştı.

     
    Org 0x10
    SAYAC1 equ h'21'
    SAYAC2 equ h'22'

    BASLA
    bcf STATUS,6
    bsf STATUS,5
    clrf TRISB
    movlw h'ff'
    movwf TRISA
    movlw b'11001110'
    movwf ADCON1
    bcf STATUS,5
    movlw b'11000001'
    movwf ADCON0
    bsf ADCON0,2
    Call GECIKME
    bsf STATUS,5
    movlw ADRESL
    bcf STATUS,5
    movwf PORTB
    GoTo BASLA

    GECIKME
    movlw d'250'
    movwf SAYAC1

    DON1
    movlw d'250'
    movwf SAYAC2

    DON2
    decfsz SAYAC2,F
    GoTo DON2
    decfsz SAYAC1,F
    GoTo DON1
    Return
  • bu programı atıyorum şimdi ama winpic800 kullanıyorum acaba konfigrasyon ayarları nasıl olmalı? boren lvp hangilerini işeretli bırakmalıyım?
  • Ben yükleyici olarak MicroPro kullanıyorum, şu şekilde ayarladım.

    Disabled(Kapalı):
    WDT
    BODEN
    CPD
    DEBUG
    Code Protect
    LVP

    Enabled(Açık):
    PWRTE
    WRT Enable

    OSC=HS
  • tmm hemen deniyorum..
  • 
Sayfa: 12
Sayfaya Git
Git
sonraki
- x
Bildirim
mesajınız kopyalandı (ctrl+v) yapıştırmak istediğiniz yere yapıştırabilirsiniz.