avatar_elektro77

arka ışık kapatma algoritması

Başlatan elektro77, 10 Eylül 2019, 00:04:18

elektro77

Program icinde 30 saniye boyunca hic bir islem yapilmadiginda lcd arka isigini nasil bir algoritma ile kapatiyoruz. Ustalarimin bilgisine ihtiyacim var.
Aslinda Usartla calisan ve bilgi girisi oldugunda islem yapan bir alici yazilimim var. 30 saniye boyunca Bilgi girisi olmadiginda, atadigim bir bitin 0 olmasini ve bu bite bagli degiskenlerinde 0 olmasi gerekli. Fakat beklenen sureyi sayarken bilgi gelirse bilgiyi islemeli. Bunu nasil yapabilirim. saat 12 oldu ve ben sabahtan beri elime kagit kalem aldim hala bunu yazamaya calisiyorum. Yardimci olacak ustalarima simdiden tesekkur ederim. Gerekirse yazilimi buraya atarim. su an bilgisyar basinda degilim.
"Eğer bir konuyu öğrenmek istiyorsan o konunun öğretmeni ol; daha iyi öğrenmek istiyorsan o konuda bir kitap yaz; daha da iyi öğrenmek istiyorsan yazdığın kitabi oku"

furkan41

arka_isik_kapat diye bir dğeişken oluştur. bunu iş yaptığın tüm fonksiyonlar içinde veya  sorgu deyimlerinde sıfırla. bir timer kur ve her 1 saniyede bu değişkeni 1 attırsın. hep arttırsın. eğer arttırma yaparken bir işlem olursa otomatik olarak işlem yapılırken değişkende sıfırlanacağından istediğin olacak. sonsuz döngü icinde veya kesme icinde arka_isik_kapat değişkenini sorgulatırsın 30 olmuş ise. arka ışığı kapatırsın.

ete

Bu işi iki şekiilde yapmak mümkün.
Metod-1:
Programda Basla-Goto basla arasını bir timer1 sayac döngüsü içine alırsın. Sayac süresi 500 ms olur ve döngüden 60 tane saydırınca 30 sn geçmiş olacaktır.
Öncel,ikle bilgi giriş noktalarına Timer önyükleme değerleri yeniden verilerek saaycın aşmaya uğraması engellenir. Ama hiç bilgi girişi olmaz ise aşma meydana gelir ve PIR1.0 biti (taşma kesmesi bayrağı) 1 olur. İşte bu noktada sende ışığı söndürürsün.
Zaman döngüsü while PIR1.0=0 .... wend aralığında yaptırılır. Öncesinde Timer ön yükleme değerleri verilir. Çalışma frekansın belli olmadığı için ön yükleme detaylarını veremiyorum. Ama picMulticalc isimli kısa programdan yardım al sana her şeyi verir.

Metod-2:
Programın Basla - Goto Basla aralığını zaman olarak ölçersin. Bunun için bir kereliğine, Tmr1 sayacını kurar ve GOTO BASLA ya gelince Timer1 değerini alırsın. Şayet PIR1.0=1 ise taşma olmuştur sayac yetersizdir. Bu durumda sayacın bölme oranını 1/2 yaparak aynı işi tekrarlarsın okuduğun sonucu 2 ile çarparsın. Yine PIR1.0=0 ise bu defa bölme oranını 1/4 alırsın ve sonucu 4 ile çarparsın.
Diyelimki bir şekilde süreyi ölçtün. Sonrası basit. 30 sn için o döngü süresinden kaç tane gerekiyor ise sayac=xxxx diyerek programa başlarsın. Her Goto Basla satırına gelmeden önce Sayac=sayac-1 dersin ve sayac=0 olmuşmu sorgularsın. Bu metod da da her bilgi geldiğinde Sayac=xxx şeklinde sayac değerini yenilersin. Sonuçta sayac=0 olmuş ise 30 sn geçmiş demektir ve arka ışığı söndürürsün.

Bu dediklerimi program dili ile de vermek isterdim ama çok fazla kod yazmak gerekiyor hem programcı dediğin bu anlatıları anlaması ve onları koda dönüştürmesi gerekir değilmi?

Ete

elektro77

#3
Alıntı yapılan: ete - 10 Eylül 2019, 09:11:22Bu dediklerimi program dili ile de vermek isterdim ama çok fazla kod yazmak gerekiyor hem programcı dediğin bu anlatıları anlaması ve onları koda dönüştürmesi gerekir değilmi?

Ete

evet anlaması lazım Hocam. ben zaten hiç bilgim olmadan sadece mantık yürüterek buna benzer bir şeyi çalıştırdım ama tımer kesmesi ile değil. benim çalıştırdığımda sayma sırasında işlem yapmada sıkıntı veriyor.  örnekleyerek anlatırsanız inanın daha çok faydası olacaktır.Benim anlama şeklim örnekleme üzerinden.timer çalıştırma ile ilgili dersiniz varsa onun linkinide alabilirim. Ve ben daha önce hiç tımer çalıştırmadım.
çalışma frekansım 8 mhz. mikrodenetleyici ise 16f877A.
"Eğer bir konuyu öğrenmek istiyorsan o konunun öğretmeni ol; daha iyi öğrenmek istiyorsan o konuda bir kitap yaz; daha da iyi öğrenmek istiyorsan yazdığın kitabi oku"

elektro77

#4
bir yerlerden 4 sayfalık bir döküman bulup timer1 kesmesi için bir şeyler okudum. Ama 16f877a da timer 1 kesmesini aktif etmek için kullanılan 'T1CON=%00100001 ' timer için ayarlar kodunu asıl programıma yerleştirdiğimde programım çalışmıyor.
"Eğer bir konuyu öğrenmek istiyorsan o konunun öğretmeni ol; daha iyi öğrenmek istiyorsan o konuda bir kitap yaz; daha da iyi öğrenmek istiyorsan yazdığın kitabi oku"

elektro77

#5
bu işi yapmak istediğim ana yazılımım aşağıdadır.
@ DEVICE PIC16f877A
@ DEVICE PIC16f877A, WDT_OFF
@ DEVICE PIC16f877A, BOD_ON
@ DEVICE PIC16f877A, PWRT_ON
@ DEVICE PIC16f877A, PROTECT_OFF
@ DEVICE PIC16f877A, HS_OSC
'----------------------------------
DEFINE OSC 8
TRISA=%00000000
TRISB=%00000000     
TRISC=%10000000     'RX PİNİ GİRİŞ OLARAK AYARLANDI
TRISD=%00000000
TRISE=%00000000
PORTA=0
PORTB=0
PORTC=0
PORTD=%00001111
PORTE=0
'-------------------------------------------------------------------------------
'CMCON=7  
'INTCON=%11000000
ADCON1=7                   'ADC KANALLARI DİJİTAL YAPILDI - ADC İPTAL
OPTION_REG.7=1            'portB deki dahili PULL-UP lar iptal edildi.
CMCON=7                   'komparatör pinleri iptal hepsi giriş çıkış yapıldı16F876A kullanılırsa bu kod kullanılır
'INTCON = %10100000        'kesme kullanılacak ise bu kod kesme çeşidine düzenlenir.
'ADCON1=%10001110          '7. bit 1 yapıldı 10 bit sonuç almak için.
'option_reg=0               'PORTB Pulluplar etkin.
                           '(Pullup=Portb' nin tüm uçlarını +5V a çekmektir.lojik 1)
'T1CON=%00100001 ' timer için ayarlar
'-------------------------------------------------------------------------------
DEFINE LCD_DREG PORTC    'LCD data bacaklari hangi porta bagli ? 
DEFINE LCD_DBIT 0        'LCD data bacaklari hangi bitten basliyor ?

DEFINE LCD_EREG PORTE    'LCD Enable Bacagi Hangi Porta bagli ?
DEFINE LCD_EBIT 2        'LCD Enable Bacagi Hangi bite bagli ?

DEFINE LCD_RSREG PORTE    'LCD RS Bacagi Hangi Porta bagli ?
DEFINE LCD_RSBIT 1        'LCD RS bacagi Hangi Bite bagli ?

DEFINE LCD_BITS 4        'LCD 4 bit mi yoksa 8 bit olarak ba?ly ?
DEFINE LCD_LINES 4       'LCD Kaç syra yazabiliyor ? 

DEFINE LCD_COMMANDUS 2000 'Command delay time in us 
DEFINE LCD_DATAUS 50 'Data delay time in us   
'----------BU KODLAR USART İLTİŞİM İLE İLGİLİDİR-------------------------------
'DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
'DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
'DEFINE HSER_SPBRG 25  ' 9600 Baud @ 4MHz, 0,16%
'DEFINE HSER_CLROERR 1 ' Clear overflow automatically
'-------------------------------------------------------------------------------
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
DEFINE HSER_SPBRG 12  ' 9600 Baud @ 8MHz, 0,16%
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
'-------------------------------------------------------------------------------
'DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
'DEFINE HSER_TXSTA 20h ' Enable transmit, BRGH = 0
'DEFINE HSER_SPBRG 129  ' 9600 Baud @ 20MHz, 0,16%
'DEFINE HSER_CLROERR 1 ' Clear overflow automatically
'-------------------------------------------------------------------------------    
P       VAR     WORD

SYMBOL GIE  =INTCON.7   'genel interruptları açıyor
SYMBOL PEIE =INTCON.6   'peripheralinterruptları açıyor
SYMBOL RCIE =PIE1.5     'USART Recive interrupt enable bit
SYMBOL RCIF =PIR1.5     'USART Receive interrupt flag bit
SYMBOL SEC=PORTA.0
SEC=0
RCIE=1
PEIE=1
GIE=1

TMR1IF VAR PIR1.0
T1CON=%00110000 ' timer için ayarlar
output porte.0
low porte.0
'ANA:
'low portd.1
'IF PIR1.0=1 then ' timerin degerinin 65535 oldugu anda portd.1 i high yapar
'PIR1.0=0
'high portd.1
'pause 200
'Endif
'goto ANA

'Üstteki programda ; TIMER1 sürekli olarak 0 dan 65535'e kadar saymaktadır ,
'TMRIF değişkeni TIMER1 65535 oldugu zaman 1 , 0 ile 65534 arası olduğu zaman 0
'değerini alır . TMRIF 1 olduğu anda portd.1 200ms liğine high olmaktadır .
'Kaç saniyede TIMER1 0 dan 65535'e ulaşıyo sorusunun cevabı ise , kullandığınız
'picin dahili ve harici osilatörüne göre değişir. Uygulamamızda 4MHz lik 16F877
'kullandığımızı var sayalım.

'-------------------------------------------------------------------------------

LCDOUT $FE,1'LCD Yİ TEMİZLER VE HAZIR KONUMA GETİRİR
PAUSE 200

ON INTERRUPT GOTO INT 'RX PİNİNE VERİ GELİRSE PROGRAMI KESER VE VERİYİ İŞLER.


BASLA:
low porte.0
IF PIR1.0=1 then ' timerin degerinin 65535 oldugu anda portd.1 i high yapar
PIR1.0=0
high porte.0
pause 200
Endif
'*******************************************************************************
'*******************************************************************************
'LCDOUT $FE,$8E,#BILGI,"   "
lcdout $FE,$CE,#GIDECEKBILGI,"  "
IF BILGI=0 THEN BASLA
'IF BILGI=14 THEN
'GOSUB SISTEMRESET
'BILGI=0
'GOTO BASLA
'ENDIF

'-------------------------ÜNİTE SECME BÖLÜMÜ------------------------------
IF BILGI=4 THEN 
GIDECEKBILGI=4
GOSUB GONDER
ENBB=1:ENBC=1:ENBD=1'onceki secilmiş unıteyı pasif eder secilen unıteyi aktif eder
pause 10                 
 ENBA=0
GOSUB MOTORSIL'unıte değiştirildiğinde onceki unıtede aktif olan motor pasif edilir.
BILGI=0'burada bilgi sıfırlanır ve program başa döner. tekrar bilgi gelinceye kadar hazırda bekler
ENDIF

IF BILGI=8 THEN
GIDECEKBILGI=8
GOSUB GONDER          
ENBA=1:ENBC=1:ENBD=1
pause 10   
 ENBB=0
GOSUB MOTORSIL
BILGI=0
ENDIF

IF BILGI=12 THEN
GIDECEKBILGI=12
GOSUB GONDER          
ENBA=1:ENBB=1:ENBD=1
pause 10                
 ENBC=0
GOSUB MOTORSIL
BILGI=0
ENDIF

IF BILGI=16 THEN
GIDECEKBILGI=16
GOSUB GONDER           
ENBA=1:ENBB=1:ENBC=1
pause 10                   
 ENBD=0
GOSUB MOTORSIL 
BILGI=0
ENDIF
'----------MOTOR SECME BOLUMU--------------------------------------------------
IF BILGI=1 THEN 
GIDECEKBILGI=1
GOSUB GONDER
GOSUB EKRAN_YAZ
MOTORNO=1
M1=1
BILGI=0'burada bilgi sıfırlanır ve program başa döner. tekrar bilgi gelinceye kadar hazırda bekler
ENDIF

IF BILGI=2 THEN
GIDECEKBILGI=2
GOSUB GONDER
GOSUB EKRAN_YAZ                
MOTORNO=2
M2=1
BILGI=0 
ENDIF

IF BILGI=3 THEN
GIDECEKBILGI=3
GOSUB GONDER
GOSUB EKRAN_YAZ
MOTORNO=3
M3=1
BILGI=0 
ENDIF

IF BILGI=5 THEN
GIDECEKBILGI=5
GOSUB GONDER
GOSUB EKRAN_YAZ
MOTORNO=4
M4=1
BILGI=0 
ENDIF
IF BILGI=6 THEN
GIDECEKBILGI=6
GOSUB GONDER
GOSUB EKRAN_YAZ
MOTORNO=5
M5=1
BILGI=0 
ENDIF
IF BILGI=7 THEN
GIDECEKBILGI=7
GOSUB GONDER
GOSUB EKRAN_YAZ
MOTORNO=6
M6=1
BILGI=0 
ENDIF
IF BILGI=9 THEN
GIDECEKBILGI=9
GOSUB GONDER
GOSUB EKRAN_YAZ
MOTORNO=7
M7=1
BILGI=0 
ENDIF
IF BILGI=10 THEN
GIDECEKBILGI=10
GOSUB GONDER
GOSUB EKRAN_YAZ
MOTORNO=8
M8=1
BILGI=0'burada bilgi sıfırlanır ve program başa döner. tekrar bilgi gelinceye kadar hazırda bekler 
ENDIF

'------------------YUKARI ASAĞI TUSU-DONDURE GİDEN BOLUM------------------------
IF ENBA=0 THEN
IF BILGI=15 THEN 'YUKARI DÖNDÜRMEYE GİDER
GIDECEKBILGI=15
GOSUB GONDER
GOSUB EKRAN_YAZ
    CW1=0:CW2=0:CW3=0:CW4=0:CW5=0:CW6=0:CW7=0:CW8=0                   
    GOSUB PULSVER_YUKARIA                'belirlenen sayıda puls verilecek
    BILGI=0
ENDIF
  IF BILGI=13 THEN 'AŞAĞI DÖNDÜRMEYE GİDER
  GIDECEKBILGI=13
  GOSUB GONDER
GOSUB EKRAN_YAZ        
    GOSUB PULSVERASAGIA                  'belirlenen sayıda puls verilecek
    BILGI=0
ENDIF
ENDIF

IF ENBB=0 THEN
IF BILGI=15 THEN 'YUKARI DÖNDÜRMEYE GİDER
GIDECEKBILGI=15
GOSUB GONDER
GOSUB EKRAN_YAZ
    CW1=0:CW2=0:CW3=0:CW4=0:CW5=0:CW6=0:CW7=0:CW8=0                   
    GOSUB PULSVER_YUKARIB                'belirlenen sayıda puls verilecek
    BILGI=0
ENDIF
  IF BILGI=13 THEN 'AŞAĞI DÖNDÜRMEYE GİDER
  GIDECEKBILGI=13
  GOSUB GONDER
GOSUB EKRAN_YAZ        
    GOSUB PULSVERASAGIB                  'belirlenen sayıda puls verilecek
    BILGI=0
ENDIF
ENDIF

IF ENBC=0 THEN
IF BILGI=15 THEN    'YUKARI DÖNDÜRMEYE GİDER
GIDECEKBILGI=15
GOSUB GONDER
GOSUB EKRAN_YAZ
    CW1=0:CW2=0:CW3=0:CW4=0:CW5=0:CW6=0:CW7=0:CW8=0                   
    GOSUB PULSVER_YUKARIC                'belirlenen sayıda puls verilecek
    BILGI=0
ENDIF
  IF BILGI=13 THEN 'AŞAĞI DÖNDÜRMEYE GİDER
  GIDECEKBILGI=13
  GOSUB GONDER
GOSUB EKRAN_YAZ        
    GOSUB PULSVERASAGIC                  'belirlenen sayıda puls verilecek
    BILGI=0
ENDIF
ENDIF

IF ENBD=0 THEN
IF BILGI=15 THEN   'YUKARI DÖNDÜRMEYE GİDER
GIDECEKBILGI=15
GOSUB GONDER
GOSUB EKRAN_YAZ
    CW1=0:CW2=0:CW3=0:CW4=0:CW5=0:CW6=0:CW7=0:CW8=0                   
    GOSUB PULSVER_YUKARID                'belirlenen sayıda puls verilecek
    BILGI=0
ENDIF
  IF BILGI=13 THEN 'AŞAĞI DÖNDÜRMEYE GİDER
  GIDECEKBILGI=13
  GOSUB GONDER
GOSUB EKRAN_YAZ        
    GOSUB PULSVERASAGID                  'belirlenen sayıda puls verilecek
    BILGI=0
ENDIF
ENDIF


GOTO BASLA
'*******************************************************************************
'----------------------RETURN DONGULER BASI-------------------------------------
DISABLE
INT:
    GIE=0
    HSERIN 5,ATLA, [WAIT("ETE"),BILGI]
ATLA:
    TEMP=RCREG 
    GIE=1
    Resume
    enable
    
'-------------ALINAN BİLGİYİ VERİCİYE GÖNDEREREK TEYİT ETME---------------------
GONDER:
         SEC=1
         PAUSE 5 
         HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]'uyandirma sinyali preambl 
         HSEROUT ["E","T","E",GIDECEKBILGI,$45,$4E,$44,$0D,$0A]'BU KOD SATIRLARI 1 ADET OLURSA KESİNLİKLE ÇALIŞMIYOR
         HSEROUT ["E","T","E",GIDECEKBILGI,$45,$4E,$44,$0D,$0A]
         SEC=0
RETURN
      DELAY: FOR I=0 TO 255
      PAUSEUS 5
       NEXT
       RETURN                                                                                  
'-------------------------------------------------------------------------------
EKRAN_YAZ:
'LCDOUT $FE,$8E,#BILGI,"   "
lcdout $FE,$CE,#GIDECEKBILGI,"  "
RETURN


'------------------------------------------------------------------------------
MOTORSIL:'baska bir unite seçildiğinde önceki unitede aktif olan motorun aktif durumunu siler.
M1=0:M2=0:M3=0:M4=0:M5=0:M6=0:M7=0:M8=0
IF M1=0 OR M2=0 OR M3=0 OR M4=0 OR M5=0 OR M6=0 OR M7=0 OR M8=0 THEN
MOTORNO=0
ENDIF
RETURN
'-------------------------------------------------------------------------------
PULSVER_YUKARIA:
IF ENBA=0 THEN'eğer ENBA AKTİFSE AŞAĞIDAKİLERİ YAP

    IF MOTORNO=1 THEN'program buraya geldiyse unıte ve motor seçilmiş demektir ve program buradayken aşağı tusuna basılırsa bılgı=15 olur ve motor 1 yukarı doner
       GOSUB PULSVER_CLK1'PULSVER CLK1 ETİKETİNE GİT VE ORADA İSTENİLEN KADAR PULS VER
    ENDIF
 
    IF MOTORNO=2 THEN             
       GOSUB PULSVER_CLK2
    ENDIF
    
    IF MOTORNO=3 THEN
       GOSUB PULSVER_CLK3
    ENDIF
   
    IF MOTORNO=4 THEN
       GOSUB PULSVER_CLK4
    ENDIF
  
    IF MOTORNO=5 THEN
       GOSUB PULSVER_CLK5
    ENDIF
  
    IF MOTORNO=6 THEN
       GOSUB PULSVER_CLK6
    ENDIF
   
    IF MOTORNO=7 THEN
       GOSUB PULSVER_CLK7
    ENDIF
   
    IF MOTORNO=8 THEN
       GOSUB PULSVER_CLK8
    ENDIF
ENDIF 
RETURN

'---------------------------------------------
PULSVERASAGIA:
IF ENBA=0 THEN
  
    IF MOTORNO=1 THEN'program buraya geldiyse unıte ve motor seçilmiş demektir ve program buradayken aşağı tusuna basılırsa bılgı=13 olur ve motor 1 i asağı doner
       CW1=1
       GOSUB PULSVER_CLK1
    ENDIF

    IF MOTORNO=2 THEN                      
       CW2=1
       GOSUB PULSVER_CLK2
    ENDIF

    IF MOTORNO=3 THEN
       CW3=1
       GOSUB PULSVER_CLK3
    ENDIF
  
    IF MOTORNO=4 THEN
       CW4=1
       GOSUB PULSVER_CLK4
    ENDIF
  
    IF MOTORNO=5 THEN
       CW5=1
       GOSUB PULSVER_CLK5
    ENDIF
   
    IF MOTORNO=6 THEN
       CW6=1
       GOSUB PULSVER_CLK6
    ENDIF
  
    IF MOTORNO=7 THEN
       CW7=1
       GOSUB PULSVER_CLK7
    ENDIF
    
    IF MOTORNO=8 THEN
       CW8=1
       GOSUB PULSVER_CLK8
    ENDIF
ENDIF 
RETURN

'-----------------------------------------------------
PULSVER_YUKARIB:
IF ENBB=0 THEN
    IF MOTORNO=1 THEN
       GOSUB PULSVER_CLK1
    ENDIF 
    
    IF MOTORNO=2 THEN
       GOSUB PULSVER_CLK2
    ENDIF
    
    IF MOTORNO=3 THEN
       GOSUB PULSVER_CLK3
    ENDIF
    
    IF MOTORNO=4 THEN
       GOSUB PULSVER_CLK4
    ENDIF
    
    IF MOTORNO=5 THEN
       GOSUB PULSVER_CLK5
    ENDIF
    
    IF MOTORNO=6 THEN
       GOSUB PULSVER_CLK6
    ENDIF
    
    IF MOTORNO=7 THEN
       GOSUB PULSVER_CLK7
    ENDIF
    
    IF MOTORNO=8 THEN
       GOSUB PULSVER_CLK8
    ENDIF
ENDIF 
RETURN

'---------------------------------------------
PULSVERASAGIB:
IF ENBB=0 THEN
    IF MOTORNO=1 THEN
       CW1=1
       GOSUB PULSVER_CLK1
    ENDIF 
    
    IF MOTORNO=2 THEN                     
       CW2=1
       GOSUB PULSVER_CLK2
    ENDIF
    
    IF MOTORNO=3 THEN
       CW3=1
       GOSUB PULSVER_CLK3
    ENDIF
    
    IF MOTORNO=4 THEN
       CW4=1
       GOSUB PULSVER_CLK4
    ENDIF
    
    IF MOTORNO=5 THEN
       CW5=1
       GOSUB PULSVER_CLK5
    ENDIF
    
    IF MOTORNO=6 THEN
       CW6=1
       GOSUB PULSVER_CLK6
    ENDIF
    
    IF MOTORNO=7 THEN
       CW7=1
       GOSUB PULSVER_CLK7
    ENDIF
    
    IF MOTORNO=8 THEN
       CW8=1
       GOSUB PULSVER_CLK8
    ENDIF
ENDIF 
RETURN
'-------------------------------------------------
PULSVER_YUKARIC:
IF ENBC=0 THEN
    IF MOTORNO=1 THEN
       GOSUB PULSVER_CLK1
    ENDIF 
    
    IF MOTORNO=2 THEN
       GOSUB PULSVER_CLK2
    ENDIF
    
    IF MOTORNO=3 THEN
       GOSUB PULSVER_CLK3
    ENDIF
    
    IF MOTORNO=4 THEN
       GOSUB PULSVER_CLK4
    ENDIF
    
    IF MOTORNO=5 THEN
       GOSUB PULSVER_CLK5
    ENDIF
   
    IF MOTORNO=6 THEN
       GOSUB PULSVER_CLK6
    ENDIF
   
    IF MOTORNO=7 THEN
       GOSUB PULSVER_CLK7
    ENDIF
   
    IF MOTORNO=8 THEN
       GOSUB PULSVER_CLK8
     ENDIF
ENDIF 
RETURN

'---------------------------------------------
PULSVERASAGIC:
IF ENBC=0 THEN
    IF MOTORNO=1 THEN
       CW1=1
       GOSUB PULSVER_CLK1
    ENDIF 
    
    IF MOTORNO=2 THEN                       
       CW2=1
       GOSUB PULSVER_CLK2
    ENDIF
    
    IF MOTORNO=3 THEN
       CW3=1
       GOSUB PULSVER_CLK3
    ENDIF
    
    IF MOTORNO=4 THEN
       CW4=1
       GOSUB PULSVER_CLK4
    ENDIF
    
    IF MOTORNO=5 THEN
       CW5=1
       GOSUB PULSVER_CLK5
    ENDIF
    
    IF MOTORNO=6 THEN
       CW6=1
       GOSUB PULSVER_CLK6
    ENDIF
    
    IF MOTORNO=7 THEN
       CW7=1
       GOSUB PULSVER_CLK7
    ENDIF
    
    IF MOTORNO=8 THEN
       CW8=1
       GOSUB PULSVER_CLK8
    ENDIF
ENDIF 
RETURN

'-----------------------------------------------------
PULSVER_YUKARID:
IF ENBD=0 THEN
    IF MOTORNO=1 THEN
       GOSUB PULSVER_CLK1
    ENDIF 
    
    IF MOTORNO=2 THEN
       GOSUB PULSVER_CLK2
    ENDIF
    
    IF MOTORNO=3 THEN
       GOSUB PULSVER_CLK3
    ENDIF
    
    IF MOTORNO=4 THEN
       GOSUB PULSVER_CLK4
    ENDIF
    
    IF MOTORNO=5 THEN
       GOSUB PULSVER_CLK5
    ENDIF
    
    IF MOTORNO=6 THEN
       GOSUB PULSVER_CLK6
    ENDIF
    
    IF MOTORNO=7 THEN
       GOSUB PULSVER_CLK7
    ENDIF
   
    IF MOTORNO=8 THEN
       GOSUB PULSVER_CLK8
    ENDIF
ENDIF 
RETURN

'---------------------------------------------
PULSVERASAGID:
IF ENBD=0 THEN
    
    IF MOTORNO=1 THEN
       CW1=1
       GOSUB PULSVER_CLK1
    ENDIF 
    
    IF MOTORNO=2 THEN                    
       CW2=1
       GOSUB PULSVER_CLK2
    ENDIF
    
    IF MOTORNO=3 THEN
       CW3=1
       GOSUB PULSVER_CLK3
    ENDIF
    
    IF MOTORNO=4 THEN
       CW4=1
       GOSUB PULSVER_CLK4
    ENDIF
    
    IF MOTORNO=5 THEN
       CW5=1
       GOSUB PULSVER_CLK5
    ENDIF
    
    IF MOTORNO=6 THEN
       CW6=1
       GOSUB PULSVER_CLK6
    ENDIF
    
    IF MOTORNO=7 THEN
       CW7=1
       GOSUB PULSVER_CLK7
    ENDIF
    
    IF MOTORNO=8 THEN
       CW8=1
       GOSUB PULSVER_CLK8
    ENDIF
ENDIF 
RETURN
'-----İLGİLİ CLK ÇIKIŞINA BELİRLENEN SAYIDA PULS VEREN BOLUM--------------------
PULSVER_CLK1:
 FOR P=0 TO SETPULS   ' SETPULS değeri ile oynayarak istenen PULS sayısı elde edilir.
    CLK1=1
    PAUSE DONUSHIZI 
    CLK1=0
    PAUSE DONUSHIZI
    NEXT
'    LCDOUT $FE,$C1," "
 RETURN
PULSVER_CLK2:
 FOR P=0 TO SETPULS   
    CLK2=1
    PAUSE DONUSHIZI 
    CLK2=0
    PAUSE DONUSHIZI
    NEXT
'    LCDOUT $FE,$C3," "  
 RETURN
PULSVER_CLK3:
 FOR P=0 TO SETPULS   
    CLK3=1
    PAUSE DONUSHIZI 
    CLK3=0
    PAUSE DONUSHIZI
    NEXT
'    LCDOUT $FE,$C5," "  
 RETURN
PULSVER_CLK4:
 FOR P=0 TO SETPULS   
    CLK4=1
    PAUSE DONUSHIZI 
    CLK4=0
    PAUSE DONUSHIZI
    NEXT 
'     LCDOUT $FE,$C7," " 
 RETURN
PULSVER_CLK5:
 FOR P=0 TO SETPULS   
    CLK5=1
    PAUSE DONUSHIZI 
    CLK5=0
    PAUSE DONUSHIZI
    NEXT 
'    LCDOUT $FE,$C9," " 
 RETURN
PULSVER_CLK6:
 FOR P=0 TO SETPULS   
    CLK6=1
    PAUSE DONUSHIZI 
    CLK6=0
    PAUSE DONUSHIZI
    NEXT
'    LCDOUT $FE,$CB," "  
 RETURN
PULSVER_CLK7:
 FOR P=0 TO SETPULS   
    CLK7=1
    PAUSE DONUSHIZI 
    CLK7=0
    PAUSE DONUSHIZI
    NEXT
'    LCDOUT $FE,$CD," "  
 RETURN
PULSVER_CLK8:
 FOR P=0 TO SETPULS   
    CLK8=1
    PAUSE DONUSHIZI 
    CLK8=0
    PAUSE DONUSHIZI
    NEXT
'    LCDOUT $FE,$CF," "  
 RETURN


END
"Eğer bir konuyu öğrenmek istiyorsan o konunun öğretmeni ol; daha iyi öğrenmek istiyorsan o konuda bir kitap yaz; daha da iyi öğrenmek istiyorsan yazdığın kitabi oku"

ete

Programa baktım da her yere dağılmış bir sürü pause var iken bu söyediğim iki metod da bu programda pek çalışacak gibi gözükmüyor.
Onun yerine bir üçüncüyü düşünmek gerek sanırım oda kesme yöntemi ile zaman tutmak olacak herhalde.
OSC frekansın 8 Mhz olduuğu için en doğrusu, her 25 ms de bir kesme oluşturmak ve böylece oluşan kesmeleri sayarak 1200 kesme sonra lcd arka ışığını söndürmek olurdu.
Her 25 ms de bir TMR0 kesmesi oluşturmak için ;
- INTCON=%11000000 verilmeli (USART kesmeside göz önünde tutularak) Dikkat edilirse TMR0 kesmesini aktif etmiyorum. Arka ışık yakıldığı zaman aktive edilecektir.
- OPTION_REG=%00000111 verilerek bölme oranı 1/256 ya ayarlanmalı.
- Sayac=1200 (word tipi) verilerek her tmr0 kesmesi sonunda Sayac=sayac-1 yapılmalı
- Her bilgi gelişinde Sayac=1200 yapılarak zaman uzatılmış olacaktır.
Gelelim Kesme kısmına. Programda bir kesme bölümü var zaten. İki farklı kaynaktan kesme oluşturulacak. Birisi TMR0 diğeri ise USART
TMR0 için kesme bayrağını kullanarak iki kesmeyi ayırıyoruz. Buna göre kesme kısmı şöyle olabilir;
DISABLE
INT:
    IF INTCON.2=1 then
       sayac=sayac-1
       IF Sayac=0 then LCD_LED=0
       INTCON.5=0  'kesmeyide kapattık
       INTCON.2=0
       GOTO CIK
    ENDIF   
    GIE=0
    HSERIN 5,ATLA, [WAIT("ETE"),BILGI]
ATLA:
    TEMP=RCREG 
    GIE=1
CIK:
    Resume
    enable
Hepsi bu kadar. Yinede Program içindeki pause lerin bu kodun hassas zaamn ttmasını engelleyeceğini unutma. Ama aşağı yukarı 30 sonra sistem LCD ledini söndürür. Belki biraz daha zaman alır. Gerekirse Sayac=1200 yerine 1100 verirsin süre dengelenir.

Genelde program baştan planlanıp ona göre algoritma geliştirilmelidir. İşin sonuna geldikten sonra algoritma değişiklikleri ki buna köklü değişiklik demek lazım programın yapısına genelde uymaz ve yeni baştan düşünü yeni kod yazmayı bile gerektirebilir. Bunuda göz ardı etme.

Ete




elektro77

#7
Hocam kısaca aşağıdaki gibi yapıp LCD ledini bilgi ğelişine bağladım ve tmr0 ı da orada aktif ettim.
bilgi girişi olduğunda led yanıyor ama bir turlu sonmuyor. sayac ilk değerini sayac=2 yaptım yinede sönmedi. Yani sayacım sanki eksilmiyor gibi.
SAYAC VAR WORD

'INTCON=%11000000 'verilmeli (USART kesmeside göz önünde tutularak) Dikkat edilirse TMR0 kesmesini aktif etmiyorum. Arka ışık yakıldığı zaman aktive edilecektir.
OPTION_REG=%00000111 'verilerek bölme oranı 1/256 ya ayarlanmalı.
Sayac=2 '(word tipi) verilerek her tmr0 kesmesi sonunda Sayac=sayac-1 yapılmalı
LCD_LED VAR PORTE.0

ON INTERRUPT GOTO INT 'RX PİNİNE VERİ GELİRSE PROGRAMI KESER VE VERİYİ İŞLER.

BASLA:
IF BILGI>0 THEN
LCD_LED=1
INTCON=%11001000
'SAYAC=SAYAC-1
ENDIF


GOTO BASLA

 DISABLE
INT:
    IF INTCON.2=1 then
       sayac=sayac-1
       IF Sayac=0 then LCD_LED=0
       INTCON.5=0  'kesmeyide kapattık
       INTCON.2=0
       GOTO CIK
    ENDIF   
    GIE=0
    HSERIN 5,ATLA, [WAIT("ETE"),BILGI]
ATLA:
    TEMP=RCREG 
    GIE=1
CIK:
    Resume
    enable
    

"Eğer bir konuyu öğrenmek istiyorsan o konunun öğretmeni ol; daha iyi öğrenmek istiyorsan o konuda bir kitap yaz; daha da iyi öğrenmek istiyorsan yazdığın kitabi oku"

ete

#8
Biraz dikkat lütfen. INCON.5=1 ise bu TMR0 kesmesi çalışır. Ne demiştim, Arka ışığı yakınca INTCON.5=1 yap ki kesme başlasın. Sen ise deneme programı yazıyorsun ve dediklerimi göz ardı ediyorsun. Bir defa mantık yürütmen lazım.
TMR0 kesmesinin çalışması için gerekli olanlar neler?
- Global kesme aktif olacak (INTCON.7)
- TMR0 kesmesi aktif olacak (INTCON.5)
bunu yapsaydın INTCON.5 değerinin sıfır olduğunu görürdün sanırım.
Sen INTCON=%11001000 şeklinde verdiğin komut ile PORTB değişiklik kesmesini aktif etmişsin. Alakası yok. INTCON=%11100000 vermen gerekirdi.

Ete

elektro77

Alıntı yapılan: ete - 10 Eylül 2019, 18:20:51Biraz dikkat lütfen. INCON.5=1 ise bu TMR0 kesmesi çalışır. Ne demiştim, Arka ışığı yakınca INTCON.5=1 yap ki kesme başlasın. Sen ise deneme programı yazıyorsun ve dediklerimi göz ardı ediyorsun.

Ete
hayir hocam deneme programi yazmadim. yukaridakileri nerede ne yazdigimi gostermek icin ana programdan kopyala yapistir yaptim. Tekrar tum kodlari yapistirip yer kaplamak ve kafa kariatirmak istemedim. Yarin ilk is bu dediklerinizi tekrar deniycem. Intcon tmr0 aktif etme ayarlarini nasil yapacagimi anlamak icin datasheetle baya hasir nesir olduk. Hatta sorunun ne oldugunu anlayamayinca INTCON %11000000 ayarlarini ilk bitten baslayarak tekker teker 1 yapip denedim. En sonunda bu sekilde size yazdim.
"Eğer bir konuyu öğrenmek istiyorsan o konunun öğretmeni ol; daha iyi öğrenmek istiyorsan o konuda bir kitap yaz; daha da iyi öğrenmek istiyorsan yazdığın kitabi oku"

elektro77

Hocam dediklerinizi aynen yaptım ama sayac bir miktar sayıp duruyor. nerede yanlış yaptığımı bir türlü bulamıyorum.
"Eğer bir konuyu öğrenmek istiyorsan o konunun öğretmeni ol; daha iyi öğrenmek istiyorsan o konuda bir kitap yaz; daha da iyi öğrenmek istiyorsan yazdığın kitabi oku"

ete

Elbette boyundan büyük işlere kalkışınca bir yerde tökezler kalırsın. Bilgi seviyene uygun işlerle uğraşmanı özellikle öneriyorum. Bu tür işlerle ancak ustalaştıktan sonra uğraşırsın. Sürekli sorarak bir yere varılmaz öğrendiklerinde kalıcı olmaz.

Bana mesaj atıp aynı soruyu sormuş ve programlarıda yollamışsın. Sana cevap yazdım ama burada takip eden arkadaşlarıda en azından bilgilendirmek adına hatalarını bir kez daha belirtmek istiyorum.

Veren isimli programa bakacak olursak orada

IF BILGI>0  THEN             'ARKA ISIK AÇIP KAPATMA BOLUMU
  SAYAC=120
  LCD_LED=1
  tmr0=60
  INTCON.5=1
ENDIF

satırları var. Yanlış değil ama eksik. Nedeni basit. Biliyorsun program bir döngü içinde çalışır. Yani bu komut satırı yalnızca bir kere çalıştırılmaz. Döngü içinde sırası geldikçe (bilgi değeri sıfırdan büyük olduğu müddetçe) yeniden çalıştırılır. Yeniden çalışınca SAYAC değeri hep 120 da kalır. Kesme içinde sen onu eksiltsen bile ana döngüde sayac yeniden 120 yapılır. O halde ne yapmak gerekiyor. Bu komutları sayac=0 oluncaya kadar yalnızca bir kere çalıştırmak gerekiyor. Bu nedenle buraya ilave yapıyoruz. Ne ekleyeceğiz?, LCD_LED=0 ise bu komutu çalıştır dersek artık komutlar içinde LCD_LED=1 yapıldıktan sonra bu komutlar bir daha çalıştırılmaz.  Ama sayac=0 olduktan sonra şayet hala Bilgi>0 ise aynı komut satırı yeniden çalıştırılır. Bunuda önlemek için komutlara BILGI=0 satırınıda eklemek gerekiyor.

IF BILGI>0 and lcd_led=0 THEN                     'ARKA ISIK AÇIP KAPATMA BOLUMU
  SAYAC=120
  LCD_LED=1
  tmr0=60
  BILGI=0
  INTCON.5=1
ENDIF


Kesme kısmında büyük bir hata yapmışsın. Sayac değeri sıfır olmuş ise TMR0 kesmesini kapatıyoruz. Sen ise SAYAC=0 ise LCD_LED=0 demişsin ama altında INTCON.5=0 diyerek kesmeyide kapatmışsın.

IF SAYAC=0 then LCD_LED=0
INTCON.5=0

 Bu şu demek oluyor. İlk kesme oluştuğunda kesmede kapatılacak ve sayac birdaha eksilmeyecek demektir. Bu satırları şöyle yazmak gerekiyor idi,

IF INTCON.2=1 then'ARKA ISIK KAPATMA BOLUMU KESMESİ
       sayac=sayac-1
       IF Sayac=0 then
           LCD_LED=0
           INTCON.5=0  'kesmeyide kapattık
       EndIF
       INTCON.2=0
       tmr0=60
       GOTO CIK   
ENDIF'ARKA ISIK KAPATMA KESME BOLUMU SONU
soru
Alan isimli programda da benzer hatalar mevcut. Onları da düzelterek çalışan versiyonu kendisine verdim.
Bu konuyu burada kilitlemek istiyordum ancak vaz geçtim. Yalnız bu konuya bir daha yanıt vermeyeceğim.
Soru gelirse isteyen cevaplayabilir.


Ete

elektro77

Evet hocam arka isik calisiyor. Cok tesekkur ederim. fakat yazilimda vericiden gonderilen bilgiyi alicida teyit edip gelen bilgi dogru ise gerekli islemi yapmasi dogru degilse ekranda kablo kopuk veya veri hatali yazmasi icin bir komut satiri vardi.kodlari Size gonderirken o dizini aktif etmeyi unutmusum. O satirlari aktif edince sizin arka isik algoritmasi ile bir cakisma veya bilgi alis verisinde bir senkron sorunu yasadim. Bu sorunu cozmeye calisiyorum su an. bakabilecekmisiniz. Surekli kablo kopuk hatasi aliyorum.
"Eğer bir konuyu öğrenmek istiyorsan o konunun öğretmeni ol; daha iyi öğrenmek istiyorsan o konuda bir kitap yaz; daha da iyi öğrenmek istiyorsan yazdığın kitabi oku"

Powered by EzPortal