avatar_ewreka

pic16f628A ile led gösterisi projesi

Başlatan ewreka, 31 Aralık 2015, 21:10:02

ewreka

Merhaba üstadlar.
Bundan birkaç ay evvel ilk projem için bu foruma yazmıştım @ete hocam da pic16f628a ile başlamamı söylemişti.
pickit3 almış bulundum, bu yüzden mplab ide kullanmak zorundayım.Malzemeleri temin ettim fakat kodu yazmakta zorluk yaşıyorum, isis şeması şu şekilde:



Fakat, dostlar nereden başlayacağımı bilmiyorum bu işte çok yeniyim.

başlangıç kodu şu şekilde

LIST P=16F628A         ;PIC16F628a' Tanıt
#INCLUDE  "P16F628A.INC" ;PIC'in INCLUDE DOSYALARI TANIT
__CONFIG   _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF                                        ;KONTROLOR AYARLARI
ORG 0x00
SAYAC_1 EQU h'20'
SAYAC_2 EQU h'21'
MOVLW 0x07
MOVWF CMCON
BSF STATUS, RP0 ;select bank 1
    MOVLW h'00' ;set PortB all outputs
    MOVWF TRISB
BCF STATUS, RP0 ;select bank 0
DUGME_1_TEST
BTFSC PORTA, 0
GOTO DUGME_1_TEST ;HAYIR
GOTO DUGME_1 ;EVET

DUGME_1
CLRF PORTB
MOVLW h'00'
MOVWF PORTB

SOL ;SOLA KAYDIRMA ISLEMI YAPILIYOR
CALL BEKLE
RLF PORTB, F ;Rotate Left f
BTFSS PORTB, 7
GOTO SOL
SAG ;SAGA KAYDIRMA ISLEMI YAPILIYOR
CALL BEKLE
RRF PORTB, F
BTFSS PORTB, 0
GOTO SAG
GOTO SOL
BEKLE
MOVLW h'FF'
MOVWF SAYAC_1
DONGU1
MOVLW h'FF' ; -> 11111111
MOVWF SAYAC_2
DONGU2
DECFSZ SAYAC_2, F
GOTO DONGU2
DECFSZ SAYAC_1, F
GOTO DONGU1
RETURN
        END


program başladığında bazı ledler yanıyor bazıları sönük RA 00 butonuna bastığımda program çalışıyor.
Amacım bu dört butonla değişik efektler yapmak,Yardımlarınızı bekliyorum.
Hürmetler.

ete

Birincisi yazdığın kodlar ASM kodları. Pickit3 ün var diye illaki mplab ide kullanmak zorunda değilsin.
Burası bir genel anlamda Basic forum sitesi. Her ne kadar genel  program algoritmaları üzerinde konuşsakda temel basic e dayanıyor. Kişinin bütün programlama dillerini bilmesi gerekmiyor. Ama kendisine en yakın olan bir dili tercih edip o konuda kendini geliştirmesi en doğrusu.
Şimdi senin bir karar vermen gerekiyor. ASM de mi devam edeceksin yoksa başka bir dilide kullanabilecekmisin.

Bu karardan sonra burada açıkladığın soruna bir cevap alabilmen için yapılacak işin senaryosunuda yazman gerektiğini unutmaman gerekir zira. Tuşlara basılınca değişik efektler yapmak istiyorum demek başka, şu tuşa basınca şöyle bir efekt, ikinci tusa basınca şöyle bir efekt çıksın demek farklı şeylerdir ve ikincisi seni daha hızlı sonuca götürür.
Ete


ewreka

Sayın @ete cevabınız için teşekkür ederim, size hemen cevap yazmadım çünkü hangi dille başlayacağımı düşünüyordum.
Sanırım asm ile başlamak iyi bir tercih olacaktır çünkü temel bir dil.Ben elektronikten çok anlamasam da programlama dillerinden biraz anlarım.

Şimdi yapmak istediğim 8 ledin (yani button 2 yebasınca) sırasıyla yanarak ortada buluşup geri gitmesi yani şu şekile;

12345678 -> ledler
10000001
01000010
00100100
00011000
00100100
01000010
10000001
0 -> sönük ledler
1 -> yanan ledler

kod şöyle idi ama çalışmadı!


LIST P=16F628A         ;PIC16F628a' Tanıt
#INCLUDE  "P16F628A.INC" ;PIC'in INCLUDE DOSYALARI TANIT
__CONFIG   _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _LVP_OFF                                        ;KONTROLOR AYARLARI
ORG 0x00

SAYAC_1 EQU h'20'
SAYAC_2 EQU h'21'

CLRF PORTB
BCF STATUS, 0
BSF STATUS, 5
CLRF TRISB
BCF STATUS, 5

MOVLW h'07'
MOVWF CMCON
;================================ BUTTON 1 KONTROL ===========================================
DUGME_1_TEST
BTFSC PORTA, 0
GOTO DUGME_1_TEST ;HAYIR
GOTO SAG_ILERI ;EVET
;================================ BUTTON 1 İŞLEM ===========================================
SAG_ILERI
CALL BEKLE
CALL ILERI
RLF PORTB, F
GOTO SAG_ILERI
GERI
MOVLW h'80'
MOVWF TRISB
ILERI
MOVLW b'10000001'
MOVWF TRISB
BEKLE
MOVLW h'FF'
MOVWF SAYAC_1
DONGU1
MOVLW h'FF'
MOVWF SAYAC_2
DONGU2
DECFSZ SAYAC_2, F
GOTO DONGU2
DECFSZ SAYAC_1, F
GOTO DONGU1
RETURN
END


Şimdiden teşekkür ederim.
Hürmetler

ete

Yazdığın kod yalnızca tek buton kontrolüne imkan tanıyor oda PORTA.0 da bağlı olan butona.
Çünki butona basılmışmı bakıyorsun, BTFSC PORTA, 0
basılmamış ise  GOTO DUGME_1_TEST    komutunu vererek basılıncaya kadar orada programı hapsediyorsun. hadi diyelimki şimdilik tek butonla çalışacaksın. Diğer yanlışın ise ,
	MOVLW h'80'
MOVWF TRISB
ILERI
MOVLW b'10000001'
MOVWF TRISB
BEKLE
şeklinde yazdığın kodlardaki TRISB ifadesi. Sen aslında PORTB ye değer yazmak istiyorsun ama oraya yazacağına PORTUN giriş çıkış pinlerini ayarlayan register olan TRIS registerine yazıyorsun. TRISB yerine PORTB yazman gerek sanırım.
Birde ledlerin diğer hareketleri eksik kalmış. Yani porta verilecek 8 ayrı değer olması gerek. Sen yalnızca 1 tane veriyorsun diğerleri nerede?

Ete

ewreka

çok teşekkür ederim sayın @ ete. cevabınız için.
Dediğiniz gibi oraları düzelttim.Düğmeleri koymadım, çünkü kod karmaşasına neden oluyorlar, adım adım gitmeyi planlıyorum.
Amacım 4 tuşun görevlerini yaptıktan sonra bunları birleştirmek.

ewreka

merhaba arkadaşlar, hani şu 2. buttona basınca ledler şu şekilde yapacaktım ya
12345678.led
10000001
01000010
00100100
00011000
00100100
01000010
10000001
0 -> sönük ledler
1 -> yanan ledler

bunu pic basic  ile  yapmaya  çalışıyorum çünkü işin çok başındayım, evet assembly temel bir dil olsa da elde edilen hex dosyaları aynı diye düşünüyorum.Assembly dili ile ilgili kaynakbulmak,pic basic'e  göre  daha zor.
Eğer ben bunu picbasic ile  yapabilirsem (daha doğrusu anlayabilirsem) bundan  sonra  picbasic ile  devam etmeyi düşünüyorum.

Bir diğer sodum ise yukarda belirttim gerçi ama PİC C, PICBASIC PRO , PIC ASSEMBLY gibi programlardan elde edilen .hex dosyasında  bir fark olur mu? yani performans ve bellekte kapladığı yer açısından?

Bir diğer soru m ise pickit3 ü picbasic te nasıl kullanabilirim? mplab gibi direkt olarak belleğe atarcasına nasıl kullanabilirim?

Cehaletimi affedin ama ben  bu işlere yeni başladım ve çevremde bu  iş ile uğraşan  kişiler  yok yani  tekbaşımayım.
Şimdiden teşekkür ediyorum.
HÜRMETLER...

ewreka

tekrar  merhaba  arkadaşlar.
kod şu şekilde ama  nerede hata yapıyorum  bilemiyorum.

bu arada pbp ve mplab işini  yaptım yani mplab ide  de pbp derleyebiliyorum.sanırım mplabda pickit3 e de atabilirim.


ILERI VAR byte
GERI VAR BYTE
    TRISB = 0         'Portb yi çıkış olarak yönlendir
    PORTB = 0         'Portb yi temizle
    Portb.0=1       'Portb nin 0.bitini 1 yap(yak)
    PORTB.7 = 1
   
main1:
for ILERI = 1 to 4
    pause 500
    portb=portb<<1       

    for GERI = 1 to 4
        pause 500
        PORTB = PORTB << 1         
    NEXT
NEXT       
goto main1

ete

#7
Bütün dillerin anası ASM dir. Pic bu dil ile çalışıyor. derleyiciler kendi dillerinde yazılanları derleme sonucunda bu dile çevirirler.
Bu çevirme işlemi hiç bir zaman direk ASM de yazılan program kadar küçük ve az yer kaplayacak şekilde olmaz. Kısaca bu konuda en iyisi direk ASM de yazılandır. Ama sende gördünki ASM de yazma gerçekten çok külfetli bir iş. Ancak uzun yıllar sonra edinilen tecrübe ile insan basic deki kadar rahat yazabilir bu ASM ile. Diğer diller yazma ve mantık yürütme kolaylığı getirirler. Bu zaman kazancı demektir.

Programlama kartının derleyici ile alakası yoktur. Pickit2 veya Pickit3 senden yüklenecek HEX dosyasını ister. Yüklersin ve pice yazarsın olur biter. HEX dosyası ilse bildiğin üzere derleme sonucunda elde edilen bir dosya.

Gelelim yapmak istediğine:
Başlangıç değerin 10000001 ise ve ikinci değer sol tarafın bir bit sağa ve sağ tarafın bir bit sola kaydırılması şeklinde gerçekleştirilmesi şeklinde elde edilmelidir.
Yaptığına bakarsak ;
portb=portb<<1  komutu PORTB deki bilginin 1 bit sola kaydırılmasını sağlayacaktır. Bu ise istediğine pek uymuyor.
Bu işi otomatik yapmak istiyorsan iki değişken kullan ve bunları birleştirip PortB ye yerleştir. Şu anda aklıma gelen yöntem bu.
Mesela;
SOL=128 (veya SOL=%10000000),   (SOL VAR BYTE şeklinde değişken tanımlanması gerekiyor)
SAG=1 (veya SAG=%00000001) olsun  (SAG VAR BYTE şeklinde değişken tamamlanması gerekiyor)
PORTB=(SOL & %11110000)+(SAG & %00001111) şeklinde alınıp porta verilir ise PORTB=%10000001 değerini alır.
Şimdi döngümüzü kurup 4 defa çalışacak şekilde ayarlar ve değişkenlerimizi farklı yönlere kaydırıp yeniden birleştirerek porta verirsek işimiz görülmüş olacaktır.
FOR I=0 to 3
PORTB=(SOL & %11110000)+(SAG & %00001111)
Pause 200
SOL=SOL>>1:SAG=SAG<<1
NEXT


Bu döngü tamamlandığında SOL değişkenimiz SOL=%00010000 ve SAG değişkenimiz SAG=%00001000 değerlerine ulaşacaktır. Şimdi aynı döngüyü tersine çevireceğimize göre yaptıklarımızın tersini yaparak tekrar başlangıca döneceğiz.
FOR I=0 to 3
PORTB=(SOL & %11110000)+(SAG & %00001111)
Pause 200
SOL=SOL<<1:SAG=SAG>>1
NEXT


şeklinde işi bitiirmiş olacağız. Bu aşamada GOTO BASLA diyerek işlemi sürekli tekrarlamak mümkün olacaktır.

Derleme işini direk MPLAB da yapabilirmisin bilmiyorum. Bu konuda hiç bir fikrim yok. Ama olabileceğini sanmıyorum.
Derleme ancak PBP derleyicisi ile olmalı. Nasıl olacağını aşağıdaki linki okuyarak anlayabilirsin.

http://etepic.com/index.php/topic,300.0.html

Ete


ewreka

Sayın @ete hocam çok ama çok teşekkür ederim.
Size  nasıl teşekkür etsem bilemedim, uzun uzun anlatmışsınız ayrıntılı olarak.
Bende MCSD idim 2003 de almıştım sertifikayı. ama  şu an programcılık yapmıyorum.Görüyorum ki pic basic benim aldığım eğtime daha yakın duruyor.Bu yüzden pic basic pro ile devam edeceğim.

Şimdi iş butonları yerleştirmeye geliyor.Ben bu işi hemen yapabilirim fakat tahminimce "kesme" kullanmak gerekecek, bunun nasıl yapılacağını malesef bilmiyorum.Bu konuyu araştırdıktan sonra yine foruma yazacağım.

Tekrar teşekkür ederim sayın ete hocam, Görüşmek üzere.

ewreka

Merhaba arkadaşlar.
Projemi  tamamladım, sizden sadece bir bakmanızı rica edecektim.
bir hata varmı nasıl yazsam daha iyi olur lütfen belirtin.

Ha bu arada bu projeye şunu eklemek istiyorum; yanan ledler varya arkadaşlar;
Yanan ledin arkasındaki iki ledin biraz sönük yanmasını istiyorum, yani aslında üç led yanacak mesela  sağa doğru yanıyor ise; en baştaki tam(%100) bir arkasındaki (%75) bir arkasındaki  ise (%25) yanacak gibi düşünebiliriz, sanırım bu PWM le ilgili.

proje şeması yukarda  , kodlar ise şu şekilde:


'*************************************************************************************
@ __config _INTRC_OSC_NOCLKOUT & _WDT_ON & _PWRTE_ON & _MCLRE_OFF & _LVP_OFF & _CP_OFF
'*************************************************************************************
portb=0
TRISB=%00000000   'PortB tamamı giriş yapıldı.
TRISA=%00001111   'A portu tamamı çıkış yapıldı.
'*************************************************************************************
ON INTERRUPT GoTo KESME
OPTION_REG=%10000101   'Pull up dirençleri İPTAL- Bölme oranı 1/64.
INTCON=%10100000  'Kesmeler aktif ve TMR0 kesmesi aktif
TMR0=0
CMCON=7   

SAG VAR BYTE
SOL VAR BYTE
I VAR BYTE
BEKLE VAR WORD

SYMBOL TUS_KARA_SIMSEK = PORTA.0
SYMBOL TUS_ORTADA_BIRLES = PORTA.1
SYMBOL TUS_HIZ_ARTIR = PORTA.2
SYMBOL TUS_HIZ_AZALT = PORTA.3
CLEAR   

BEKLE = 200 
PORTB = 0                   'Portb yi temizle

BASLA:
    PAUSEUS 1000
    GOTO BASLA
'*************************************************************************************
KARA_SIMSEK:
    PORTB.0 = 1
    for i=1 to 7
    pause BEKLE
    portb=portb<<1
    next
    for i=1 to 7
    pause BEKLE
    portb=portb>>1
    next 
goto KARA_SIMSEK 
'*************************************************************************************
ORTADA_BIRLES:
    SOL=128
    SAG=1
    FOR I=0 to 3
    PORTB=(SOL & %11110000)+(SAG & %00001111)
    Pause BEKLE
    SOL=SOL>>1:SAG=SAG<<1
    NEXT
    FOR I=0 to 3
    PORTB=(SOL & %11110000)+(SAG & %00001111)
    Pause BEKLE
    SOL=SOL<<1:SAG=SAG>>1
    NEXT
goto ORTADA_BIRLES
DISABLE
'**************************************************************************************
KESME:
    IF (TUS_KARA_SIMSEK = 0) then
        PORTB = 0
        PAUSE 1000
        GOTO KARA_SIMSEK                               
    ENDIF
    if (TUS_ORTADA_BIRLES = 0) then
        PORTB = 0
        PAUSE 1000
        goto ORTADA_BIRLES
    ENDIF
    IF (TUS_HIZ_ARTIR = 0) THEN
        BEKLE = BEKLE - 50
        IF (BEKLE < 50) THEN
            BEKLE = 50
        ENDIF
    ENDIF
        IF (TUS_HIZ_AZALT = 0) THEN
        BEKLE = BEKLE + 50
        IF (BEKLE > 500) THEN
            BEKLE = 500
        ENDIF
    ENDIF
    INTCON.2=0         
    Resume             'geldiğin yere dön
    Enable             'kesmeler yeniden aktif.
END



Projeyi bitirmeme çok az kaldı, şimdiden teşekkür ederim.

Hürmetler.

ete

Program mantık olarak fena değil ama tuttuğun yol yanlış. Kusurlar şunlar,
1. Kesme kullanılan programda en büyük pause 5us olmalı. Fazlası gerekirse döngü kurarak 5us nin katlarını elde etmelisin.

2. Belkide en önemli hata kesme içinden programı kesme dışına göndermen. Bu şekilde programın çalışması mümkün değil. Kesme özel bir bölgedir. Oraya girdinmi usulüne uygun şekilde resume enable ile çıkmalısın. Bu gibi durumlarda kesme içinde elde ettiğin seçeneklere göre bir işaret değişkeni (bir nevi flag) set edersin sonra geldiğin yerde bunu test ederek ilgili program kısmına programı yönlendirirsin. Böylece program değişkliği kesme içinde değil kesme dışında yapılmış olur.
Şöyle bir örnek vereyim. Sıra isimli bir değişkenin olsa ve sıra=1 ,karaşimşek, sıra=2 ise ortada birleş programını temsil etmiş olsa. Program başla etiketine geldiğinde sıra=0 ile gelmiş olsun. Bu konumda bir tuşa basılırsa ve bu tuş karaşimşek tuşu ise kesme içinde yalnızca sıra=1 yapıp kesmeden çıkman yeterli olacaktır. Basılan tus ortadabirleş tuşu ise sıra=2 olacaktır.
Basla etiketinden hemen sonra if sıra=1 then karasimsek ve benzer şekilde if sıra=2 then ortadabirleş demen yeterli olacaktır. Kesme oluşmadığı sürece sıra=0 kalacağı için program oradan ayrılmayacaktır.
Diyelimki programı karasimsek kısmına gönderdik. Orada çalışırken yeniden bir tusa basılırsa ve bu tus ortada birleş tuşu ise sıra=2 olarak geri dönecektir. O halde karasimsek alt programında If sıra=2 then ortadabirles demen gerekir. Aynı şekilde ortada birleş kısmında ise If sira=1 then karasimsek demen gerekir.
Süre değiştirme tusu mvcut şekli ile kalabilir.

Ete

ewreka

Ete hocam çok teşekkür ederim, verdiğiniz cevabı tekrar tekrar okuyup araştırma yapacağım.Sağlıklı günler dilerim

Hürmetler.

ete

Programda bazı eksiklikler ve kusurlar vardı. Onları düzelterek söylediğim mantık üzerinden programını çalıştırdım.
Sorunsuz çalışıyor. Dosyalar ilişiktedir.
Ama bakmadan önce sende kendi mantığını oluştursan iyi olur.
İlgilenen arkadaşlar için güzel bir örnek olduğunu düşünüyorum.

Biraz açıklama vermek iyi olacak öğrenenler için sanırım.
Bu sistemde A portuna bağlı 4 adet buton bulunmaktadır. Buton kontrolü normal program akışı içinde yapılmıyor.
Onun yerine yaklaşık her 16ms de bir TMR0 kesmesi oluşturularak sistem tuşları kesme içinde kontrol etmektedir.
Bu tuşların iki adedi animasyon seçim tuşu diğer ikiside animasyon hızı azaltma ve artırma tuşları olarak çalışmaktadır. Animasyon seçim tuşları SIRA ismini verdiğimiz değişken değerini değiştirmekte ve buna bağlı olarak ana program akışında ilgili animasyon hemen seçilmektedir. BU sistem bayağı randımanlı çalışıyor.
Hız işinde pause yerine döngüsel gecikme kullandım ve başlangıç değerini 5000 aldım bu yaklaşık 5000*10=50.000 us lik gecikmeye tekabül etmekte olup maksimum değeri 100 ms olmaktadır. Aslında döngünün getirdiği komut gecikmeside sürede etkili olduğu için görsel olarak bakıp bu süre değerlerini kullanmaya karar verdim. İsteyen değiştirebilir.
Ete

ewreka

Tamam sayın hocam, ben de araştırma yapıyordum.
pause, pauseus' u nasıl kullanabilirim diye.Hocam kesme olduğunda pauseus yani mikrosaniye kullanmamızın sebebi kesmeye daha rahat dallanabilmesi mi?

Ve yukarda bahsettiğim; yanan led (%100) arkasındaki led (%50) bir arkasındaki led ise (%25 ) yansın istiyorum programınıza bakmadığım için bunu yaptınızmı bilmiyorum.
Bunun nasıl olduğu hakkında biraz tiyo verebilirmisiniz

Hürmetler sayın hocam.

ete

Ledleri %100 yansın %50 yansın demek zor. Bunu yapmanın yolu PWM kullanmaktan geçiyor.
Kullandığın Pic de 1 adet HPWM (ana programdan bağımsız geri planda çalışan) çıkışı var. Ama sana 8 adet PWM lazım. Bu durumda yazılımsal PWM yaratman gerekiyor. Bunu yaptığın zaman ya tuş kontrolün zayıflayacak yada Led kontrolün ikisini bir arada yapayım dersen daha hızlı bir işlemci kullanmak gerekebilir.
Üstelik standart bir parlaklık seviyeside istemiyorsun kayan ledlerde ardışık parlaklık kontrolü istiyorsunki bu sağlam bir algoritma da gerektiriyor.

Sitede MIBAM konusunu araştır. Buna ait bir program vermiştim diye hatırlıyorum.
İşin temelinde Led pininden bir PWM sinyali çıkartmak ve bu sinyalin DUTY değerini yavaş yavaş düşürmeye dayanır. Normal PWM ile çalışırsan çok fazla komut gecikmesi yaşayacağın için MIBAM (Mirror Bit Angle Modulation) sistemi ile yapmak biraz daha kolay hale gelebiliyor.
Ama yinede istediğini he riki animasyon modunda yapmak çok sağlam bir program gerektiriyor. Biraz kafa yorunca anlayacaksın.

Ete

Powered by EzPortal