18F4520 de timer hakkında

Başlatan tamerugur, 04 Mayıs 2012, 23:21:10

tamerugur

Arkadaşlar Meerhaba...
şöyle bir problemim var, yapacağım devrede 2 timer kullanmam lazım. timer0 0-59 saniye arasında sayacak ve eeproma yüklediğim değere gelince programda belirttiğim yere dallanacak. timer1 ise 0-25 dakika arasında sayacak ve eeproma yüklediğim değere gelince programda istediğim yere dallanacak. yalnız timer1 de dakika ve saniye bazında işlem yapacağım.
timer1 kısmında sorunum yok fakat timer0'ı kullanmayı beceremedim. program aşağıda. yardımcı olacak ve ilgilenecek arkadaşlarıma şimdiden teşekkür ederim.

#include <18f452.h>
#device ADC=10
#fuses HS,PROTECT,NOBROWNOUT,NOPUT,NOWRT,NODEBUG,CPD,NOWDT,NOLVP
#use delay (clock=4000000)
#define kirmizi pin_c2
#define yesil pin_c0
#define sari pin_c1
#define start      pin_d0

float voltaj0=0,topvolt=0,gerilim=0,gerilim1=0,topvolt1=0;
unsigned long int bilgi0=0;
signed int8 tm,tm1,tm2,tm3,a1,v1,a,v;
int32 ms=0,ms1=0,t1=15575,t0=60;
unsigned int8 saniye=0,dakika=0,saniye1=0,dakika1=0;
#int_timer0 //timer0 kesmesi
void timer0_kesme()
{
set_timer0(t0); //timer0 degeri belirleniyor
ms1++;

            if(ms1==100)
            {
            ms1=0;
            saniye1++;
            }
                     if(saniye1==60);
                     {
                     saniye1=0;
                     
                     }
}
#int_timer1
void  timer1_kesme ()
{
    set_timer1(t1);   
    ms++;           
    if (ms==100)
    {
       ms=0;
       saniye++;
         if(saniye==60)
         {
         saniye=0;
         dakika++;
            if(dakika==60)
            {
               dakika=0;
            }
         }
    }
}
void main()
{
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);   
   setup_timer_2(T1_DISABLED,0,1);   
   setup_adc(adc_clock_div_32);
   setup_adc_ports(A_ANALOG);
   
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1); // Timer0 ayarları yapılıyor
   set_timer0(t0);   // TMR0 değeri belirleniyor
   
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); // Timer1 ayarları yapılıyor
   set_timer1(t1);   // TMR1 değeri belirleniyor
   enable_interrupts(INT_timer0); // int_timer0 kesmesini aktif yapar
   enable_interrupts(INT_timer1); // int_timer1 kesmesini aktif yapar
   enable_interrupts(GLOBAL);     // Aktif edilen kesmelere izin ver

basla:
                     if(input(start)==1)
                    {
adim1:
                                                if(saniye1==tm)                                  //tm eeproma yazılan iki basamaklı tam sayı örnegin 35
                                                {
                                                output_high(sari);
                                                goto adim2;
                                                }
                                                else
                                                {
                                                   goto adim1;
                                                }
adim2:
                                                if(dakika==tm1)&&(saniye==tm2)   //tm1 eeproma yazılan iki basamaklı dakika örnegin 15
                                                 {                                                    //tm2 eeproma yazılan iki basamaklı saniye örneğin 18
                                                    output_low(sari);
                                                    output_high(kirmizi);
                                                    goto bitis;
                                                  }
                                                 else
                                                 {
                                                  goto adim2;
                                                  }
bitis:
output_low(sari);
output_low(kirmizi);
output_high(yesil);
dakika1=0
saniye1=0
saniye=0
goto basla;
}
}

justice_for_all

18f serilerinde timer0 8bit veya 16bit kullanilabilir buyuk ihtimal seninki 16bit calisiyor olabilir.
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

yldzelektronik

Hs osc demişsin ama 4 mhz tanımlamışsın?
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

tamerugur

Alıntı yapılan: yldzelektronik - 06 Mayıs 2012, 11:59:47
Hs osc demişsin ama 4 mhz tanımlamışsın?

doğru söylüyosun ama 20 mhz de lcd hatalı çalışıyor. dahili osilatörde kullansam sonuç aynı.

yldzelektronik

Hs yazdıysan sanırım 10 mhz üstü delay tanımlamalısın.4 mhz kullanıcaksan xt tanımlaman gerekli.Bunları denedin mi bilmiyorum.Birde 18f45k20 de timer1 osc kaynağı olarak seçiliyodu.Böyle gıcık durumları da gözden geçir derim.Hoş osc kaynağı seçilebilmesi tam olarak neyi ifade ediyor bilmiyorum ama pll için kullanıldığını okumuştum datasheette.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

tamerugur

Alıntı yapılan: yldzelektronik - 07 Mayıs 2012, 09:47:08
Hs yazdıysan sanırım 10 mhz üstü delay tanımlamalısın.4 mhz kullanıcaksan xt tanımlaman gerekli.Bunları denedin mi bilmiyorum.Birde 18f45k20 de timer1 osc kaynağı olarak seçiliyodu.Böyle gıcık durumları da gözden geçir derim.Hoş osc kaynağı seçilebilmesi tam olarak neyi ifade ediyor bilmiyorum ama pll için kullanıldığını okumuştum datasheette.

dediklerinizi denedim fakat sonuç değişmedi. teşekkür ederim

taso

#6
sanırım sorun t0=60;   

cok az timer işini bitirmeden interupt gelliyor

neden saniye icin iki farklı timer kullanıyorsun ?  saniye aynı saniye değil mi :)

int8 sn,dk,sa;


int_timer0

zaman(){

c=(c+1)%50;  //setup_timer1(t1_internal|t1_div_by_8) yaklaşık 1 sn ediyor 20mhz

sn=(sn+!c)%60;

dk=(dk+!sn*!c)%60;

sa=(sa+!dk*!sn*!c)%24;

set_timer(65535-50000);//20mhz

}

Pyrodigy

#7
Alıntı yapılan: tamerugur - 04 Mayıs 2012, 23:21:10
Arkadaşlar Meerhaba...
şöyle bir problemim var, yapacağım devrede 2 timer kullanmam lazım. timer0 0-59 saniye arasında sayacak ve eeproma yüklediğim değere gelince programda belirttiğim yere dallanacak. timer1 ise 0-25 dakika arasında sayacak ve eeproma yüklediğim değere gelince programda istediğim yere dallanacak. yalnız timer1 de dakika ve saniye bazında işlem yapacağım.
timer1 kısmında sorunum yok fakat timer0'ı kullanmayı beceremedim. program aşağıda. yardımcı olacak ve ilgilenecek arkadaşlarıma şimdiden teşekkür ederim.

#include <18f452.h>
#device ADC=10
#fuses HS,PROTECT,NOBROWNOUT,NOPUT,NOWRT,NODEBUG,CPD,NOWDT,NOLVP
#use delay (clock=4000000)
#define kirmizi pin_c2
#define yesil pin_c0
#define sari pin_c1
#define start      pin_d0

float voltaj0=0,topvolt=0,gerilim=0,gerilim1=0,topvolt1=0;
unsigned long int bilgi0=0;
signed int8 tm,tm1,tm2,tm3,a1,v1,a,v;
int32 ms=0,ms1=0,t1=15575,t0=60;
unsigned int8 saniye=0,dakika=0,saniye1=0,dakika1=0;
#int_timer0 //timer0 kesmesi
void timer0_kesme()
{
set_timer0(t0); //timer0 degeri belirleniyor
ms1++;

            if(ms1==100)
            {
            ms1=0;
            saniye1++;
            }
                     if(saniye1==60);
                     {
                     saniye1=0;
                     
                     }
}
#int_timer1
void  timer1_kesme ()
{
    set_timer1(t1);   
    ms++;           
    if (ms==100)
    {
       ms=0;
       saniye++;
         if(saniye==60)
         {
         saniye=0;
         dakika++;
            if(dakika==60)
            {
               dakika=0;
            }
         }
    }
}
void main()
{
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);   
   setup_timer_2(T1_DISABLED,0,1);   
   setup_adc(adc_clock_div_32);
   setup_adc_ports(A_ANALOG);
   
   setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1); // Timer0 ayarları yapılıyor
   set_timer0(t0);   // TMR0 değeri belirleniyor
   
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); // Timer1 ayarları yapılıyor
   set_timer1(t1);   // TMR1 değeri belirleniyor
   enable_interrupts(INT_timer0); // int_timer0 kesmesini aktif yapar
   enable_interrupts(INT_timer1); // int_timer1 kesmesini aktif yapar
   enable_interrupts(GLOBAL);     // Aktif edilen kesmelere izin ver

basla:
                     if(input(start)==1)
                    {
adim1:
                                                if(saniye1==tm)                                  //tm eeproma yazılan iki basamaklı tam sayı örnegin 35
                                                {
                                                output_high(sari);
                                                goto adim2;
                                                }
                                                else
                                                {
                                                   goto adim1;
                                                }
adim2:
                                                if(dakika==tm1)&&(saniye==tm2)   //tm1 eeproma yazılan iki basamaklı dakika örnegin 15
                                                 {                                                    //tm2 eeproma yazılan iki basamaklı saniye örneğin 18
                                                    output_low(sari);
                                                    output_high(kirmizi);
                                                    goto bitis;
                                                  }
                                                 else
                                                 {
                                                  goto adim2;
                                                  }
bitis:
output_low(sari);
output_low(kirmizi);
output_high(yesil);
dakika1=0
saniye1=0
saniye=0
goto basla;
}
}
Timerlara özgü registerleri nerede ayarlıyorsun? Timer0,1,2..vs setuplarını tekrar gözden geçirmeni tavsiye ederim. TXCON Registeri nerede??? INTCON , PIEX, PIRX nerede ayarlıyorsun???? Prescale???? Datasheetlere tekrar bak!!!!!!!!!!
Daha sonra hesaplama kısmında,

Aşağıda Timer hesap makineleri var bu linkler işine yarayacaktır. 
1.link hazır C Kodu da üretiyor, Include in Source işaretlersen sana direkt  örnek program kodu üretiyor

http://eng-serve.com/pic/pic_timer.html
2.link ise ücretsiz indirip kurabileceğin bir timer hesaplama tablosu. Ben bunu kullanıyorum çok mutluyum  :P

http://pictimer.picbingo.com/download/index.php
Persistance is the name of the game in this business....

tamerugur

Alıntı yapılan: taso - 10 Mayıs 2012, 14:37:44
sanırım sorun t0=60;   

cok az timer işini bitirmeden interupt gelliyor

neden saniye icin iki farklı timer kullanıyorsun ?  saniye aynı saniye değil mi :)

int8 sn,dk,sa;


int_timer0

zaman(){

c=(c+1)%50;  //setup_timer1(t1_internal|t1_div_by_8) yaklaşık 1 sn ediyor 20mhz

sn=(sn+!c)%60;

dk=(dk+!sn*!c)%60;

sa=(sa+!dk*!sn*!c)%24;

set_timer(65535-50000);//20mhz

}
öncelikle teşekkür ederim. Saniye aynı saniye, ama iki farklı saniye saniye sayılması gerekiyor. yani şöyle anlatacak olursak start verdikten sonra timer saymaya başlayacak ve 10 saniye sonra ledi yakacak. led yandıktan sonra tekrar timer sıfırlanıp 20 saniye bekleecek ve yanan ledi söndürüp başka ledi yakacak.tabi burada timer süreleri eeproma yazılan değerler olacak (ki bu değerleri keypad ile giriyorum)aslında sadece timer1 kullanarak yaptım istediğimi ama timer0 kullanamadığım için iş inada bindi:)

tamerugur

Alıntı yapılan: Pyrodigy - 10 Mayıs 2012, 17:56:16
Timerlara özgü registerleri nerede ayarlıyorsun? Timer0,1,2..vs setuplarını tekrar gözden geçirmeni tavsiye ederim. TXCON Registeri nerede??? INTCON , PIEX, PIRX nerede ayarlıyorsun???? Prescale???? Datasheetlere tekrar bak!!!!!!!!!!
Daha sonra hesaplama kısmında,

Aşağıda Timer hesap makineleri var bu linkler işine yarayacaktır. 
1.link hazır C Kodu da üretiyor, Include in Source işaretlersen sana direkt  örnek program kodu üretiyor

http://eng-serve.com/pic/pic_timer.html
2.link ise ücretsiz indirip kurabileceğin bir timer hesaplama tablosu. Ben bunu kullanıyorum çok mutluyum  :P

http://pictimer.picbingo.com/download/index.php
ccs de project wizard dan ayarlıyorum. timer değerlerini. 2. link harika çok teşekkür ederim.