zamanlayici

Başlatan selvi, 20 Eylül 2009, 17:04:21

selvi

vericiden aliciya 100msn de bir veri yollacagim eger alici 100ms icinde veri almasa aliciya bagli olan led yansin
usart kesmesini kullanmayi dusunuyorum.alicida 100msn boyunca verinin gelip gelmedigini anlamak icin zamanlama islemini nasil yapmam gerekiyor.
Yaşam anlamlandırıldıkça kutsaldır....

ete

Selvi ,
Artık böyle soruları sormaman gerektiğini düşünüyorum. Daha doğrusu programlamada epeyce mesafe kat ettiğini düşünüyorum.

>Sorunun cevabı basit. Elinde 2 alternatif var.
Birincisi timer0 sayacı diğeride Timer1 sayacı olabilir.
Yapılacak iş veri geldiği zaman bu timerlardan birini 100 ms sonra kesme oluşturacak şekilde kuracaksın. Kesme bölümünde ledi yakabilirsin. Arada veri gelirse timer değerini yenileyeceksin. Hepsi bu. Belkide söylemesi kolay gelde yap diyeceksin ama senin bunu yapabileceğini düşünüyorum.

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

selvi

tmr0 aklimdaydi.fakat farkli secenekler olabilir diye dusundum.mesala:
HSERIN 100,cik,[WAIT("ARA"),AL ] seklinde olabilir mi?yani 100msn bilgi gelmese led yak seklinde yapilabilir mi?hserin deki  gecikme ve etiket durumu hiza gore farkli durumlar cikiyor.9600 hizda gecikme en fazla 1 yapabiliyorum.hizi dusurdukce bu gecikme biraz yukselir.
Yaşam anlamlandırıldıkça kutsaldır....

ete

Şayet USARt kesmesi kullanacak isen Hserin komutunun çalışması için her hangi bir verinin gelip kesme oluşturması gerekir. Gelen bilgi senin beklediğin olmayabilir o zaman orada 100 ms lik bir bekleme söz konusu olabilir.  Bir veri gelmez ise hiç bir zaman Usart kesmesi meydana gelmeyeceğinden senin 100 ms lik bekleme orada çalışmayacaktır. O nedenle ikisi farklı şeyler.
Sana lazım olan bilgi gelsin gelmesin 100 ms lik bir bekleme sonunda bilgi gelmemiş ise led in yanmasıdır. O nedenle direk USART kesmesi yanında birde timer0 yada timer1 kesmesi açman gerek. Ama kesme ilk bilgi geldikten sonra açılmalı yada baştan açılıp her bilgi geldiğinde timer resetlenmeli (yada başka bir deyişle 100 ms bekletecek ön yükleme değeri timer a yüklenmelidir.)

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

selvi

programi asagidaki sekilde duzenledim.transceiver bicimiyle oldu.farkli bir verici(vericinin programini vermedim.fazla karismasin diye)  ile bu sistemi acma ve kapat yapiyorum.yani farkli bir verici ile RB=1 ve RB=0 yapiyorum.vericinin tek islevi budur.actiktan sonra asagidaki programda oldugu gibi verici yaklasik 200msn bir veri yolluyor.alicida yaklasik 260ms icinde veri gelmezse led(portb.6=1)yaniyor.proteusda calistiramadim.
@ DEVICE pic16F628 'islemci 16F628A 
@ DEVICE pic16F628, WDT_OFF 'Watch Dog timer kapali 
@ DEVICE pic16F628, PWRT_ON 'Power on timer acik 
@ DEVICE pic16F628, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F628, MCLR_OFF 'MCLR pini kullaniliyor. 
@ DEVICE pic16F628, XT_OSC 'Dahili osilatör kullanilmayacak
@ DEVICE pic16F628, LVP_OFF
@ DEVICE pic16F628, BOD_OFF
               
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 25  '9600 baud @ 4mhz
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

SYMBOL GIE  =INTCON.7   'genel interruptlarý açýyor
SYMBOL PEIE =INTCON.6   'peripheral interruptlarý açýyor
SYMBOL RCIE =PIE1.5     'USART Recive interrupt enable bit
SYMBOL RCIF =PIR1.5     'USART Receive interrupt flag bit
PIE1.0=0
T1CON=%00100001   
RCIE=1
PEIE=1
GIE=1

ON INTERRUPT GOTO KESME 
 
CMCON=7           '16F628 de komparatör pinleri iptal hepsi giris çikis
OPTION_REG.7=1    'Dahili pull-up lar pasif yapildi
TRISB=%00001011
TRISA=%00110010
PORTB=0
PORTA=0
PORTA.0=0

 VER    VAR  BYTE
 AL     VAR  BYTE  
 US     VAR  BIT
 RB     VAR  BIT
 DUR    VAR  BIT
 K      VAR  WORD
 I      VAR  WORD 
  
 CLEAR
LOOP:
IF DUR=1 THEN
PORTB.6=1
For K=0 to 50000
pauseus 5
pauseus 5
next 
PORTB.6=0
ENDIF 
IF RB=1 THEN
PORTA.0=1
VER=153
HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]'uyandirma sinyali preambl 
HSEROUT ["A","R","A",VER ]
HSEROUT ["A","R","A",VER ]
PORTA.0=0
For I=0 to 40000
pauseus 5
next 
ENDIF 
if  AL =153   then  'vericiden gonderilen sayac degeri
TMR1H=0:TMR1L=0
PIE1.0=1
ENDIF 
IF US=1 THEN
US=0
        IF  AL=73   THEN  'aliciyi ac 
        PORTB.4=1:PAUSE 500:PORTB.4=0
        PIE1.0=1 :RB=1
        ENDIF
KAPAT:   
        IF  AL=233    THEN   'aliciyi kapat 
        PIE1.0=0 :RB=0
        PORTB.4=1 :PAUSE 500: PORTB.4=0
        ENDIF
ENDIF
GOTO LOOP
;---------USART KESME-----------
DISABLE
KESME:
GIE=0 'tüm interruptlari kapat yani INTCON.7=0
IF PIR1.0=1 THEN
DUR=1 
PIR1.0=0 'kesme bayragi sifirlanacak 
GOTO CIK
ENDIF 
HSERIN 1,BIR,[WAIT("ARA"),AL]
TEMP=RCREG
RCREG=0
TEMP=0
US=1
GOTO CIK
BIR:US=0 
CIK:
RCIF=0
GIE=1 'Yani INTCON.7=1 kesmeleri açtik.
RESUME
ENABLE 
END
Yaşam anlamlandırıldıkça kutsaldır....

ete

Doğrusu yazdığın program kısmen doğru ama bazı eksikler var.
Aslında mantığını tam olarak anlamak mümkün değil. O nedenle belkide eksik yoktur.

Mesela alıcıyı aç ve alıcıyı kapat gibi alt programların var ancak açıp kapatma işini kimin yaptığı belli değil.

Her neyse önceki mesajlarında süreyi 100 ms olarak istemiş idin. O nedenle 100 ms üzerinden bazı düzenlemeler yaptım. Aşağıdaki ni bir dene istersen. Yada mantığı kavrayıp kendi mantığına uydur.

Ete

@ DEVICE pic16F628 'islemci 16F628A
@ DEVICE pic16F628, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F628, PWRT_ON 'Power on timer acik
@ DEVICE pic16F628, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F628, MCLR_OFF 'MCLR pini kullaniliyor.
@ DEVICE pic16F628, XT_OSC 'Dahili osilatör kullanilmayacak
@ DEVICE pic16F628, LVP_OFF
@ DEVICE pic16F628, BOD_OFF
               
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 25  '9600 baud @ 4mhz
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

SYMBOL GIE =INTCON.7   'genel interruptlary' açy'yor
SYMBOL PEIE=INTCON.6   'peripheral interruptlary' açy'yor
SYMBOL RCIE=PIE1.5     'USART Recive interrupt enable bit
SYMBOL RCIF=PIR1.5     'USART Receive interrupt flag bit
 
CMCON=7           '16F628 de komparatör pinleri iptal hepsi giris çikis
OPTION_REG.7=1    'Dahili pull-up lar pasif yapildi
TRISB=%00001011
TRISA=%00110010
PORTB=0
PORTA=0


 VER    VAR  BYTE
 AL     VAR  BYTE 
 TEMP   var  BYTE
 US     VAR  BIT
 RB     VAR  BIT
 DUR    VAR  BIT
 K      VAR  WORD
 I      VAR  WORD
 
 
T1CON=%00010000     ' 1/2 --BİT 4-5 PRESCALER 11 = 1/8 , 10=1/4 , 01=1/2, 00=1/1

RCIE=1  'USART Receive kesmesi enable biti
PEIE=1  'Çevresel kesmeler açıldı
GIE=1   'global kesmeler açıldı 

ON INTERRUPT GOTO KESME
dur=0
LOOP:
    IF DUR=1 THEN
      PORTB.6=1
      For K=0 to 50000
        pauseus 5
        pauseus 5
      next
      PORTB.6=0
    ENDIF
    
    IF RB=1 THEN
      PORTA.0=1
      VER=153
      HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]            'uyandirma sinyali preambl
      HSEROUT ["A","R","A",VER ]
      HSEROUT ["A","R","A",VER ]
      PORTA.0=0
      For I=0 to 40000
        pauseus 5
      next
    ENDIF
    
    if AL =153   then  'vericiden gonderilen sayac degeri 
      TMR1H=60:TMR1L=179 'timer1 önyükleme değeri verildi
      PIE1.0=1  'timer1 kesmesi aktif
      T1CON.0=1 'timer1 aktif 
      PIR1.0=0  'TMR1 kesme bayrağını her ihtimale karşın sıfırladık 
    ENDIF
    
    IF US=1 THEN
      US=0
      IF AL=73   THEN  'aliciyi ac   alıcıyı kim açıyor?????????
        PORTB.4=1:Gosub delay:PORTB.4=0  'alıcıyı bu açıyor ise açıp kapatıyor olması gerek
        PIE1.0=1 :RB=1
        TMR1H=60:TMR1L=179 'timer1 önyükleme değeri verildi
        T1CON.0=1 'timer1 aktif 
        PIR1.0=0  'TMR1 kesme bayrağını her ihtimale karşın sıfırladık               
      ENDIF
      
KAPAT:   
        IF  AL=233    THEN   'aliciyi kapat  Kim kapatıyor ???????
          PIE1.0=0 :RB=0   'TİMER1 KESMESİ KAPALI
          T1CON.0=0 'timer1 KAPALI
          PORTB.4=1 :gosub delay: PORTB.4=0
        ENDIF
      ENDIF
      
      GOTO LOOP
      
Delay:
      for I=0 to 50000
        pause 5
      next
      return  
            
;-----------------USART KESME---------------------------
DISABLE
KESME:
      GIE=0 'tüm interruptlari kapat yani INTCON.7=0
      IF PIR1.0=1 THEN  'TİMER1 KESMESİ OLUŞMUŞ İSE
        DUR=1
        PIR1.0=0 'kesme bayragi sifirlanacak
        GOTO CIK
      ENDIF
      
      HSERIN 3,CIK,[WAIT("ARA"),AL]
      TEMP=RCREG
      US=1
      dur=0
CIK:
     TMR1H=60:TMR1L=179 'HER DURUMDA TİMER1 ÖNYÜKLEME DEĞERİ VERİLECEK.
     GIE=1 'Yani INTCON.7=1 kesmeleri açtik.
RESUME
ENABLE
END
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

selvi

hocam verdiginiz programi denedim.soyle bir durum aciga cikti.simulasyonda programi calistirdigimda led belli sure araliklarla yanip sonuyor.alici bilgi almadiginda da ayni bicimiyle led yanip sonuyor.normalde belirnen sure(100ms) icinde  bilgi alisi oldugunda ledin yanmamasi, belirlenen sure gectiginde bilgi alisi olmadiginda ledin yanmasi gerekir.
program vericiden aliciya 50msn de bir bilgi yolluyor .bunun nedenide verici modulun fazla enerji harcamasi.duruma gore bu sureyi kisaltip-uzatabilirim.
diger bir durum ac ve kapat alt programlarindan bahsetmissiniz.o kismi farkli bir verici ile aciyorum.o sorun değil.ek ayrinti.asil sormak istedigim sizinde belirtginiz sekildedir.fakat ustten bahsettigim sorun.her kosulda ledin yanip sonmesi.zamanlarla biraz oynadim.bir sey degismedi.simulasyonda kaynakli bir durum olabilir mi?cok ihtimal vermesemde.
Yaşam anlamlandırıldıkça kutsaldır....

ete

Amacını anlamadığımı söylerken haksız değilmişim.
Yazdığın programda led'i yakıyor ve yaklaşık 500 ms sonra söndürüyorsun. Ledin yanıp sönmesi bu nedenle oluyordur.
Bu aşamadan sonra çok fazla yardımcı olmam beklenemez. Zira işin amacını tam olarak bilemiyorum.
Ama verdiğim program senin amacına uygun olarak çalışır.
Burada vericinin programıda önem kazanıyor. Zira oradan gelecek sinyale göre bu programda Timer1 kesmesi açılıyor. Daha sonra hiç kapatılmıyor.
100 ms kısa bir süredir ve simulasyonda bunu tutturmak yani bu süreye uygun olarak veri yollamak zor olabilir.

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

selvi

program karismamasi icin ac ve kapati kaldirdim.ac ve kapat in gorevi sadece RB degiskenini RB=1 ve duruma gore RB=0 yapmaktir.zaten loop dongusunden once RB=1 yaptim.digeri tmr1 kesmesi olustugunda dur=1 oluyor.ve led yanip sondugunde dur=0 oluyor.yeni bir tmr1 kesmesi olusmayana kadar dur=0 dir.anladigim kadariyla led yanip sonmez.sizin verdiginiz programda dur=1 olduktan sonra dur=0 yapilmamisti.
  asagidaki programda verici her 50ms bir veri yolluyor.alici veri aldiginda tmr1 aktiflestiriyor.ve programa gore 100msn icinde veri gelmese ledin yanmasi gerekiyor.simulasyonda surekli veri alinsada alinmasa led yaniyor.bu kismi cozemedim.belki cok basit bir nokta ama bir turlu goremedim.
@ DEVICE pic16F628 'islemci 16F628A
@ DEVICE pic16F628, WDT_OFF 'Watch Dog timer kapali
@ DEVICE pic16F628, PWRT_ON 'Power on timer acik
@ DEVICE pic16F628, PROTECT_OFF 'Kod Protek kapali
@ DEVICE pic16F628, MCLR_OFF 'MCLR pini kullaniliyor.
@ DEVICE pic16F628, XT_OSC 'Dahili osilatör kullanilmayacak
@ DEVICE pic16F628, LVP_OFF
@ DEVICE pic16F628, BOD_OFF
               
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_SPBRG 25  '9600 baud @ 4mhz
DEFINE HSER_CLROERR 1 ' Clear overflow automatically

SYMBOL GIE =INTCON.7   'genel interruptlary' açy'yor
SYMBOL PEIE=INTCON.6   'peripheral interruptlary' açy'yor
SYMBOL RCIE=PIE1.5     'USART Recive interrupt enable bit
SYMBOL RCIF=PIR1.5     'USART Receive interrupt flag bit
 
CMCON=7           '16F628 de komparatör pinleri iptal hepsi giris çikis
OPTION_REG.7=1    'Dahili pull-up lar pasif yapildi
TRISB=%00001011
TRISA=%00110010
PORTB=0
PORTA=0


 VER    VAR  BYTE
 AL     VAR  BYTE
 TEMP   var  BYTE
 US     VAR  BIT
 RB     VAR  BIT
 DUR    VAR  BIT
 K      VAR  WORD
 I      VAR  WORD
 
 
T1CON=%00010000     ' 1/2 --BİT 4-5 PRESCALER 11 = 1/8 , 10=1/4 , 01=1/2, 00=1/1

RCIE=1  'USART Receive kesmesi enable biti
PEIE=1  'Çevresel kesmeler açıldı
GIE=1   'global kesmeler açıldı

ON INTERRUPT GOTO KESME
RB=1   'ac ve kapatindaki yaptigi bu degiskeni degistirmek.yani programi yonlendirmek
LOOP:
    IF DUR=1 THEN
      DUR=0
      PORTB.6=1
      For K=0 to 50000
        pauseus 5
        pauseus 5
      next
      PORTB.6=0
    ENDIF
   
    IF RB=1 THEN
      PORTA.0=1
      VER=153
      HSEROUT [REP$AA\5,REP$00\5,REP$FF\5]            'uyandirma sinyali preambl
      HSEROUT ["A","R","A",VER ]
      HSEROUT ["A","R","A",VER ]
      PORTA.0=0
      For I=0 to 10000
        pauseus 5
      next
    ENDIF
   
    if AL =153   then  'vericiden gonderilen sayac degeri
      TMR1H=60:TMR1L=179 'timer1 önyükleme değeri verildi
      PIE1.0=1  'timer1 kesmesi aktif
      T1CON.0=1 'timer1 aktif
      PIR1.0=0  'TMR1 kesme bayrağını her ihtimale karşın sıfırladık
    ENDIF 
;-----------------USART KESME---------------------------
DISABLE
KESME:
      GIE=0 'tüm interruptlari kapat yani INTCON.7=0
      IF PIR1.0=1 THEN  'TİMER1 KESMESİ OLUŞMUŞ İSE
        DUR=1
        PIR1.0=0 'kesme bayragi sifirlanacak
        GOTO CIK
      ENDIF
     
      HSERIN 3,CIK,[WAIT("ARA"),AL]
      TEMP=RCREG
      US=1
      dur=0
CIK:
     TMR1H=60:TMR1L=179 'HER DURUMDA TİMER1 ÖNYÜKLEME DEĞERİ VERİLECEK.
     GIE=1 'Yani INTCON.7=1 kesmeleri açtik.
RESUME
ENABLE
Yaşam anlamlandırıldıkça kutsaldır....

ete

Programda DUR değişkeni veri gelip gelmediğini açıklayan değişken.
Dur=1 ise ver gelmemiş yani led yansın, veri=0 ise ver gelmiş led sönsün şeklinde kullanılması gerekir.
Verdiğim program parçasında da ver gelmemesi durumunda Dur=1 oluyor, veri gelmesi halinde ise Dur=0 oluyor idi. Ama sen başka mantık yürütüyor isen onu bilemem.

Ayrıca her 50 ms de bir veri yollanması iddalı bir süre. Pratikte bu sıklıukla veri alınabilirmi bilemiyorum.
Deneme yapılarak (gerçek devrede) veri sıklığı test edilmeli bence. Zira bu süre tutturulamıyor ise led sürekli yanar konumda kalacaktır.

Program şu hali ile çok yönlü ve tamamına hakim olunmadan doğru çalışan bir program için fikir yürütmek zor. Ksımı yürütülen fikirler ise başka kısımların bozulmasına sebep olabilir. O nedenle programın bütününü açıklaman ve diğer programıda burada vermen gerekebilir. Yada bu kadar bilgi ile kendin çözümü bulabilirsin artık diye düşünüyorum.

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