Xc8 timer kullanımı

Başlatan seyityildirim, 04 Ağustos 2015, 11:38:09

seyityildirim

Merhaba arkadaşlar. xc8 i yeni öğrenmeye başladım pic16f84a ile çalışıyorum. interrupt rutini olmadan timer0 ı sayıcı olarak çalıştırmak istiyorum. örnek uygulaması olan var mı acaba ? ben çalıştıramadım

Tagli

Aslında Timer0 zaten varsayılan ayarlarla kendisi çalışıyor. Senin bir şey yapmana gerek yok. İstersen prescaler'i değiştirebilirsin. Veya istersen harici kaynaktan clock verebilirsin. Onun dışında pek bir ayarı yok zaten.
Gökçe Tağlıoğlu

seyityildirim

Örnek bir kod olursa kavrayacağımı düşünüyorum.

Tagli

Mesela Timer0 ile ne yapmak istiyorsun? Dahili clock ile zaman mı tutacaksın yoksa dışarıdan gelen bir sinyali mi sayacaksın?
Gökçe Tağlıoğlu

RaMu

Nasıl öğreneceğinizi öğrenirseniz veya
nasıl bulacağınızı öğrenirseniz daha kolay olur.
Bu gibi temel örnekler, birçok kişi tarafından
detaylı olarak dahi anlatılmış,
örnekleri paylaşılmış durumda.
Biraz araştırma yapmalısınız.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

seyityildirim

Haklısınız evet ama yaz boyunca internete sadece elimdeki bu dandik telefon ile girebiliyorum. adam akıllı girebildiğim tek site burası o yüzden buraya yazdım. neyse internet olunca araştırırım sağolun

RaMu

Anlıyorum bende birkaç sene önce aynı durumdaydım.
Nokia 5200 vardı, nokia pc suite ile bilgisayara bağlayıp,
bilgisayar üzerinden telefonun internetini kullanıyordum.
Opera internet tarayıcısının turbo denen modunda ve
javascript vb. şeyleri kapatarak,
birçok siteyi bilgiyi alabilecek kadar ziyaret edebiliyordum.

Yine bu forumdada xc8 ile timer kullanan örnekler olması lazım.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

seyityildirim

#7
Pc studio var pc de ama telefonu bir türlü görmedi. timer uygulaması var forumda evet ama hep kesme kullanılarak yapılmış ben kesme kullanmadan registerdaki değeri okuyarak ona göre işlem yapmak istiyorum amacım iyice anlamak.

mesaj birleştirme:: 05 Ağustos 2015, 10:15:51

kesme ile timer/counter kullanabiliyorum. okulda 8051 öğrenirken kesme kullanmadan da timer kullanmıştık bunu pic te yapmaya çalıştım olmadı. ilk başta TMR0=250 olarak atıyorum. daha sonra if(TMR0==255) şeklinde kontrol ediyorum ve led yakıyorum. porta nın 4. bitinden 5 kez butonla düşen kenar veriyorum led yanmıyor. ama kesme kullanırsam cillop gibi çalışıyor. sıkıntıyı anlamadım

Tagli

Kodu yolla, bir bakalım.

Ama ilk akla gelen ihtimal, "button bouncing" mağduru olman.
Gökçe Tağlıoğlu

RaMu

#9
Kesme kullansanda kullanmasanda
timer0 çalışması için değişen bir ayar yoktur.
Sadece intcon register ındaki T0IE (Timer 0 Interrept Enable)
aktif yada pasif yapılarak,
timer0 overflow (255 e kadar saydı ve tekrar 0 a dönüyor)
olursa kesme versin veya vermesin ayarı yapılıyor.
Geri kalan tüm ayarlar tamamen aynı,
kesme olan örneği incelemen yeterli.

Bence şu problemde olabilir.
Kesme kullanmadan, timer0 ı 250 ye kurup,
255 olmasını yakalamak biraz zor.

Hatta timer0 ı herhangibir değere kurup (misal 0)
herhangibir değere eriştiğini (misal 255)
yakalayabilmek zor.
Neden:
Özellikle C ile çalışırken dahada zor ona sonra değinecem.
Yanlış hatırlamıyorsam 16F84A kullanıyordun,
timer0 a 250 yükledin,
sonra if(TMR0==255) { işlem }
şeklinde bekliyorsun,
burada derleyici şöyle bir asm kodu yazacaktır;

KONTROL
MOVLW 255 
XORWF  TMR0,W   (bu komut veya subwf komutu, timer0 prescaler ını temizler 
;yani bir miktar hatalı sayımada sebep olabilir)
BTFSS   STATUS,Z
GOTO    KONTROL  ;255 değilse tekrar kontrol etmeye git
işlem ....                 ;255 miş gerekli işlemi yap
.
.
.

Burada kontrol döngüsünün 1 defa tamamlanması 5 komut çevrimi sürüyor,
eğer timer0 prescaler olmadan sayıyorsa
çok net bakmadım ama
bu şekilde timer0 ın 250 den 255 e vardığını anlamak imkansız gözüküyor,
birkaç tur attıktan sonra belki tam XORWF  TMR0,W esnasında
timer0 değeri 255 ise bir yakalama olur,
yoksa çok zor görünüyor.

Misal problem buradan mı kaynaklanıyor anlamak için,
timer0 50 gibi bir değere kurulur,
sonra if(TIMER0>=150) denir
buradan 5 komut çevrimi hatayla dahi olsa
kesinlikle bir sonuç alınması gerekir.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

seyityildirim

Hepinize teşekkür ederim arkadaşlar açıklamalar doğrultusunda şu şekilde çözüme vardım. Option reg içini ayarladıktan sonra

TMR0=250;

while(1)
{
if(TMR0==255)
    PORTB=0xFF;

}

kodunu yazdım ve çalıştı eğer if kontrolünü while ın içinde yapmazsam değeri yakalayamıyorum while içinde yaparsam gayet güzel çalışıyor. neden bu halde çalıştığını anlamasam da sonuçta çalıştı. neyse bundan sonra hep kesme kullanılırım daha sağlıklı :)
Not: telefondan girdiğimden kod penceresine yazamadım modlar kusura bakmasın:)

mehmet

#11
http://eng-serve.com/pic/pic_timer.html
Aşağıdaki kodlar bu sayfadan otomatik olarak üretildi.
8MHz. kristal, ön bölücü 1/16, TMR değeri de 131
olarak belirlendi. 1KHz. (1ms) de kesme yapacak
şekilde ayarlandı. Ancak XC8 için bu kodlar üzerinde
biraz değişiklik yapmak gerekli...

/*
* Example Source Code For PIC Timers
*   THis blinks LEDs on PORTB to show interrupt rates
*
* Barton Dring
* Dring Engineering Services
* [url=http://www.eng-serve.com]www.eng-serve.com[/url]
*
* Example only!  Use any code at your own risk.
*/


// Interrupt Handler
void interrupt()
{
  // Timer0 Interrupt - Freq = 1000.00 Hz - Period = 0.001000 seconds
  if (INTCON.TMR0IF ==1) // timer 0 interrupt flag
  {
    PORTB.F0 = ~PORTB.F0;      // Toggle PORTB bit0 LED
    INTCON.TMR0IF = 0;         // clear the flag
    INTCON.TMR0IE = 1;         // reenable the interrupt
    TMR0 = 131;           // reset the timer preset count
  }

}



// code starts here...
void main()
{

  // setup portb to show the interrupts by blibking LEDs
  TRISB = 0x00;    // PORT is all output...to show the interrupts
  PORTB = 0;       // start with all outputs low

//Timer0 Registers Prescaler= 16 - TMR0 Preset = 131 - Freq = 1000.00 Hz - Period = 0.001000 seconds
OPTION_REG.T0CS = 0;  // bit 5  TMR0 Clock Source Select bit...0 = Internal Clock (CLKO) 1 = Transition on T0CKI pin
OPTION_REG.T0SE = 0;  // bit 4 TMR0 Source Edge Select bit 0 = low/high 1 = high/low
OPTION_REG.PSA = 0;   // bit 3  Prescaler Assignment bit...0 = Prescaler is assigned to the Timer0
OPTION_REG.PS2 = 0;   // bits 2-0  PS2:PS0: Prescaler Rate Select bits
OPTION_REG.PS1 = 1;
OPTION_REG.PS0 = 1;
TMR0 = 131;             // preset for timer register


// Interrupt Registers
  INTCON = 0;           // clear the interrpt control register
  INTCON.TMR0IE = 1;        // bit5 TMR0 Overflow Interrupt Enable bit...1 = Enables the TMR0 interrupt
  INTCON.TMR0IF = 0;        // bit2 clear timer 0 interrupt flag
  INTCON.GIE = 1;           // bit7 global interrupt enable


  while(1)  //endless loop
  {
  }
}


Bunlar da aynı kodların 16F84A için düzenlenmiş hali...
/* 
 * File:   main.c
 * Author: Mehmet
 *
 * Created on 05 Ağustos 2015 Çarşamba, 19:28
 */

#include <stdio.h>
#include <stdlib.h>


// PIC16F84A Configuration Bit Settings

// 'C' source line config statements

#include <xc.h>

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

// CONFIG
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF       // Watchdog Timer (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (Power-up Timer is disabled)
#pragma config CP = OFF         // Code Protection bit (Code protection disabled)


/*
* Example Source Code For PIC Timers
*   THis blinks LEDs on PORTB to show interrupt rates
*
* Barton Dring
* Dring Engineering Services
* [url=http://www.eng-serve.com]www.eng-serve.com[/url]
*
* Example only!  Use any code at your own risk.
*/


// Interrupt Handler
void interrupt ISR()
{
  // Timer0 Interrupt - Freq = 1000.00 Hz - Period = 0.001000 seconds
  if (INTCONbits.TMR0IF ==1) // timer 0 interrupt flag
  {
    PORTBbits.RB0 = ~PORTBbits.RB0;      // Toggle PORTB bit0 LED
    INTCONbits.TMR0IF = 0;         // clear the flag
    INTCONbits.TMR0IE = 1;         // reenable the interrupt
    TMR0 = 131;           // reset the timer preset count
  }

}



// code starts here...
void main()
{

  // setup portb to show the interrupts by blibking LEDs
  TRISB = 0x00;    // PORT is all output...to show the interrupts
  PORTB = 0;       // start with all outputs low

//Timer0 Registers Prescaler= 16 - TMR0 Preset = 131 - Freq = 1000.00 Hz - Period = 0.001000 seconds
OPTION_REGbits.T0CS = 0;  // bit 5  TMR0 Clock Source Select bit...0 = Internal Clock (CLKO) 1 = Transition on T0CKI pin
OPTION_REGbits.T0SE = 0;  // bit 4 TMR0 Source Edge Select bit 0 = low/high 1 = high/low
OPTION_REGbits.PSA = 0;   // bit 3  Prescaler Assignment bit...0 = Prescaler is assigned to the Timer0
OPTION_REGbits.PS2 = 0;   // bits 2-0  PS2:PS0: Prescaler Rate Select bits
OPTION_REGbits.PS1 = 1;
OPTION_REGbits.PS0 = 1;
TMR0 = 131;             // preset for timer register


// Interrupt Registers
  INTCON = 0;           // clear the interrpt control register
  INTCONbits.TMR0IE = 1;        // bit5 TMR0 Overflow Interrupt Enable bit...1 = Enables the TMR0 interrupt
  INTCONbits.TMR0IF = 0;        // bit2 clear timer 0 interrupt flag
  INTCONbits.GIE = 1;           // bit7 global interrupt enable


  while(1)  //endless loop
  {
  }
}


Ana döngüde while ile sonsuz döngü yapılmaktadır. Eğer
sonsuz döngü yapılmaz ise son kod işlendikten sonra
program sonlanır.
Ana döngüde INTCON.TMR0IF kontrol edilirse daha uygun
olacağını düşünüyorum. Daha sonra da;
    INTCON.TMR0IF = 0;   
    INTCON.TMR0IE = 1;
kodlarının verilmesi gerekli ki bir sonraki kesme çalışabilsin...
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr

seyityildirim

@mehmet teşekkür ederim son açıklaman faydalı oldu. ama boş yere kesme örneği paylaşmışsın kesme olarak yapabildiğimi kesme kullanmadan yapmak istediğimi belirtmiştim. teşekkür ederim yine de. neden while döngüsü kullanmadan çalışmadığını sondaki açıklaman ile anladım teşekkürler hepinize

RaMu

#13
Alıntı yapılan: seyityildirim - 05 Ağustos 2015, 18:20:24
...
Not: telefondan girdiğimden kod penceresine yazamadım modlar kusura bakmasın:)
...



Fotoğraftaki gibi parantezli code code etiketlerini girdikten sonra
araya yazdıkların, mesajı gönderdiğinde kod etiketi içinde görünür.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

seyityildirim

[
Deneme :) bir ki , kod kod :)
]