avatar_elektro77

TİMER1 Örnek

Başlatan elektro77, 10 Ekim 2022, 00:43:14

elektro77

Hocam ekte timer 1 i anlamak adına bir örnek simülasyon yapmaya çalıştım ama başardığım söylenemez. Nedense bu timer1 kafamı karıştırdı.
Örnekte, 8 MHz de 1/8 bölme oranında 150mS lik bir timer ayarladım ama B0 çıkışını kapatamıyorum. Uygulama üzerinde bir örnek gösterebilir misiniz?
Kodları buraya da bırakıyorum:
#config
 __Config _HS_OSC  &  _WDT_OFF &_PWRTE_OFF &_BODEN_OFF &_CP_ON &_CPD_OFF &_LVP_OFF 
#ENDCONFIG
'------------------
define OSC 8
'ADCON1=7              'ADC KANALLARI DİJİTAL YAPILDI - ADC İPTAL
ADCON1=%10000010       '5 KANAL ADC AKTİF EDİLDİ.
CMCON=7               'komparatör pinleri iptal hepsi giriş çıkış yapıldı.
OPTION_REG.7=0        'portB deki dahili PULL-UP lar AKTİF edildi. OPTION_REG.7=1 İSE PULLUPLAR PASİF
'------------------
 TRISA=%00011111      'ADC OKUNACAK PİNLER GİRİŞ YAPILDI
 TRISB=%11111111      'Portb nin tamamı GİRİŞ olarak ayarlandı
 TRISC=%00000011      'portc deki bazı pinler giriş olarak ayarlandı
 PORTA=%00000000
 PORTB=%00000000
 PORTC=%00000000
'-------------------
DEFINE LCD_DREG		PORTC	
DEFINE LCD_DBIT		0		
DEFINE LCD_RSREG	PORTC	
DEFINE LCD_RSBIT	5	
DEFINE LCD_EREG		PORTC	
DEFINE LCD_EBIT		4		
DEFINE LCD_BITS		4	
DEFINE LCD_LINES	4
DEFINE LCD_COMMANDUS   2000     'Command delay time in us 
DEFINE LCD_DATAUS      50       'Data delay time in us
 '-------------------------------------------------------------------------------
DEFINE ADC_BITS        10       'A/D çevirim sonucu kaç bit olacak
DEFINE ADC_CLOCK       5        'Clock kaynağı (5=FOSC/16)
DEFINE ADC_SAMPLEUS    20       'Örnekleme zamanı mikro saniye cinsinden.
'-------------------------------------------------------------------------------      
SAYI var word: SAYI=0
X    VAR WORD '0. KANAL ADC DEĞİŞKENİNİN YAZILDIĞI DEĞER
'Y    VAR WORD '1. KANAL ADC DEĞİŞKENİNİN YAZILDIĞI DEĞER
symbol B0         =portB.0


lcdout $FE,1 'ekranı temizlemek
pause 300
'-------------------------------------------------------------------------------

BASLA:

T1CON=%00110001

BASLA_BIR:

TMR1H=$6D:TMR1L=$84:PIR1.0=0  '150mS önyükleme(8 mHz de 1/8 ORANDA 28036)
WHILE PIR1.0=0
'buraya bütün programı koy yada belirli bir aşamadan sonraki program parçasını koy
    Adcin 0 ,x
    gosub ekran
    B0=1

WEND

'program buraya geldiğinde 150 ms dolmuş olacak.
'İşte burada ledleri varsa buzzeri şayet aktif iseler toggle yapacaksın.

B0=0
    PAUSE 100


GOTO BASLA_BIR

  EKRAN:
	    lcdout $FE,$80,"ADC 0 :",DEC4 X   ,"  "        'okunan o,pot değerini ekrana yazdırmak
	    lcdout $FE,$C0,"PIR1.0:",DEC PIR1.0   ,"  "        
        RETURN
"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

#1
Aşağıdaki kod parçasını ilgili yere yerleştir öyle bak farkı göreceksin.
Bu tür kullanım şeklinde artık pause kullanmaman gerekir. Ben kullanmadım. Timer-1 in 150 ms lik gecikmesinden yararlandım sonucu göreceksin. B0 çıkışını timer döngüsü dışında bir kere HIGH yapıyorum. Sonra o döngü sayesinde her 150 ms de bir yanıp sönüyor. Olay bu.
Bu sistemde PIR.0 bitinin değerini çok sıhhatli göremiyorsun. Sebebi basit.
Bu bit timer döngüsü öncesi sıfırlanıyor ve döngü çalıştığı müddetçe sen onu sıfır olarak ekranda görüyorsun. Sorun 1 olduğu zaman onu görmede. Wend den sonra bu bit 1 oluyor ama b0 ı toggle yapıp hemen tekrar başa yollayınca PIR1.0 bitinin 1 olma hali neredeyse anlık oluyor ve bunuda ekrana vermediğin için göremiyorsun.
Görmek istersen aşağıdaki ilaveyi dene.

toggle b0  
lcdout $FE,$C0,"PIR1.0:",DEC PIR1.0   ,"  ":pause 150  
mantık şöyle 150 ms o bit LOW da kaldı HIGH olduğunda sende hem ekrana verip hemde zorunlu olarak 150ms high da kalmasını sağlamış oluyorsun.

Ete

BASLA:
B0=1
T1CON=%00110001

BASLA_BIR:

TMR1H=$6D:TMR1L=$84:PIR1.0=0  '150mS önyükleme(8 mHz de 1/8 ORANDA 28036)
WHILE PIR1.0=0
'buraya bütün programı koy yada belirli bir aşamadan sonraki program parçasını koy
    Adcin 0 ,x
    gosub ekran
WEND

'program buraya geldiğinde 150 ms dolmuş olacak.
'İşte burada ledleri varsa buzzeri şayet aktif iseler toggle yapacaksın.

toggle b0  

GOTO BASLA_BIR

elektro77

Sanırım anlamakta zorlandığım şey, daha uzun programlarda bu timer ı nerede kurup nerede kapatmam gerekeceği. Wend den sonrası bir nevi return döngüsü mü olmuş oluyor?
"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

#3
Bir de verdiğiniz örnekte register ı T1CON=%00110001 bu şekilde ayarlamışsınız. Datasheet e göre
maximum bölme oranı 1/8. Ben olayı anlamak adına 1000mS lik bir döngü seçmek istesem PicMultiCalc bana 1/32 prescaler oranını öneriyor. Bu durumda Timer 1 i kullanamıyoruz galiba doğru mu anlamışım Hocam? Bir de register deki bit 2 yi anlamlandıramadım.
bit 7-6 Unimplemented: Read as '0'
bit 5-4 T1CKPS1:T1CKPS0: Timer1 Input Clock Prescale Select bits
11 = 1:8 prescale value
10 = 1:4 prescale value
01 = 1:2 prescale value
00 = 1:1 prescale value
bit 3 T1OSCEN: Timer1 Oscillator Enable Control bit
1 = Oscillator is enabled
0 = Oscillator is shut-off (the oscillator inverter is turned off to eliminate power drain)
bit 2 T1SYNC: Timer1 External Clock Input Synchronization Control bit
When TMR1CS = 1:
1 = Do not synchronize external clock input
0 = Synchronize external clock input
When TMR1CS = 0:
This bit is ignored. Timer1 uses the internal clock when TMR1CS = 0.
bit 1 TMR1CS: Timer1 Clock Source Select bit
1 = External clock from pin RC0/T1OSO/T1CKI (on the rising edge)
0 = Internal clock (FOSC/4)
bit 0 TMR1ON: Timer1 On bit
1 = Enables Timer1
0 = Stops Timer1
"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

Büyük gecikmeler gerektiği zaman bir ikinci değişkeni devreye sokmak gerekir.
Genelde 4 Mhz osc frekansında 250 ms lik gecikme elde etmek mümkün bu ise 4 adet kullandığın zaman sana 1000 ms lik gecikmeyi sağlar yani 4 kere gecikme yaratırsan 4x250=1000 ms edecektir. 8 Mhz ve üzeri frekanslarda 100 ms lik dilimleri kullanıyorum. Bu durumda 10 defa çalıştırırsan 1000 ms edecektir.
BASLA satırından hemen sonra KES=10 dersin. Wend satırından hemen sonra ise,
Kes=Kes-1 if KES>0 then BASLA_BIR dersin olur biter. Böylece kes=kes-1 satırı aşıldığı zaman başlangıçta KES=? kaç ayarlamış isen o kadar gecikme döngüsü çalıştırmış olursun.

Multicalc 1/8 bölme oranında istediğin gecikmeyi sağlamıyor ise anlaki o OSC frekansında o gecikmeyi sağlamak mümkün değil o halde dilimlere bölüp o şekilde kullanman gerekir.

Bit2 ye geelince üzerinde kafa yormadım ama sanırım Timer-1 sayacı yanlızca dahili osc den tetik almaz. Gerekirse harici kaynakdan da puls alarak sayabilir. Bu durumda hariçten gelen sinyal ile senkronize olsunmu olmasınmı onu ayarlıyor.

Timer döngüsü bir aralık zaman sayarak sana çalışma imkanı sağlıyor. Bu sayede zaman bağlı bir takım işleri yapmana olanak sağlıyor hemde ekstra ilave kod kullanmadan. Led yakıp söndürme buzzeerden beep - beep ses çıkartma. Belirli zaman dilimnde yapılması gerekenleri yapma gibi. Özellikle bu son söylediğime bir kaç örnek vereyim. DS18B20 yaklaşık 750 ms de sıcaklığı okumaktadır. Bu süreden önce sıcaklığı okumaya çalışırsan sensör meşgul (Busy) ikazı verir yani okumaman gerekir. AMa bu şekilde bir döngü kur her bir kesmesi 250 ms olsun 3 cü döngüden sonra gidip sensörü rahatlıkla okuyabilirsin.
Mesela başka bir örnek DS1307 RTC kullanıyorsun. Her an sürekli bu RTC yi okumanın bir anlamı yok hatta RTC yi sürekli meşgul edersen ileri geri gitmeler çoğalır. EN uygun okuma zamanı iki okuma arasına en azından 1000 ms (yani 1sn) lik süre koymakla olur. İşte Timer-1 bunuda sana sağlar.
Bunlar örnekler. Gerisi senin ufkuna kalmış.
Nerede açıp nerede kapatacağınada sen karar ver artık. Programa göre değişir bu. Kimisinde hiç kapatman gerekmez sürekli o döngüde çalışır. Ama bazen öyle durumlar olurki kapatmanda gerekebilir onu sen bileceksin.

Ete

elektro77

#5
Hocam hala kafamın almadığı yerler var.
Ana program başla satırının altında mı olacak, yoksa basla_bir in altında mı?
Goto basla komutu nereye konacak.
8 MHz de  100mS lik 10 dilim ayarladım ama bir garip çalışıyor. 255 lerden dönüp geliyor.
aşağıdaki kodları  adc den okunan değerlere göre sıra ile yanıp sönen ledlere çevirebilir misiniz?
Aynı cep telefonundaki şarj çubuğu gibi. Belki o zaman tam anlayabilirim. Lütfen.
Açıkcası kendimi de veremiyorum bugün nedense! Konuyu tam anladıktan sonra kütüphaneme koyacağım ama bu şekilde koyup atlamak istemiyorum.
BASLA:
T1CON=%00110001
KES=10
B0=1

 
BASLA_BIR:
TMR1H=$FF:TMR1L=$39:PIR1.0=0  '100mS önyükleme(8 mHz de 1/8 ORANDA 65337)

WHILE PIR1.0=0
'buraya bütün programı koy yada belirli bir aşamadan sonraki program parçasını koy
    Adcin 0 ,x
    gosub ekran
WEND
Kes=Kes-1 
if KES>0 then BASLA_BIR
 
'program buraya geldiğinde 1000 ms dolmuş olacak.
'İşte burada ledleri varsa buzzeri şayet aktif iseler toggle yapacaksın.
 
toggle b0  

GOTO BASLA_BIR


  EKRAN:
	    lcdout $FE,$80,"ADC 0 :",DEC4 X   ,"  "        'okunan o,pot değerini ekrana yazdırmak
        lcdout $FE,$C0,"PIR1.0:",DEC PIR1.0   ,"  "':pause 150
        LCDOUT $FE,$90,"KES :",#KES,"  "        
        RETURN
"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

Bu istediğinin konu ile hiç alakası yok. Nedemek sıra ile yanan ledler????
Bunu yapmayacağım kusura bakma. Kendin yap o işi. Çok akıllısın ancak başka işlere çalıştırıyorsun kafanı.!!!!!!

Yazdığın kodlarda zamanlama hatası var.
OSC frekansın 8 Mhz ise 100 ms lik dilim için ön yükleme değerin 40536 olmalı ve onunda hex karşılığı 9E58 dir.

Bu bir algoritma çalışması yada açıklaması. Bunu uygulamak için belirli bir senaryon yada amacın olmalı. Ben sana GOTO BASLA yı nereye koyacağını global olarak anlattım. Anlamıyorsan bu konuda bir uygulama yapmadığın içindir. Aslında bu bilgiler senin için fazla daha tam anlamı ile program yazmayı henüz bilmiyorsun üzerinde çalışman lazım. Zamanla bu dediklerimide anlayacak ve kafanda tyer bulacaktır. O zaman neyi nereye koyacağını daha rahat bulursun diye düşünüyorum.
BUnları bana kimse öğretmedi. Her şeyi kendi kendime öğrendim hala daha öğreniyorum yeni şeyler yeni taktikler.

Programdaki bir kusur da kes değişkeni sıfırlandığı zaman yeniden 10 değerini almalı ki aynı işleri yapabilsin. O halde Toggle komutundan sonra GOTO BASLA_BIR yerine GOTO BASLA demen yada Toggle dan sonra KES=10 : GOTO BASLA_BIR yazman gerekir. Bunları mantık yolu ile düşünebilmen gerekiyor. Her satırda kim ne yapıyor bir sonraki satıra geçince ne oluyor bunları mantık incelemesinden geçirmen lazım ancak bu şekilde işin mantığı kafana oturur.

Ete

elektro77

#7
Alıntı yapılan: ete - 10 Ekim 2022, 15:34:20Bu istediğinin konu ile hiç alakası yok. Nedemek sıra ile yanan ledler????
Bunu yapmayacağım kusura bakma. Kendin yap o işi. Çok akıllısın ancak başka işlere çalıştırıyorsun kafanı.!!!!!!

Yazdığın kodlarda zamanlama hatası var.
OSC frekansın 8 Mhz ise 100 ms lik dilim için ön yükleme değerin 40536 olmalı ve onunda hex karşılığı 9E58 dir.

Bu bir algoritma çalışması yada açıklaması. Bunu uygulamak için belirli bir senaryon yada amacın olmalı. Ben sana GOTO BASLA yı nereye koyacağını global olarak anlattım. Anlamıyorsan bu konuda bir uygulama yapmadığın içindir. Aslında bu bilgiler senin için fazla daha tam anlamı ile program yazmayı henüz bilmiyorsun üzerinde çalışman lazım. Zamanla bu dediklerimide anlayacak ve kafanda tyer bulacaktır. O zaman neyi nereye koyacağını daha rahat bulursun diye düşünüyorum.
BUnları bana kimse öğretmedi. Her şeyi kendi kendime öğrendim hala daha öğreniyorum yeni şeyler yeni taktikler.

Programdaki bir kusur da kes değişkeni sıfırlandığı zaman yeniden 10 değerini almalı ki aynı işleri yapabilsin. O halde Toggle komutundan sonra GOTO BASLA_BIR yerine GOTO BASLA demen yada Toggle dan sonra KES=10 : GOTO BASLA_BIR yazman gerekir. Bunları mantık yolu ile düşünebilmen gerekiyor. Her satırda kim ne yapıyor bir sonraki satıra geçince ne oluyor bunları mantık incelemesinden geçirmen lazım ancak bu şekilde işin mantığı kafana oturur.

Ete

Hocam baştan beri bana ne dedi iseniz onu yapmaya çalışıyorum. Ben çocuk kilidi çalışmamda sıra ile yanan ledler yapmaya çalışıyorken siz timer1 i bana önerdiniz. Tımer1 ile bu iş olmayacaksa neden önerdiniz? Son zamanlarda sorulan soruları tam okumadan geçiştirdiğinizi düşünmeye başladım. Eksik bilgi vererek kafamı karıştırıyorsunuz. Bu yazdıklarımı da sakın yanlış algılamayın, sadece açık sözlülüktür. Tabi ki işiniz olabilir tek işiniz biz olmayabiliriz ama baştan beri siz ne dedi iseniz nereye ne yaz dedi iseniz onu yapmaya çalışıyorum. Amacım sadece öğrenmeye çalışmak. Para amaçlı bir proje yaptığım falan yok. Sadece öğrenmek. Boş zamanlarımı değerlendirmek.
Başka şeylere kafamın çalışıyor olması ile ne demek istediğinizi açıklarsanız beni düşünmekten kurtarırsınız.
"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

Amacın ledleri yakmak olabilir ama bu amacı gerçekleştirecek bir kod şekli göremedim.
Ben neye göre yapacağım bu işi?.
"aşağıdaki kodları  adc den okunan değerlere göre sıra ile yanıp sönen ledlere çevirebilir misiniz?"
bu işin bir senaryosu olur ve bende o senaryoya göre bir şeyler yazarım. Burada kafama göre bir şey yapacak durumda değilim. Anlamadığım şeyide yapamam.
Timer konusunu çalışırken birden lede döndün. Sana daha önce bu led işininde nasıl yapılacağını söylemiştim. Biraz çalışsan denemeler yapsan olmazmı? Yok her zamanki gibi kesitimeden direk amacına ulaşmaya çalışıyorsun sonra benzer konularda yeniden çuvallıyorsun.
Aklın başka işlere çalışıyordaki söylemim sürekli kırk dalda iş yapmana dayanıyor Bir şeyi başlamış isen onu bitirmeden başka konuya geçme yada geçmemelisin. Elbette akıl senin kafa senin  istediğini yaparsın ama açıklarını bana kapattırmamalısın. Ben elimden geldiğince sana bilgi verme konusunda yardımcı olmaya çalışıyorum. Amacım bir şeyler öğrenmen. Kestirmeye sapınca bozuluyorum. Buda benim davranışım kimse mükemmel değildir.

Ete

elektro77

Hocam senaryonun tamamını verdim size çocuk kilidi konusunda.  Ama okuyamayacağınızı söylediniz.O konunun devamı ve yeni başlayanlara faydası olsun diye timer1 örneği olarak yeniden başlık açtım.
Ayrıca Kodu yarım verince de kızıyorsunuz. Ne yapacağımı şaşırdım valla.
Yine de özür dilerim.
"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

#10
Timer 1 i anlamak için bu güne kadar ki tüm projelerimi ve projelerinizi inceleyip bir örnek aradım.
en az 50 proje kodu taradım. Malesef sadece 2 örnek bulabildim. birisinde kod döngü sürelerini ölçmüşsünüz birinde de ne yaptığınızı çok anlamlandıramadım. Bana önerdiklerinizde ise yeni yöntemler denediğiniz kesin. Çünkü bana önerdiğiniz şekilde hiç bir proje göremedim.
bulduklarımdan biri bu:
'------------------------------------------------------------------------
@ DEVICE PIC16f877A
@ DEVICE PIC16f877A, WDT_OFF
@ DEVICE PIC16f877A, BOD_ON
@ DEVICE PIC16f877A, PWRT_ON
@ DEVICE PIC16f877A, PROTECT_OFF
@ DEVICE PIC16f877A, HS_OSC
'------------------------------------------------------------------------
define OSC 10
PORTA=0:TRISA=0
PORTB=0:TRISB=%11111111
PORTC=0:TRISC=0
PORTD=0:TRISD=0
PORTE=0:TRISE=%000000100
CMCON=7
ADCON1=7
OPTION_REG.7=0

DEFINE I2C_SLOW 1      ' 8Mhz den yüksek karistal frekanslarında bu komutu kullanmak zorundayız.
DEFINE I2C_SDA PORTE,1 'I2C data pini tanımlaması  
DEFINE I2C_SCL PORTE,0 'I2C CLK pini tanımlaması

DEFINE LCD_DREG  PORTD      '
DEFINE LCD_DBIT  4
DEFINE LCD_EREG  PORTD
DEFINE LCD_EBIT  3
DEFINE LCD_RSREG PORTD 
DEFINE LCD_RSBIT 2
DEFINE LCD_BITS  4
DEFINE LCD_LINES 4
'------------------------------------------------------------------------
SN      VAR BYTE 56
DAK    VAR BYTE 57
ACIK    VAR BYTE 58
KAPALI  VAR BYTE 59
SAAT    VAR BYTE 60
ESKISN  VAR BYTE 61
AYGUN  VAR BYTE 62
AY      VAR BYTE 63
YIL    VAR BYTE 64 
HAFGUN  VAR BYTE 65
SECOND  VAR BYTE 66
HOUR    VAR BYTE 67
MINUTE  VAR BYTE 68
WEEK    VAR BYTE 69
DAY    VAR BYTE 70
MONTH  VAR BYTE 71
YEAR    VAR BYTE 72
TEMP    VAR BYTE 73                  
HIZA    var BYTE 74
HIZB    VAR BYTE 75
I      VAR BYTE 76
SAYAC  VAR WORD 77
ARA    VAR BYTE 79


SYMBOL AKTIF=ARA.0 '  VAR Byte 79'  BIT  'FAN MOTORU ÇALIŞTIRILMIŞ İSE AKTIF=1 OLACAK DEĞİLSE AKTİF=0 OLACAK ZAMAN KONTROLÜ İÇİN GEREKLİ

SYMBOL MENU=PORTB.0
SYMBOL SEC =PORTB.1
SYMBOL YUKARI=PORTB.2
SYMBOL ASAGI =PORTB.3
SYMBOL F1 =PORTB.4      'FONKSIYON TUSLARI
SYMBOL F2 =PORTB.5 
SYMBOL F3 =PORTB.6
SYMBOL F4 =PORTB.7 
SYMBOL ELVTR=PORTA.0  'ROLE1
SYMBOL MKINA=PORTA.1  'ROLE2
SYMBOL FAN = PORTA.2  'ROLE3 
SYMBOL LAMP= PORTA.3  'ROLE4
SYMBOL SCL  =PORTE.0
SYMBOL SDA  =PORTE.1
SYMBOL KENAR=PORTE.2
'------------------------------------------------------------------------
PORTB=0
PORTD=0
PORTE=0
PORTA=0

'LCDOUT $FE, $40, $00, $00, $11, $0A, $04, $0A, $11, $00 ' 
'LCDOUT $FE, $48, $00, $00, $00, $01, $02, $14, $08, $00 ' 

LCDOUT $FE, $40,$00, $0E, $11, $11, $11, $11, $0E, $00 '
LCDOUT $FE, $48, $04, $11, $0E, $1F, $0E, $11, $04, $00 ' 

pause 200
LCDOUT $FE,1
PAUSE 300
LCDOUT $FE,$80," BIR ETE PROJESIDIR "
LCDOUT $FE,$C0," BU PROJE ALGORITMA "
LCDOUT $FE,$94," GELISTIRMEK AMACI  "
LCDOUT $FE,$D4,"    URETILMISTIR    "
PAUSE 1000
clear
READ 10,ACIK
IF ACIK=255 THEN ACIK=1
READ 11,KAPALI
IF KAPALI=255 THEN KAPALI=1

READ 12,HIZA:IF HIZA=255 THEN HIZA=5
READ 13,HIZB:IF HIZB=255 THEN HIZB=5

LCDOUT $FE,1
SDA=1:SCL=1
'------------------------------------------------------------------------
BASLA: 
    
    FOR I=0 TO 10
'    T1CON=%00110001:TMR1L=0:TMR1H=0    
      GOSUB EKRAN_BASLA
      IF F1=0 then
        ELVTR=1-ELVTR
        WHILE F1=0:WEND
        pause 10
      ENDIF
      
      PAUSE 5
      
      IF F2=0 then
        MKINA=1-MKINA
        WHILE F2=0:WEND
        pause 10        
      ENDIF
      
      PAUSE 5
      
      IF F3=0 THEN
        IF AKTIF=1 THEN 
            FAN=0
            AKTIF=0
            SN=0:DAK=0
            WHILE F3=0:WEND
            GOTO BASLA
        ENDIF  
        FAN=1-FAN
        IF FAN=1 THEN 
          AKTIF=1
          GOSUB ZAMANAC
        else
          AKTIF=0  
        ENDIF  
        WHILE F3=0:WEND
        PAUSE 10        
      ENDIF  
      
      PAUSE 5
      
      IF F4=0 THEN    
        LAMP=1-LAMP          
        WHILE F4=0:WEND
        PAUSE 10
      ENDIF  
      
      IF MENU=0 THEN AYAR  
' T1CON=0:SAYAC.byte0=TMR1L:SAYAC.Byte1=TMR1H:PIR1.0=0            
    NEXT 

 'BURDAN GERİSİ YAKLAŞIK 30 MS SÜRÜYOR  
      IF AKTIF=1 THEN  'FAN MOTORU AKTİF İSE YANİ ÇALIŞTIRILMIŞ İSE
        GOSUB ZAMANOKU
        IF FAN=1 AND DAK=ACIK THEN
            FAN=0
            GOSUB ZAMANAC
        ENDIF
            
        IF FAN=0 AND DAK=KAPALI THEN
            FAN=1
            GOSUB ZAMANAC
        ENDIF
      ENDIF                      
      PAUSE 5
      
      goto basla

ZAMANAC:
        SECOND=0:MINUTE=0:ESKISN=255:SN=0:DAK=0
        GOSUB ZAMANYAZ
        RETURN
EKRAN_BASLA:  '12345678901234567890"
LCDOUT $FE,$02," F1  F2  F3  F4  "
lcdout $fe,$C0,"ELVT MKIN FFAN LAMP "
LCDOUT $FE,$95,ELVTR,ELVTR,"  ",MKINA,MKINA,"  ",AKTIF,AKTIF,"  ",LAMP,LAMP 

LCDOUT $FE,$D4,"  MENU= AYARLAR    "
RETURN

EKRAN_AYAR:
          lcdout $fe,$02," - ELEVATOR HIZ KONT"
          LCDOUT $fe,$C0," - MAKINA HIZ KONTR."
          lcdout $fe,$94," - ROLE-1 ZAMAN AYAR"
          lcdout $fe,$d4," - AYAR MENUSU CIKIS"
          RETURN
          

HIZ_BIR:  'ELEVATOR HIZ AYARI
        IF YUKARI=0 THEN
          HIZA=HIZA+1
          IF HIZA=16 then HIZA=15
          PAUSE 50
          WHILE YUKARI=0:WEND
        ENDIF  
        
        IF ASAGI=0 THEN
            HIZA=HIZA-1
            IF HIZA=255 THEN HIZA=0
            PAUSE 50
            WHILE ASAGI=0:WEND
        ENDIF    
        PORTC=(PORTC & %11110000)+HIZA
        RETURN
        
HIZ_IKI:  'MAKINA HIZ AYARI
        IF YUKARI=0 THEN
          HIZB=HIZB+1
          IF HIZB=16 then HIZB=15
          PAUSE 50
          WHILE YUKARI=0:WEND
        ENDIF  
        
        IF ASAGI=0 THEN
            HIZB=HIZB-1
            IF HIZB=255 THEN HIZB=0
            PAUSE 50
            WHILE ASAGI=0:WEND
        ENDIF    
        PORTC=(PORTC & %00001111)+HIZB<<4
        RETURN

 AYAR:  TEMP=PORTA & %00001111:PORTA=0
      gosub ekran_AYAR
      WHILE MENU=0:WEND

AYARBIR:
        lcdout $fe,$02,"<->":pause 150:lcdout $fe,$80," - ":PAUSE 150
        IF ASAGI=0 THEN AYARIKI
        IF YUKARI=0 THEN AYARDORT
        IF SEC=0 THEN BIREBIR          
        goto AYARBIR

AYARIKI:
        lcdout $fe,$C0,"<->":pause 150:lcdout $fe,$C0," - ":PAUSE 150
        IF ASAGI=0 THEN AYARUC
        IF YUKARI=0 THEN AYARBIR
        IF SEC=0 THEN IKIBIR    
        goto AYARIKI    
        
AYARUC:
        lcdout $fe,$94,"<->":pause 150:lcdout $fe,$94," - ":PAUSE 150
        IF ASAGI=0 THEN AYARDORT
        IF YUKARI=0 THEN AYARIKI
        IF SEC=0 THEN UCBIR    
        goto AYARUC

AYARDORT:
        lcdout $fe,$D4,"<->":pause 150:lcdout $fe,$D4," - ":PAUSE 150
        IF ASAGI=0 THEN AYARBIR
        IF YUKARI=0 THEN AYARUC
        IF SEC=0 THEN CIKIS  
        goto AYARDORT
                    
BIREBIR: gosub TEMIZLE
      LCDOUT $FE,$80,"ELEVATOR HIZ KONTROL"
      LCDOUT $FE,$C0,"YUKARI= +  ASAGI= -"      
      WHILE SEC=0:WEND
BIREIKI:
      LCDOUT $FE,$9B,"HIZ= ",DEC HIZa,"  "
      LCDOUT $FE,$D4," CIKIS SEC TUSU ILE "
      GOSUB HIZ_BIR
      IF SEC=0 THEN
          WRITE 12,HIZA:PAUSE 10
          GOTO CIKIS
      ENDIF  
      GOTO BIREIKI
      
IKIBIR:
      gosub TEMIZLE
      LCDOUT $FE,$80," MAKINA HIZ KONTROL "
      LCDOUT $FE,$C0,"YUKARI= +  ASAGI= -"      
      WHILE SEC=0:WEND
IKIYEIKI:
      LCDOUT $FE,$9B,"HIZ= ",DEC HIZB,"  "
      LCDOUT $FE,$D4," CIKIS SEC TUSU ILE "
      GOSUB HIZ_IKI
      IF SEC=0 THEN
        WRITE 13,HIZB:PAUSE 10
        GOTO CIKIS
      ENDIF  
      GOTO IKIYEIKI


UCBIR:
      GOSUB TEMIZLE
      LCDOUT $FE,$80,"ROLE-1 ZAMAN AYARLAR"
      LCDOUT $FE,$C0,"YUKARI= +  ASAGI= -" 
      LCDOUT $FE,$94,"ROLE=  ACIK  KAPALI" 
      LCDOUT $FE,$D4,"DAK.="
      WHILE SEC=0:WEND
UCEIKI:            
      LCDOUT $FE,$DD,$FE,$0E:PAUSE 100:LCDOUT $FE,$0C:PAUSE 100
      LCDOUT $FE,$DC,DEC2 ACIK
      IF YUKARI=0 THEN
        ACIK=ACIK+1:IF ACIK>99 THEN ACIK=99
        WHILE YUKARI=0:WEND
      ENDIF
        
      IF ASAGI=0 THEN
          ACIK=ACIK-1:IF ACIK=255 THEN ACIK=0
          WHILE ASAGI=0:WEND
      ENDIF
      IF SEC=0 THEN 
          WHILE SEC=0:WEND
          GOTO UCEUC
      ENDIF  
      GOTO UCEIKI
      
UCEUC:
      LCDOUT $FE,$E5,$FE,$0E:PAUSE 100:LCDOUT $FE,$0C:PAUSE 100
      LCDOUT $FE,$E4,DEC2 KAPALI
      IF YUKARI=0 THEN
        KAPALI=KAPALI+1:IF KAPALI>99 THEN KAPALI=99
        WHILE YUKARI=0:WEND
      ENDIF
        
      IF ASAGI=0 THEN
          KAPALI=KAPALI-1:IF KAPALI=255 THEN KAPALI=0
          WHILE ASAGI=0:WEND
      ENDIF
      IF SEC=0 THEN 
        WRITE 10,ACIK:PAUSE 10
        WRITE 11,KAPALI:PAUSE 10
        GOTO CIKIS
      ENDIF  
      GOTO UCEUC              
      

TEMIZLE:
      LCDOUT $FE,1:RETURN
      
CIKIS:
      GOSUB TEMIZLE      
      WHILE SEC=0:WEND
      PAUSE 100
      PORTA=TEMP
      GOTO BASLA
      

ZAMANOKU:
        I2CRead SDA,SCL,$D0,$00,[SECOND,MINUTE]
        SN =((SECOND>>4) & %00001111)*10+(SECOND & %00001111)
        dak=((MINUTE>>4) & %00001111)*10+(MINUTE & %00001111)
        
        RETURN 
                      
ZAMANYAZ: 
    
        I2CWrite SDA,SCL,$D0,$00,[SECOND]
        I2CWrite SDA,SCL,$D0,$01,[MINUTE]
        I2CWrite SDA,SCL,$D0,$07,[16]
        PAUSE 10
        RETURN 


diğeride bu:
#CONFIG
  __CONFIG _CP_ALL & _WRT_256 & _CPD_ON & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
#ENDCONFIG  
 '-------------------------------------------------------------------------------
define OSC 4
DEFINE LCD_DREG        PORTC    'LCD data bacakları hangi porta bağlı?
DEFINE LCD_DBIT        4        'LCD data bacakları hangi bitten başlıyor?
DEFINE LCD_EREG        PORTC    'LCD Enable Bacağı Hangi Porta bağlı?
DEFINE LCD_EBIT        3        'LCD Enable Bacağı Hangi bite bağlı ?
DEFINE LCD_RSREG      PORTC    'LCD RS Bacağı Hangi Porta bağlı ?
DEFINE LCD_RSBIT      2        'LCD RS bacağı Hangi Bite bağlı  ?
DEFINE LCD_BITS        4        'LCD 4 bit mi yoksa 8 bit olarak bağlı?
DEFINE LCD_LINES      2        'LCD Kaç sıra yazabiliyor

DEFINE LCD_COMMANDUS  2000    'Command delay time in us 
DEFINE LCD_DATAUS      50      'Data delay time in us

'-------------------------------------------------------------------------------
 TRISA=%00000111
 TRISB=%01110000
 TRISC=%00000000
 portb=0
 PORTC=0
 '------------------------------------------------------------------
ADCON1=%10001110                '7. bit 1 yapıldı 10 bit sonuç almak için.
INTCON=%11001000                'PORTB değişiklik kesmesi aktif
'T1CON =%00000000                'Bölme oranı 1/1yapılacak
CMCON=7 
'-------------------------------------------------------------------------------
symbol faz_R=portB.4
symbol faz_S=portB.5
symbol faz_T=portB.6

FAZ VAR  BYTE 56
SIRA VAR BYTE 57
KONT var byte
TEMP VAR BYTE
SAY VAR BYTE
OLD VAR BYTE
BUL VAR BYTE

W VAR WORD  
Z VAR BIT
ILK VAR BIT
'---------------------------------------------------------------
LCDOUT $FE,1
PAUSE 250
LCDOUT $FE,$80,"LUTFEN  BEKLEYIN"
PAUSE 1000
KONT=2
TEMP=PORTB
ON INTERRUPT GOTO KESME

'TMr1=$9E5F (40543 desimal
 OLD=FAZ
 T1CON=%00000001
      TMR1H=$E4:TMR1L=$C5
  PIR1.0=0
  OLD=123
  SIRA=0
BASLA:
'      IF SIRA=1 THEN
'        LCDOUT $FE,1,"KONT=",DEC KONT
'      ENDIF  
      
      LCDOUT $FE,$C0," FAZ=",DEC FAZ'," KONT=",DEC KONT
      IF FAZ=123 AND OLD=FAZ THEN
        LCDOUT $FE,$80,"FAZ SIRASI:R-S-T"
        OLD=FAZ
        GOSUB DELAY
      ENDIF
          
      IF FAZ=132 THEN
        LCDOUT  $FE,$80,"FAZ SIRASI:R-T-S"
        OLD=FAZ
        GOSUB DELAY
      ENDIF
      
      IF PIR1.0=1 THEN
        Z=0:INTCON=0:
        WHILE 1
          IF Z=0 THEN 
            LCDOUT $FE,$80,"DIKKAT FAZ EKSIK"
          ELSE
            LCDOUT $FE,$80,REP 32\16  
          ENDIF  
          PAUSE 150
          TOGGLE Z
        WEND        
'        LCDOUT $FE,$C0," FAZ=",DEC FAZ," SAY=",DEC SAY,"  "
      ENDIF

      GOTO BASLA
        
DELAY:
      FOR W=0 TO 1000:NEXT  
      RETURN        
                
      ' R  S  T                R T S    S R T    S T R    T R S    T S R
      ' 1  2  3  1  2  3      132132    213213    231231    312312    321321

DISABLE
KESME:
      SIRA=SIRA+1:IF SIRA=4 then SIRA=0
      IF FAZ_R=1 THEN '1            123 132 321 312 213 231  RST RTS SRT STR TSR TRS 
        IF SIRA=0 THEN SIRA=1
'        If kont=3 then BUL=1
'        If kont=2 THEN BUL=3
        KONT=1
      ENDIF
      
      IF FAZ_S=1 THEN  '2
        IF KONT=1 THEN FAZ=12
        IF KONT=3 THEN FAZ=13                
        KONT=2
      ENDIF  
      
      IF FAZ_t=1 THEN  '3
        IF KONT=2 THEN FAZ=123
        IF KONT=1 THEN FAZ=132                
        KONT=3
      ENDIF 
      
      TMR1H=$E4:TMR1L=$C5 '67 ÇALIŞIYOR

      TEMP=PORTB
      INTCON.0=0      
      RESUME 
      ENABLE
Bu timer1 konusu kafamı allak bullak etti. Bu güne kadar neredeyse hiçbir şey öğrenmemişim gibi hissediyorum.
Aşağıdaki gibi bir uygulama da ben yapmaya çalıştım.
Senaryo şöyle. Isı belirlenen sınırı aştığında buzzer alarm veriyor. Isıyı simülasyondaki pot temsil ediyor. O anda led ve buzzer wend den sonraki kodlardan bağımsız kullanılabiliyor. Bilmiyorum bir mantık hatam var mı? Çünkü, saat ve ısı entegreleri hariç, hala timer 1 in nerelerde kullanılabileceğini aklım almadı. Anlamadığım bir şey daha var: Timer1 içindeki gosub-return dallanmaları timer 1 süresini ne oranda etkiliyor?  Kodlar aşağıdadır. Simülasyon ise ektedir..
#config
 __Config _XT_OSC  &  _WDT_OFF &_PWRTE_OFF &_BODEN_OFF &_CP_ON &_CPD_OFF &_LVP_OFF 
#ENDCONFIG
'------------------
define OSC 4
'ADCON1=7              'ADC KANALLARI DİJİTAL YAPILDI - ADC İPTAL
ADCON1=%10000010      '5 KANAL ADC AKTİF EDİLDİ.
CMCON=7              'komparatör pinleri iptal hepsi giriş çıkış yapıldı.
OPTION_REG.7=1        'portB deki dahili PULL-UP lar AKTİF edildi. OPTION_REG.7=1 İSE PULLUPLAR PASİF
'------------------
 TRISA=%00011111      'ADC OKUNACAK PİNLER GİRİŞ YAPILDI
 TRISB=%10000000      'Portb nin tamamı GİRİŞ olarak ayarlandı
 TRISC=%00000011      'portc deki bazı pinler giriş olarak ayarlandı
 PORTA=%00000000
 PORTB=%00000000
 PORTC=%00000000
'-------------------
DEFINE LCD_DREG        PORTC    
DEFINE LCD_DBIT        0        
DEFINE LCD_RSREG    PORTC    
DEFINE LCD_RSBIT    5    
DEFINE LCD_EREG        PORTC    
DEFINE LCD_EBIT        4        
DEFINE LCD_BITS        4    
DEFINE LCD_LINES    4
DEFINE LCD_COMMANDUS  2000    'Command delay time in us 
DEFINE LCD_DATAUS      50      'Data delay time in us
 '-------------------------------------------------------------------------------
DEFINE ADC_BITS        10      'A/D çevirim sonucu kaç bit olacak
DEFINE ADC_CLOCK      5        'Clock kaynağı (5=FOSC/16)
DEFINE ADC_SAMPLEUS    20      'Örnekleme zamanı mikro saniye cinsinden.
'-------------------------------------------------------------------------------      
SAYI var word: SAYI=0
HAM  VAR WORD '0. KANAL ADC DEĞİŞKENİNİN YAZILDIĞI DEĞER
'Y    VAR WORD '1. KANAL ADC DEĞİŞKENİNİN YAZILDIĞI DEĞER
KES VAR byte
P VAR WORD
symbol B0        =portB.0
symbol LED1      =portB.2
symbol LED2      =portB.4
symbol LED3      =portB.6
symbol tus        =portb.7
symbol BUZZER    =portC.7

lcdout $FE,1 
pause 300
'-------------------------------------------------------------------------------

BASLA:
T1CON=%00110001                'TİMER 1 AKTİF EDİLİR VE BÖLME ORANI 1/8 AYARLANIR
KES=4                          'Daha uzun süreler elde etmek için kullanılır
B0=1
'-------------------------------------------------------------------------------

BASLA_BIR:
TMR1H=$CF:TMR1L=$2C:PIR1.0=0  '100mS önyükleme(4 mHz de 1/8 ORANDA)
WHILE PIR1.0=0                'buradan alta bütün programı koy yada belirli bir aşamadan sonraki program parçasını koy

Adcin 0 ,HAM
IF HAM>800 THEN                'Ham 800 den büyükse alarm devreye giriyor
BUZZER=1
ENDIF
  IF tus=1 then                'alarm sireni çalarken tuş ile işlm yapılabiliyor. ve led1 açılıyor
  WHILE TUS=1:WEND 
  LED1=1:BUZZER=1              'alarm devrede ilen tuşa basıldı ise buzzer 1 kere ses veriyor.
  ENDIF


GOSUB EKRAN
WEND                          'program buraya geldiğinde 400 ms dolmuş olacak. İşte burada ledleri varsa buzzeri şayet aktif iseler toggle yapacaksın.
Kes=Kes-1 
if KES>0 then BASLA_BIR


IF BUZZER =1 THEN BUZZER=0:PAUSE 50
IF LED1=1 THEN TOGGLE LED1
toggle b0
GOSUB EKRAN

KES=4
GOTO BASLA_BIR                        


'GOTO BASLA
'-------------------------------------------------------------------------------



EKRAN:
lcdout $FE,$80,"ADC 0 :",#HAM  ,"  "'okunan o,pot değerini ekrana yazdırmak
lcdout $FE,$C0,"PIR1.0:",#PIR1.0,"  "':pause 50
LCDOUT $FE,$90,"KES  :",#KES  ,"  "        
RETURN
"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

Her projede Timer kullanılacak diye bir kanun yok.
Ben gereken yerlerde sürekli kullanıyorum. Buda yeni bir mantık eski projelerde kullanmamış olabilirim.
Önemli olan nasıl işe yaradığı ki onuda anlatmaya çalıştım.

Konumu zaten Timer-1 kullanmak değil Timer-1'i bahsini ettiğim amaçla kullanmak bizim konumuz.

Hala anlamadığında bahsediyorsun bu bilgi eksikliğin var anlamına geliyor.
ELinde 4 adet ledin var ve her biri farklı nedenlerle flash yapmak zorunda.
Ana programı aksatmadan bunları nasıl flash yaptırırsın.?

Senin ilk verdiğin kod da gösterdiğin şekilde.
Led1=1:pause 100:led1=0:pause 100
Led2=1:Pause 100:led2=0:pause 100
şeklinde 4 ledi yaparsan kodun son lede ulaşması için 600 ms geçmesi gerekecek. Bu sence mantıklımı.?
Sana söylemiştim AKTIF diye bir değişken tanımlarsın. Bunun 0 nolu biti Led1 in falsh yapacağını belirler. 1 ise flash yap 0 ise yapma gibi.
1 nolu bit led2 yi, 2 nolu bit led3'ü ve 3 nolu bit de led4 ün flash durumunu belirler.
AKTIF=%00001011 şekinde değer aldığını varsayalım. Bu ne anlama gelecek. Led4, Led2 ve Led1 flash yapacak demektir.
Timer döngümüzü 150 ms üzerinden kurduk diyelim. Her, WEND komut satırını aştığımızda 150 ms geçmiş olacak buda bizim flash hızımız oalcak.
Wend satırından hemen sonra,
IF AKTIF.0=1 then TOGGLE LED1
IF AKTIF.1=1 then TOGGLE LED2
IF AKTIF.2=1 Then TOGGLE LED3
IF AKTIF.3=1 Then TOGGLE LED4
yazarsan bu ledler program çalışırken flash yapacaklardır. Üstelik her biri diğerini süre olarak etkilemeden. İstediğimzide bu değilmi?

Timer döngüsü kurduğun süre kadar çalışır. Bu süre sen başka bir etikete gosub ile gitsen bile çalışmaya devam eder. O halde dikkat edilecek nokta şu olmalı. Gittiğin yerlerden çok kısa sürelerde dönmelisin. Pause vs olan yerlere gidersen PIR.1=1 çoktan olmuş olabilir. Mümkünse her şeyi bu döngü içinde halletmelisin. Gitmek ve uzun süre oralarda kalmak zorunda ise Timer kullanma derim. Bu sorunun cevabınıda mantık olarak düşünmen gerekirdi.

Bu örnek ve açıklamalardan sonra halâ Timer-1 yararını anlamadın ise yapacağım bir şey yok bu konuyu kapatıryorum artık.

Ete

Powered by EzPortal