18F452 Sayıcı Devresi HEX Problemi

Başlatan Rhyme, 14 Nisan 2012, 09:48:52

Rhyme

Arkadaşlar merhaba,

18f452 ile basicde yazılmış bir programla 4 tane butondan gelen ( Sıfırla - Başla - Yukarı - Aşağı ) bilgilerle 5 er dakikalık artma azalma ile geri sayıcı devre yapıyorum,
dün devreyi bread board a kurdum hex dosyasını gönderdim, LCD de sadece başlangıçta çıkan Zamanı Ayarla yazısı sürekli dönüyor hiç bir şekilde butonlar çalışmıyor acaba hatam nerde ?

Bu arada devreye harici kristal osilatör bağladım 4 Mhz.

2. Problem ; Bu program 5 dakikadan geri sayacak ben ayarladım fakat 5 dakikaya ayarlıyorum 5:59 dan geri sayıyor bunada el atabilecek bir arkadaş varsa çok sevinirim.

Program :

     
  DEFINE LCD_RSREG PORTB
  DEFINE LCD_EREG PORTB
  DEFINE LCD_RWREG PORTB
  DEFINE LCD_DREG PORTB
  DEFINE LCD_RSBIT  4
  DEFINE LCD_EBIT  5
  DEFINE LCD_RWBIT  6
  DEFINE LCD_DBIT  0
  DEFINE LCD_BITS  4
  DEFINE LCD_LINES  2
        
     saat  var      byte
     minute  VAR     word                       
    second  VAR     byte          ' Define second variable
    ticks   VAR     byte          ' Define pieces of seconds variable
    i       VAR     WORD          ' Debounce loop variable     
        minute = 0
        second = 0
        ticks = 0
        I=0
       
';********************************************************************************************
        TRISC=0
        TRISB=0
          TRISD=%00001111
        PORTD=0
       PORTB=0   
        PORTC=0
        PORTD.7=1
' ;*************************SIFIR**********************************************
SIFIR:
 
LCDOUT $FE,1
   PAUSE 100
       minute = 0
        second = 0
        ticks = 0
        saat=0
        I=0
'  ;****************************************************************************

'     LCDOUT $FE,$40,4,0,14,4,4,4,14,0
     LCDOUT $FE,$86,"ZAMANI"
      LCDOUT $FE,$C3,"AYARLAYINIZ"
    '
     PAUSE 2000

MAINLOOP1:   
LCDOUT $FE,1
' ;*************************ANA PROGRAM*****************************************
       LCDOUT $FE,$80,"Dakika = ",dec2 minute
'      LCDOUT $FE,$C0,"Saniye = ",dec2 second
'       LCDOUT $FE,$80,"saat=",dec2 saat
   mainloop:
        If PORTD.0 = 0 Then SIFIR
        If PORTD.1 = 0 Then sil
        If PORTD.2 = 0 Then decSN
        If PORTD.3 = 0 Then incSN
       
       


  Goto mainloop
';****************************ARTIRMA************************************
IncSN:
        WHILE   PORTD.3 = 0
        WEND
        minute = minute + 5
'         If minute= 60 Then
'         minute = 0
'           saat = saat + 1
'        Endif
       
'        If saat = 24 Then
'         saat = 0
       
'              Endif
        GOTO ZAM

';**************AZALTMA*************************************
DecSN:
     
       WHILE   PORTD.2 = 0
        WEND
        If minute = 0  Then
         minute=0
         ELSE
        minute = minute - 5
        ENDIF
       
'DAK:       
'           If saat =0 or saat =%11111111 Then
'         saat = 24
       
'              Endif
'          Goto ZAM
';*****************************TUS GEÇİKMESİ*************************       
ZAM:
       IF  minute>=100 THEN
       LCDOUT $FE,$80,"Dakika = ",dec3 minute
       ELSE
       LCDOUT $FE,1
        LCDOUT $FE,$80,"Dakika = ",dec2 minute
        ENDIF
'         LCDOUT $FE,$C0,"Saniye = ",dec2 second
'         LCDOUT $FE,$C0,"Saniye=",dec2 second
       
        For i = 1 to 20
           PAUSE 15                    
        Next     

          Goto mainloop 
             
';*******************************KONTROL**********************************
sil:
LCDOUT $FE,1     
KONT:
       If second=0 and minute = 0  Then KONT_SAY
basla:
         IF  minute>=100 THEN
        LCDOUT $FE,$80, "DAKiKA = " ,dec3 minute
        LCDOUT $FE,$C0,"SANiYE = " ,dec2 second
        ELSE
        LCDOUT $FE,1
        LCDOUT $FE,$80, "DAKiKA = " ,dec2 minute
        LCDOUT $FE,$C0,"SANiYE = " ,dec2 second
        ENDIF
         If  minute = 0 AND SECOND =0 Then KONTROL
        second = second - 1
       
        FOR I=0 TO 100
      PAUSE 9 
        If PORTD.0 = 0 Then SIFIR
        NEXT i
        If second >= 60 Then
         second = 59
         endIF
         If second =0 Then
         If  minute = 0 AND SECOND =0 Then BASLA
         Minute = minute - 1
         
      Endif
       GOTO BASLA 
       
KONT_SAY:
        LCDOUT $FE,$80, " DAKiKA "
         LCDOUT $FE,$C0,"AYARINI YAPINIZ"
       PAUSE 1000
         Goto mainloop1
KONTROL:     
       PORTD.4=1
      PAUSE 5000         
       PORTD.4=0
    Goto mainloop1      
       
        END

Rhyme


Rhyme

Arkadaşlar donanım problemini çözdüm, sadece 5 dk dan geri sayma sıkıntısı kaldı isteyenle devreyi paylaşabilirim...

ete

Basit bir döngü ile zaman saymaya çalışmışsın ama hassas bir zaman ayarı yapılması zordur bunu biliyorsundur sanırım.
Bir sayac geri sayma yapıyorsa ve bu saydığı zaman ise önce her 1000 ms de bir sn değeri bir eksiltilir. Saniye daima 59 dan başlar.
Ama 5:00 şeklinde ki bir zaman değerinden 1 saniye eksiltince sn=59 olur ama aynı şekilde Dakika da 4 değerine inmesi gerekir.

Ekisltme komutlarının olduğu yerde komutların sıralaması çok önemlidir.
Saniye=Saniye-1 komutunda Saniye değeri önceden sıfır ise bir çıkartılınca saniye değeri 255 olur. Bu konumda ;
IF Saniye=255 then
   saniye=59
   dakika=dakika-1
   IF dakika=255 then dakika=0 demek ayrıca gerekir.
Endif

Bu satırları programa eklerseniz sistem doğru çalışacaktır.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

Rhyme

Dostum ilgin için sağol ama programa dediğin satırları tam yerleştiremedim tekrar yardımcı olurmusun ?

Teşekkürler

Rhyme

Konu güncel ve ACİL yardımcı olabilecek var mı ?

BAHAR

Çok karmaşık kodların var ve birden fazla problem olabilir. Kaynak kodunu proteus dosyası ile birlikte verirsen programı baştan takip etmek yerine proteus'ta deneyerek problemi kolayca bulabiliriz.

ete

#7
Başla ile KONT_SAY etiketleri arasındaki satırları aşağıdaki şekilde değiştir.
Öncelikle Minute değişkenini Byte olarak değiştir. Word olması gerekmiyor. İllaki word oalrak kalsın dersen aşağıdaki satırlarda yer alan;
IF Minute=255 THEN komut satırı,  IF MINUTE=65535 THEN şeklinde değiştirilmelidir.
basla:
         IF  minute>=100 THEN
        LCDOUT $FE,$80, "DAKiKA = " ,dec3 minute
        LCDOUT $FE,$C0,"SANiYE = " ,dec2 second
        ELSE
        LCDOUT $FE,1
        LCDOUT $FE,$80, "DAKiKA = " ,dec2 minute
        LCDOUT $FE,$C0,"SANiYE = " ,dec2 second
        ENDIF       
       
        FOR I=0 TO 100
      PAUSE 9 
        If PORTD.0 = 0 Then SIFIR
        NEXT i
        second = second - 1
        IF SECOND=255 THEN
          SECOND=59
          Minute=minute-1
          IF minute=255 then minute=0
        ENDIF   
                
        If  minute = 0 AND SECOND =0 Then BASLA
       GOTO BASLA

Programda bir sürü saçmalık mevcut.
Mesela;
BASLA satırından bir kaç satır sonra şu komut satırı mevcut;
If  minute = 0 AND SECOND =0 Then KONTROL
Birkaç satır sonra ise,
If  minute = 0 AND SECOND =0 Then BASLA  komut satırı var. Bunların ikiside aynı şartı kontrol ediyor ama farklı yerler yönlendiriyor programı.
İlk komut satırını bu nedenle sildim. Bence mantıksız olan o satır.

Programın tamamında fazlalık yada eksiklikler mevcut. Mesela Ayar işlemlerinde Second=Second-5 deniliyor ama Second  değeri eksile eksile sonuçta yeniden 255 değerine dönecektir bunu kontrol eden bir şey göremedim. Muhtemelen aynı şey dakika içinde mevcut.

Ete

Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

Rhyme

Ete hocam öncelikle çok teşekkür ederim.

Arkadaşlar program saçma ve karışık değil aslında aynı kod dizisi üzerinde bir kaç kombinasyon denedik, micro code studio da çalışıyorum orda yazılan çoğu satır işlev görmüyor aslında o yüzden size karışık geliyor.

Bu devre orjinalinde her butona bastığında 1 sn artarak gidiyordu, ben 5 dk lık olarak ayarladım, yada ayarlamaya çalıştım :)

devreyi düzenlenmiş baskı devre+kodlar+simülasyonunu ihtiyacı  olanlarla paslaşabilirim.

Herkese çok teşekkürler iyi çalışmalar.

Rhyme

Hocam bu seferde devre enteresan çalışıyor..

5 Dakikaya ayarlıyorsun zaten hızlı sayıyor 5 dk yı 4 dk 30 saniyede saydı, 2. si 0:59 saniyeden geri saymaya başlıyor 00:00 dan sora biteceğine 00:59 a geri dönüyor devre+ek dosyalarını yükledim göz atabilirmisiniz?


http://turbobit.net/70yaf0ah8pj1.html

ete


Pause ile elde edilen bir saniye sayacından ne kadar hassasiyet bekleyebilirsinki?. Elbette 5 dakikayı ya daha az yada daha fazla zamanda sayacaktır.
Saniye süresini aşağıdaki döngü belirlemektedir.
FOR I=0 to 100
  Pause 9
....
Next
şeklindeki döngü dikkat edersen tam tamına 9 x 101=909 ms lik bir gecikme yaratır. Buna birazda komut gecikmesi eklersen yaklaşık gecikme süresi 910 ms dolayındadır. Halbuki 1 sn=1000 ms dir o halde senin sistemin 1sn yi 1000 ms yerine 910 ms dolayında tamamlamaktadır. Bu durumda döngü sayısını artırarak sn değerini 1000 ms olarak yakalamaya çalışman gerekiyor. Örnek verecek olursak;
110*9=990 ms ve komut gecikmeleri ile birlikte 995 ms dolayında bir gecikme yaratırki bu gerçeğe hiç olmazsa biraz daha yakın.

Programın süre bitiminden sonra ne yapması gerektiğini hiç bir yere yazmamışsın.
Aşağıdaki satır süre bitiminde programı yeniden başla satırına yönlendiriyor.
If  minute = 0 AND SECOND =0 Then BASLA
Bunun yerine;
If  minute = 0 AND SECOND =0 Then KONT_SAY
yazarsan süre bitiminde program yeniden süre girilmesini isteyerek işlemi baştan başlatabilir.
Farklı bir şey istiyorsan artık kendin ayarlamalısın. Programı yazdınız yada birisi yazdı ama pek programa hakim değilsiniz. Öyle anlıyorum.
Yoksa programın neden hızlı saydığını ve neden süre bitiminde aynı şeyi tekrarladığını anlamanız kolay olurdu.

Ete

Bilgi hazinedir paylaştıkça büyür.            http://etepic.com