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
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.
Örnek bir kod olursa kavrayacağımı düşünüyorum.
Mesela Timer0 ile ne yapmak istiyorsun? Dahili clock ile zaman mı tutacaksın yoksa dışarıdan gelen bir sinyali mi sayacaksın?
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.
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
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.
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
Kodu yolla, bir bakalım.
Ama ilk akla gelen ihtimal, "button bouncing" mağduru olman.
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.
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:)
http://eng-serve.com/pic/pic_timer.html (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...
@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
Alıntı yapılan: seyityildirim - 05 Ağustos 2015, 18:20:24
...
Not: telefondan girdiğimden kod penceresine yazamadım modlar kusura bakmasın:)
...
(http://s24.postimg.cc/438iljfc5/kod_tag.png)
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.
[
Deneme :) bir ki , kod kod :)
]
Alıntı yapılan: seyityildirim - 05 Ağustos 2015, 21:17:50
[
Deneme :) bir ki , kod kod :)
]
[ code ]
while(1);
[ /code ]
while(1);
while(1);