Pic in bir çıkışı high iken diğer çıkışları high yapmak ?

Başlatan sint0, 28 Ocak 2018, 15:07:06

sint0

Arkadaşlar merhaba,

Senaryoyu anlatayım. Bildiğimiz üzere 16f628a'nın 16 adet giriş çıkış ucu bulunuyor.

BUTON1 VAR PORTB.0
BUTON2 VAR PORTB.1
BUTON3 VAR PORTB.2
BUTON4 var PORTB.3
 
CIKIS1 VAR PORTA.0
CIKIS2 VAR PORTA.1
CIKIS3 VAR PORTA.2
CIKIS4 VAR PORTA.3

B portunun 4 tanesini giriş , A portunun 4 tanesini çıkış olarak kullandım.

Aşağıdaki programa göre BUTON1=0 olduğunda , CIKIS1 60 sn High oluyor. Burada sorun yok.

Fakat CIKIS1 high durumdayken BUTON2 BUTON3 BUTON4 çalışmıyor.Yani program başa dönmeden çalışmıyor orada takılıp kalıyor.
CIKIS1 60sn high konumundayken BUTON2-3-4 ü aynı anda nasıl kullanabilirim? 

Değerli hocalarımdan yardım istiyorum. Teşekkürler.


CMCON=7
DEFINE OSC 4

B VAR BYTE
B=0

BUTON1 VAR PORTB.0
BUTON2 VAR PORTB.1
BUTON3 VAR PORTB.2
BUTON4 var PORTB.3
 
CIKIS1 VAR PORTA.0
CIKIS2 VAR PORTA.1
CIKIS3 VAR PORTA.2
CIKIS4 VAR PORTA.3

trisa=%00000000
trisb=%11111111

porta=0
portb=1

PAUSE 10

BASLA:

if BUTON1=0 THEN
CIKIS1=1
PAUSE 60000
ENDIF

IF BUTON2=0 THEN
CIKIS2=1
PAUSE 60000
  ENDIF
 
IF BUTON3=0 THEN
CIKIS3=1
PAUSE 60000
ENDIF

IF BUTON4=0 THEN
CIKIS4=1
PAUSE 60000
ENDIF

GOTO BASLA
END


ete

Sebebini hiç düşünme fırsatın oldumu?
Ben söyleyeyim istersen;
Pause 6000 sana 6 senlik bir gecikme yaratır. Bu süre birmeden pic diğer komut satırına geçemez.
Bu durumda hem gecime yaratıp hemde tuşlara basılmışmı bakman gerekecek.
Bu durumda şayet bakılacak buton tek olsa normal 6 sn lik bir gecikme yaratıp onun içinde iken diğer butonada basılmışmı bakabilirdin. Ama elinde 4 adet buton var. Her birinin basılması durumunda 6 sn lik gecikmesi mevcut. Bu durumda tek bir gecikme alt programı ile bu işi halletmek imkansız. Zira bir butona basıldımı 6 sn lik süresi başlayacak ve diyelimki 1 dakika sonra diğer butona da basıldı onunda 6 sn lik siresinin başlaması gerekir. Başlatmak kolayda ayrı ayrı zamanları saydırmak kolay değil. Daha doğrusu yolu bu değil.
Sonuca gelecek olursak,
1 sn lik sayan standart bir süren olacak. Hem tuş kontrolü yapıp hemde bu süreyi saydırman gerekecek.
Her bir butonun ayrı süre sayacı olacak ve her 1 sn geçişinde kim aktif ise onun sayacı 1 artacak.
Süresi dolan ne yapacak bunu programında belirlememişsin. Bu ledler yanacak da kim söndürecek. Madem söndürülmüyorlar neden 6 sn orada bekliyorsun buda garip aslında.
Diğer bbir metod ise Kesme kullanarak standart bir süre sayımı yaplabilir. He rbir kesme 100 ms olursa 1 sn geçmesi için 10 kesme geçmesi gerekir. Bu kesmeler sayılarak süreleri hesaplayabilirsin.
Dediğim gibi standat bir süre sayacın (100-1000 ms) olacak ve her bir butonun kendi süre sayacı olacak. Aktif isimli bir değişkenin olacak bunun ilk 4 biti senin aktif bitlerin olacak. Aktif olanın biti 1 olacak ve hangisi aktif ise süre sayacı standart süre bitimi sonunda bir artırılacak. Olay bundan ibaret.
Üzerinde çalış yapamazsan tekrar mesaj at.
Ete

sint0

Sayın Erol hocam,

Şu anda tetik almak için 1 entegre, zamanları saydırmak için her kanal başına 1 entegre kullanıyorum. Devrede toplam 9 adet mikrodenetleyici bulunuyor.

ana entegre tetiği aldıktan sonra 1 portu high yapıyor. Diğer 8 entegrenin input butonlarına veriyor. Hangi kanalın butonuna basılırsa ,o entegre ana entegreyi mclr ucuna 100ms high göndererek resetliyor ve kendi çıkış portunu 30 dk boyunca high yapıyor. 8 kanallı devre, her kanalı saydırmak için 1 mikrodenetleyici kullanıyorum.

9 entegre kullanmak yerine 1 entegreyle bu algoritma çalışabilir mi? Kullandığım kodlar aşağıda mevcut. Teşekkürler.

ana entegre
CMCON=7
DEFINE OSC 4


B=0

BUTON VAR PORTB.0

CIKIS VAR PORTA.0

trisa=%00000000
trisb=%11111111

porta=0
portb=1

PAUSE 10

BASLA:

if BUTON=0 THEN
CIKIS=1
WHILE BUTON=0:WEND
PAUSE 100 'buton titremesi
ENDIF


GOTO BASLA
END



kanal entegre kodu

CMCON = %00000111 
ANSEL= 0
TRISIO=%001110


LED1 VAR GPIO.0
TUS1 VAR  GPIO.1
RESET VAR GPIO.4
GPIO=0



PAUSE 10         
     

DONGU:

    IF TUS1=1 THEN             
    HIGH RESET
    PAUSE 100
    LOW RESET
    high LED1
 
    PAUSE 65500
    PAUSE 65500
    PAUSE 65500
     PAUSE 65500
    PAUSE 65500
    PAUSE 65500
    PAUSE 65500
    PAUSE 65500
     PAUSE 65500
    PAUSE 65500
    PAUSE 65500
    PAUSE 65500
    PAUSE 65500
     PAUSE 65500
    PAUSE 65500
    PAUSE 65500
    PAUSE 65500
    PAUSE 65500
     PAUSE 65500
    PAUSE 65500
    PAUSE 65500
    PAUSE 65500
    PAUSE 65500
     PAUSE 65500
    PAUSE 65500
    PAUSE 65500
    PAUSE 65500
    PAUSE 65500
    low LED1                 
       ENDIF
 
   
       

GOTO DONGU
                     
    END

ete

Bu sistem tek işlemci ile çalıştırılabilir. Yazdıklarından az çok sistemi anladım ama aslında bu yazılanlar yerine amacı ortaya koyan işlemciden bağımsız bir senaryo verilese daha kolay halledilebilir idi. Bu bir algoritma meselesi. Programcılıkta ortada bir amaç vardır ve bu amacı gerçekleştirecek yan birimler vardır (butonlar, göstergeler, ışıklar vs) Kişi ortaya bir algoritma yani amacın gerçekleştirilmesini sağlayacak bir gidiş yolu koymak durumundadır. Bu bazen kestirmeden giden bir yol olur ve olaya tek yönden bakmakla çok yönden bakmak arasındaki farka bağlı olarak amacı gerçekleştirir ama ortaya başka sorunlar koyar senin örneğinde olduğu gibi. Bu işi anlatırken sürekli kendi algoritmasından etkilenen kişi anlatırkende o algoritmaya pararlel bir algoritma ortaya koyar. Yine sende olduğu gibi diyeceğim çünki öyle yapıyorsun. Akıl akıldan üstündür 10 kişiye sorsanız 10 kişi farklı yollardan amaca gidiş yolu belirleyebilir ama daima bnların içinden birisi en iyisidir. Buda tecrübe ile ortaya koyulan bir işlem olur çoğunlukla.
Bu nedenle sen önce bir senaryo ver bir nevi lafla olayı gerçekleştirmek gibi. Ardındn yeniden düşünelim.

Ben bir başlangıç yapayım istersen bu senaryoya.
Önce donanım olarak 8 adet butonumuz ve bunların hepsi bir giriş pinine bağlı olmalı , 8 adet de  çıkış pinimiz olmalı.
- Bu butonlardan herhangi birine basıldığı zaman o butona ait çıkış pini HIGH yapılmalı ve o pinin HIGH da kalma süresi en az 30 dakika olmalı.
- Her hangi bir çıkışta 30 dakikalık high süresi çalışırken diğer butonlarda hala aktif olmalı ve her hangi bir butona basıldığında onunda çıkışı 30 dakika süre ile sayabilmelidir.
- Programda yada açıklamada eksik olan bu 30 dakikalık süreler sonunda o çıkışların ne olacağı. Yani her bir aktif olan çıkış 30 dakika sonunda pasif mi olacaktır bunu açıklamak gerek.
benden bu kadar çünkü buraya kadar anladıklarım. Gerisini sen yaz.

Ete

sint0

Alıntı yapılan: ete - 29 Ocak 2018, 08:10:53
Ben bir başlangıç yapayım istersen bu senaryoya.
Önce donanım olarak 8 adet butonumuz ve bunların hepsi bir giriş pinine bağlı olmalı , 8 adet de  çıkış pinimiz olmalı.
- Bu butonlardan herhangi birine basıldığı zaman o butona ait çıkış pini HIGH yapılmalı ve o pinin HIGH da kalma süresi en az 30 dakika olmalı.
- Her hangi bir çıkışta 30 dakikalık high süresi çalışırken diğer butonlarda hala aktif olmalı ve her hangi bir butona basıldığında onunda çıkışı 30 dakika süre ile sayabilmelidir.
- Programda yada açıklamada eksik olan bu 30 dakikalık süreler sonunda o çıkışların ne olacağı. Yani her bir aktif olan çıkış 30 dakika sonunda pasif mi olacaktır bunu açıklamak gerek.
benden bu kadar çünkü buraya kadar anladıklarım. Gerisini sen yaz.

Ete


Evet Erol hocam senaryo  yukarıdakiler ve  30 dakika sonra pasif olacak.

ete

Ortada bir şema yok. Yazdıklarıma bakarsan 8 giriş ve 8 çıkış pini ihtiyacın var. Bunu net bir şekilde 18 bacaklı işlemciler sağlayamaz.
Bu durumda 28 pin işlemcilerden birini kullanmak gerekir.
Piyasaya bakınca güncel yeni nesil ve düşük maliyetli işlemciler olarak, 16F886, 18F25K22 gibi işlemcilerden birini kullanmak uygun olur.
Sence ne yapılmalı. Tabiiki ihtiyacı 8 giriş 8 çıkış ise gerçekten. Çünki programlara bakıyorum hep 4 giriş kullanmışsın. Buda olursa 8 olsun yedekte bulunsun mantığı güdüyorsun gibi bir intiba uyandırıyor bende.
Neyse en azından işin tamamını ben yapmış olmamak için işlemciden bağımsız bir kod örneği vereceğim sana sen artık kendine göre düzenlersin kime uygulayacak isen.

Ete

sint0

Evet hocam 8 kanal yedek olsun diye ilerde mikrodenetleticiyi büyütürüm diye düşünüyorum.

ete

8 pin üzerinden çalışacak örnek kodu aşağıda veriyorum. İşlemciden bağımsız yazdım kodu işlemciye göre en azından PORTB pullup dirençlerini aktive edersin.
Yanlarına mümkün olduğunca açıklama koydum. Program TMR1 sayacının her 500 ms (yarım saniye) de bir kesme oluşturması esasına dayanmaktadır. Böylece 120 kesme sonunda 1 dakikalık süre geçmiş olacaktır. Bu noktada aktif olan çıkış veya çıkışların dakika sayaçlarını birer artırıp 30 olup olmamalrına bakmak yada baştan 30 verip her dakika geçişinde birer eksilterek sıfır olup olmadıklarına bakmak işimizi halledecektir.
Program aşağıdadır.
Bu bir algoritma çalışmasıdır. Konuyla ilgili diğer arkadaşlarında incelemesini isterim. Sorusu olan olursa cevaplarım.
Kısaca yaptığımız iş, her biri 500 ms lik süre alan bir kesme yaratmak ve bu kesmeleri sayarak 120 tane olup olmadığına bakmak. Bu esnada yani 500 ms lik kesme süresi içinde de sürekli olarak 8 adet giriş butonlarından birine basılıyormu diye bakmak ve basılanlardan pasif olan var ise ki bunu AKTIF isimli değişkenin bitlerinden anlayabiliyoruz ona ait çıkışı aktif edip sayacını başlatmaktan ibarettir.
AKTIF değişkeninin 0 nolu biti birinci butona karşılık gelen çıkışın aktif olup olmadığını bize gösterecek.
Programda çıkışları PORTC den verdiğime göre;
AKTIF.0=1 ise PORTC.0=1 demektir. AKTIF.1=1 ise PORTC.1=1 demektir. Bu şekilde devamla AKTIF.7=1 ise PORTC.7=1 demek olur. Tabiiki aktif biti 1 olanları sadece saydırıyoruz Pasif olanlara dokunmuyoruz.
Buyurun bu işe ait program parçası;

'buraya sigorta ayarlarını yazın
DEFINE OSC 4       
CMCON=7
OPTION_REG.7=0

TRISA=0:PORTA=0
TRISB=%11111111:PORTB=0
TRISC=0:PORTC=0
'portb pullup ları aktif edilecek yeni nesillerde WPU veya WPUB ile ediliyor kimisinde OPTION_REG.7=0 verilmesi de gerekiyor

DAK   VAR BYTE[8]   'her bir çıkışın dakika sayacı
AKTIF VAR BYTE 
I     VAR BYTE 
W     VAR BYTE 
KES   VAR byte   'kesme sayacımız 120 defa sayacak                     
TEMP  VAR BYTE 

CLEAR
PAUSE 500
'1 sn=1000 ms dir
'1 dak=60*1000ms=60.000 ms eder.
'her kesme 500 ms 2 kesme 1000 ms ediyor yani 1 saniye bundan 60 tane sayarsak yani 120 kesme sayarsak 1 dakika edecektir.
'o halde her 120 kesmede bir aktif olan çıkışların sayaclarını 1 artırarak (yada eksilterek) 30 dakika sayacı yapacağız.
'biz önce dakika sayacağız. bunun için her kesmemiz 500 ms olduğuna göre 1 dakika için 60 *
BASLA:

      'HER BİR KESME 500 MS GECİKME YARATACAK
       TMR1H=$0B:TMR1L=$DC  'timer'a ön yükleme değeri verdik  'her kesme 500ms süre alıyor.
       T1CON=%00110001      'bölme oranı 1/8 ve timer1 aktif edildi
       PIR1.0=0             'Kesme bayrağı sıfırlandı
       KES=120              '120 tanesi 1 dakika edecek       
SAY:
       TMR1H=$0B:TMR1L=$DC:PIR1.0=0     
       while PIR1.0=0
         for I=0 to 7
           IF PORTB.0[I]=0 AND AKTIF.0[I]=0 THEN 'BUTONA BASILMIŞ VE BUTONA AİT ÇIKIŞ PASİF İSE
              AKTIF.0[I]=1
              DAK[I]=30 ' O GİRİŞE AİT SURE SAYACINI 30 DAKİKAYA AYARLADIK
              PORTC.0[I]=1 'BUTONA KARŞILIK GELEN ÇIKIŞ HIGH YAPILDI
           ENDIF
         NEXT   
       WEND  'KESME OLUŞUNCAYA KADAR BEKLE
       IF AKTIF>0 THEN kes=kes-1
       IF KES>0 THEN SAY 'HENÜZ 1 DAKIKA DOLMADI TEKRAR SAY     
'bu noktada 1 dakika dolmuş demektir o halde aktif olan çıkışların sayaclarına bakacağız
       FOR W=0 TO 7   '8 TANE BIRIMLİK INDEX DÖNGÜSÜ SAYIYORUZ         
         IF AKTIF.0[W]=1 THEN  'ŞAYET AKTİF DEĞİŞKENİ BİTLERİNDEN BİRİSİ HIGH İSE (AKTİF DEMEKTİR)
            TEMP=dak[W]     'O AKTİFE AİT DAKİKA SAYACINI TEMP DEĞİŞKENİNE AKTARIYORUZ
            TEMP=TEMP-1        'SÜRE SAYACINI BİR ARTIRIYORUZ.           
            IF TEMP=0 THEN     'SÜRELERDEN AKTİF OLAN SIFIRLANMIŞ İSE 30 DAKİKA GEÇMİŞ DEMEKTİR
               PORTC.0[W]=0    'O HALDE ONA AİT ÇIKIŞI PASİF YAPALIM
               AKTIF.0[W]=0    'AKTİFLİĞİ BİTTİĞİNE GÖRE ONUDA PASİF YAPALIM
            ENDIF   
            DAK[W]=TEMP      'SÜRE HENÜZ DOLMADI YENİDEN DAKİKA DEĞERİNİ DEĞİŞKENİNE YERLEŞTİRELİM
          ENDIF
        NEXT
        KES=120 'KESME ADEDİ TEKRAR 1 DAKİKAYA EŞİTLENDİ
        goto say  'SAYMAYA DEVAM EDELİM


Ete

NOT: Bazı kusurlar varmış onları düzelttim. Yükleyenler var ise yeniden yüklemelerini öneriyorum.
Sistemi 16F628 li bir devrede 5 butonlu olarak denedim sorun yok çalışıyor.

ete

Bu sistemde kodu çözebilenler butonlar arasındaki süre hassasiyetinin 1 dak olduğunu yada olacağını anlamışlardır.
Çünki 1 dak dolmadan basılan bütün butonların süreleri aynı dakika içinde değerlendirilmektedir. Daha hassas bir sistemde saniye bazında çalışma gerekir. Bunun için TMR1 sayacını yine 500 ms lik iki dilimde çalıştırıp 1 sn lik süreyi elde etmek ve her 1 sn dolduğunda da basılan butonlara ait saniye sayacını çalıştırmak gerekir. Basılmış butonların saniye sayaçları 60 olduğunda sayac tekrardan sıfırlanıp dakika sayacı bir artırılmalı (programda eksilme yönetemi kullandık) ve böylece sürenin dolduğu yine dakika sayacının değerinden anlaşılmalıdır.
İlişikteki örnekte 16F628A ile yapılmış bir sistem göreceksiniz. Bu sistemde toplamda 7 butonlu bir sistem çalıştırılmaktadır.
MCLR pini çıkış olamadığı için onu atlayıp kullanıyoruz bu nedenle olması gereken 8 butondan bir eksik sistem.
Aslında PORTA yı giriş ve PORTB yi çıkış olarak kullansak 8 butınlu sistemde çalıştırılabilir. Tabiiki bu durumda PORTA ya bağlanmış butonlara pullup direnci eklemek gerekecektir.
Önceden de belirttiğim gibi bu toplu zaman takibi sistemine bir örnektir. Pek çok yerde kullanılabilir. Örneğin çok alarmlı bir saatte çoklu ve zamana bağlı açma kapatma işlemlerinde kullanılabilir.

Dosya ilişiktedir. Program PBP 3.1 derleyicisine göre yazılmıştır. 2.60 versiyonu kullananları yalnızca Config satırlarında yer alan;
#CONFIG  komutu yerine ASM ve
#ENDCONFIG komutu yerine ENDASM yazmaları yeterli olacaktır.

Ete

onurinci

Sil_Buton.pdsprj ....hocam galiba sizde isis versiyonunu yükselttiniz,eski versiyon DSN dosyası olarak export edebililirmisiniz ?

ete

Hem 7 hem 8 versiyonları kullanıyorum. Ancak versiyon7 beni sinir ediyor. Mümkün olduğunca kullanmamaya çalışıyorum. Sorun yeni bir devre oluştururken ilk seçtiğin komponent için kırk saat bekliyor sonra serbest kalıyor. Diğerinde hiç bir sorun yok. Bu nedenle bu seferde öyle yaptım.
Basit bir devre yeniden çizmedim artık ilişikteki PDF dosyasından şemaya bakabilirsiniz.

Ete


Powered by EzPortal