avatar_medes

sayac komutu

Başlatan medes, 30 Eylül 2011, 21:16:03

medes

ete hocam
Bir zaman rolesi yapmaya çalıştım sizin 4 haneli sayıcıdan faydalandım artı saydırma butonu vardı bende eksi saydırma butonu ekledim ve iki hane olarak 99 kadar sayıyor ve sıfıra geçiyor buraya kadar gayet güzel. Ben ayrıca bir sayac daha ilave ettim bildiğim kadarıyla programdan istenen diplayda ayarladığım bir sayı örnek=66 sayısı  ayarlandığında sayac=66 oluyor start tuşuna basılınca role=1 oluyor ardından sayac1 saymaya başlıyor sayac1=66 olunca  sayac =sayac1 birbirine eşit olunca role bırakıyor fakat aşağıda yaptığım yazılım çalışıyor fakat sayac1 sanki sabit bir çalışma yapıyor displada ayarladığım zamanı bulamıyorum mesela displayda sayac 10'na ayarlı iken role kapanma zamanı display'da sayac=99'a  ayarladığım zamanla aynı sanki burada bir hatamı var hocam yoksa yanlış bir seçimmi yaptım.saygılarımla
PORTA=0:TRISA=%00011000
PORTB=0:TRISB=%10000000
CMCON=7
OPTION_REG=%00000100 'Pull up dirençleri AÇIK (PORTB.7 için) - Bölme oranı 1/32.
'bölücü ayarlaması 000=1/2, 001=1/4 , 010=1/8 , 011=1/16 , 100=1/32 , 101=1/64 , 110=1/128,
'111=1/256
INTCON=%00100000 'Kesmeler aktif ve TMR0 kesmesi aktif
'-----------------------------------------------------------------
@ DEVICE pic16F628A 'işlemci 16F628
@ DEVICE pic16F628A, WDT_ON 'Watch Dog timer açık
@ DEVICE pic16F628A, PWRT_ON 'Power on timer açık
@ DEVICE pic16F628A, PROTECT_OFF 'Kod Protek kapalı
@ DEVICE pic16F628A, MCLR_off 'MCLR pini kullanılMIYOR.
@ DEVICE pic16F628A, INTRC_OSC_NOCLKOUT 'Dahili osilatör kullanılacak
'-----------------------------------------------------------------
DEFINE OSC 4
'-------------------------------------------------------------------------
SAYAC var WORD 'Sayılacak değerleri tutacak olan değişkenimiz
SAYAC1 var WORD
SIRA var BYTE 'display gösterim sırası
BIRLER var BYTE 'sayımızın birler hanesi
ONLAR VAR BYTE 'sayımızın onlar hanesi
YUZLER VAR BYTE 'sayımızın yüzler hanesi
BINLER VAR BYTE 'sayımızın binler hanesi
I VAR BYTE 'döngü değişkenimiz
SAYI VAR BYTE 'çevirme değişkeni
X VAR BYTE 'ara değişken
SYMBOL Disp0=PORTA.0 ' birler hanesi ortak uç
SYMBOL Disp1=PORTA.1 ' onlar hensie ortak uç
SYMBOL Disp2=PORTA.2 ' yüzler hanesi ortak uç
SYMBOL Disp3=PORTA.3 ' binler hanesi ortak uç
SYMBOL TUS =PORTB.7 'Buton
SYMBOL TUS1 =PORTA.4
SYMBOL START=PORTA.3
SYMBOL ROLE=PORTA.2
PAUSE 100
SAYAC=0
SAYAC1=0
INTCON.7=1 'tüm kesmeler açık
TMR0=99
ON INTERRUPT GoTo KESME 'kesme oluşursa KESME adlı etikete git.
BASLA:
'**************************************************************
IF START=0 THEN    'START'A basıldığında
   TOGGLE ROLE     'role çeker 
   IF ROLE=1 THEN  'role=1 ise
   GOTO SAYDIR     'saydır komutuna git
   ENDIF
    ENDIF
'*************************************************************
IF TUS=0 then
GOSUB DELAY
SAYAC=SAYAC+1
IF SAYAC>99 then SAYAC=0
while tus=0:wend
ENDIF
IF TUS1=0 then
GOSUB DELAY
SAYAC=SAYAC-1
IF SAYAC>99 then SAYAC=0
while TUS1=0:wend
ENDIF
X=SAYAC DIG 0 :GOSUB AL:BIRLER=SAYI
X=SAYAC DIG 1 :GOSUB AL:ONLAR=SAYI
GOTO BASLA
AL: LOOKUP X,[63,6,91,79,102,109,125,7,127,111,99,57],SAYI :RETURN
DELAY:
for I=0 to 35000
PAUSEUS 5
Next
RETURN
DISABLE
KESME:
SIRA=SIRA+1:IF SIRA>1 then SIRA=0 'hangi hanenin ekrana verileceğini belirliyor
IF SIRA=0 then 'ilk hane yani birler hanesi ise
DISP1=0 'önce bir önceki gösterime ait display kapatılıyor
PORTB=BIRLER 'Haneye ait bilgi porta (segmentlere) veriliyor
DISP0=1 'Display açılıyor.
ENDIF
IF SIRA=1 THEN
DISP0=0
PORTB=ONLAR
DISP1=1
ENDIF

TMR0=99 '5 ms lik süreyi yaratacak olan TMR0 değeri registere yükleniyor.
INTCON.2=0 'TMR0 Kesme bayrağı sıfırlanıyor
RESUME
ENABLE
'************************************************************
SAYDIR:   'displayda ayarlı olan sayı örneğin=display sayac=66 ise
          'sayac1 samaya başlar sayac1=66 olduğunda ıf sayac and sayac1 then ile
    SAYAC1=0 'karşılaştırma yapılarak eşit ise role=0 olur
    WHILE SAYAC1<255  'burada sayac1 sabit bir zaman içinde roleyi kapatıyor
     PAUSE 10         'olması gereken displayda ayarlı olan sayac'la eşit olduğu
    SAYAC1=SAYAC1+1   'zaman kapatmalı
    WEND     
    IF SAYAC AND SAYAC1 THEN ROLE=0 'karşılaştıma
    GOTO BASLA
END

ete

#1
Mesajlarda kod verilince Kod Tag (#) işaretli buton kullanmanız gerekiyor. Bu şekilde hemkod rahat okunabilir hemde yerden tasarruf etmiş oluruz. Ben senin yerine düzelttim.

Soruna gelince istediğinle yazdığın kod bence uyuşmuyor. Doğru olan anlattıklarına bakarak ekandaki sayac değeri ile sayac1 değeri eşitlenince röle bırakması ve programında Basla etiketine dönmesi gerekir. Sen de bunlar aşağı yukarı oluyor ama sayac1 değeri 255'e gelince program Basla etiketine dönüyor. İşin bu kısmını düzeltmek gerekir. Ancak Sayac değerinin sıfır olma ihtimalinide göz ardı etmemek gerek sanırım. Düzeltilmiş kod aşağıdadır.
Ayrıca SAYDIR isimli alt programı Kesme etiketinden önce bir yere yerleştir.

SAYDIR:
    SAYAC1=0 'karşılaştırma yapılarak eşit ise role=0 olur
    IF SAYAC=0 then
        ROLE=0
        Goto Basla
     endif
    WHILE SAYAC1<SAYAC 
     PAUSE 10         'olması gereken displayda ayarlı olan sayac'la eşit olduğu
    SAYAC1=SAYAC1+1   'zaman kapatmalı
    WEND     
    Role=0 'program bu satıra gelince SAYAC=SAYAC1 olmuş olacak mecburen
    GOTO BASLA
END


medes

ETE HOCAM
program güzel oldu yalnız start tuşuna bastığımda biraz geç bıraktığım zamana kadar role çekilmiş olarak bekliyor buda istenmeyen durum acaba start tuşuna bastığımda değil bıraktığım
zaman role çeksin istiyorum. bu mümkün olabilirmi acaba. ben bir türlü yapamadım .saygılarımla

ete

İşleri biraz karıştıracaksın gibime geliyor ama madem öyle istiyorsun;
Tuş kontrolünü aşağıdaki şekilde değiştir.
IF START=0 THEN    'START'A basıldığında 
  while START=1:WEND
   TOGGLE ROLE     'role çeker 
   IF ROLE=1 THEN  'role=1 ise
   GOTO SAYDIR     'saydır komutuna git
   ENDIF
    ENDIF

Ete

medes

#4
ete hocam
ben işleri karıştırmak için değil daha güzel olsun programda problem olmaması için birazda öğrenmek için sizleri rahatsız ediyorum. hocam ben sizden daha önce bu tür kodların kullanmayı öğrenmiştim hocam bu kodları sayenizde çok iyi kullanıyorum .allah sizden razı olsun. hocam bu vemiş olduğunuz kodu ben denedim olmadı nedeni start tuşuna bastığımda rolenin çekmemesi lazım. bu kodu kullandım hemde aynı şekilde  yine role çekiyor ve ben start tuşundan elimi çekmediğim süre içindede role çekmiş olduğundan zamanlama süresi uzamış oluyor benim istediğim start tuşuna bastım role çekmeyecek ne zaman elimi tuştan çeker isem o zaman role çeksin ve zamanlama başlasın daha anlaşılır olarak start tuşuna bastığımda yükselen kenarda değil düşen kenarda role çeksin istiyorum. herhalde böyle daha anlaşılır oldu . saygılarımla

ete

Tuş kontrolü yanlış olmuş şöyle değiştir.
while START=0:WEND

ete

medes

#6
ete hocam
program şimdi normale döndü gayet güzel çalıştı. hocam bir sorum daha olcak örneğin program
çalışır iken program etkilenmeden herhangi bir port'un birinde belirli aralıklarda yanıp sönen
bir led koymak istediğimiz zaman nasıl bir program ilave etmemiz lazım devre üzarinde güzel bir
görünüm oluyor birde devrenin çalışmaya hazır bir imac veriyor ben bildiğim şekilde yaptığımda
çalışan diğer program etkileniyor. diğer çalışan programlar etkilenmeden bir ledin yanıp sönmesi
nasıl bir uygulama yapılabilinir.saygılarımla

ete

Kesme etiketinde ikinci bir sayaç çalıştır. Sayac her değer artışı 5ms olacaktır. Buna göre led'i her 150 ms de bir yakıp söndürmek istersek
LEDSAY=LEDSAY+1
IF LEDSAY=30 then
  TOGGLE LED
   LEDSAY=0
ENDIF

Bu kod ile istediğini yapabilirsin. Yanıp sönme hızını artırmak için 30 rakamını küçültmen , hızı çoğaltmak içinde 30 rakamını artırman gerekiyor.

Ete

medes

Ete hocam
hayırlı günler dilerim uygulama gayet güzel çalıştı yalnız bu program işi öyleki çok deneyim çok okumak hataların nereden kaynaklandığını anlamaya çalışmak gerekiyor en basit bir hata insanı
çok uğraştırıyor.bayağı bi şeyler öğreniyoruz sayenizde öyleki led yak söndür yazılımını programa
ilave yaptım. fakat bir türlü çalıştıramadım. bayağı bir süre sonra aklıma geldi sizin bir arkadaşa
sayaçları basla komutundan önce sıfırlanması gerektiği tanımlamalardan önce yapılır ise bazen işe yaramadığını yazmıştınız aklıma geldi  basla komutundan önce sayacı sıfırladım başladı çalışmaya
teşekkür eder saygılarımı sunarım.

ete

Bazı şeyler direk akla gelmez. Ancak programı çalıştırınca bir şeylerin yanlış olduğu görülür ve hemen hata aramaya başlanır. Senide yaptığın gibi ne yapman gerektiğini anlar ve düzeltirsin.
Elbette sayac değeri devre çalışmaya başladığı zaman sıfırdan başlamalıdır.  Normalde aksine bir komut olmadığı taktirde sayac değeri ilk başlangıçta sıfır olmalıdır. Ancak işlemci bazı adresleri kendi işleri için geçici olarak kullanır ve orada bu kullanımdan kalan bir değer (rastgele bir değer) yer alabilir. Bu durumda sayac değeri şayet 30 dan büyük ise progamın led yakıp söndürme kısmı aksayacaktır. Çünki en fazla 30 olmasına müsaade etmişiz. Dolayısıyla değeri başlamadan önce sıfırlarsan sorun kalmamış oluyor.

Ete

Powered by EzPortal