Arkadaşlar merhaba
pic18f4520 ile Timer0 uygulaması yapıyorum. 16 bitlik timer0 kullanıyorum. Timer0 değerim 46005, prescaler=64, harici osilatör frekansım=20 MHz. Bu değerlere göre yaklaşık 250 ms de ledin flaş yapması gerekiyor. Fakat flaş yapma süresi 1 sn kadar. Hesaplamalarım doğrumudur?
İyi çalışmalar...
verdiğiniz değerlerde 250 ms'de bir interrupt almanız gerekiyor. kodunuzu paylaşırsanız inceleme şansımız olur.
/*
* File: TMR.c
#define _XTAL_FREQ 20000000
#pragma config OSC = HS // Oscillator Selection bits HS
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor enabled)
#pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode enabled)
// CONFIG2L
#pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // Brown-out Reset Enable bits (Brown-out Reset enabled and controlled by software (SBOREN is enabled))
#pragma config BORV = 3 // Brown Out Reset Voltage bits (Minimum setting)
// CONFIG2H
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
// CONFIG3H
#pragma config CCP2MX = PORTC // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1)
#pragma config PBADEN = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config LPT1OSC = OFF // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))
// CONFIG5L
#pragma config CP0 = OFF // Code Protection bit (Block 0 (000800-001FFFh) not code-protected)
#pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) not code-protected)
#pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) not code-protected)
#pragma config CP3 = OFF // Code Protection bit (Block 3 (006000-007FFFh) not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection bit (Block 0 (000800-001FFFh) not write-protected)
#pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) not write-protected)
#pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) not write-protected)
#pragma config WRT3 = OFF // Write Protection bit (Block 3 (006000-007FFFh) not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot block (000000-0007FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) not protected from table reads executed in other blocks)
#include <xc.h>
int i=0;
void __interrupt(high_priority) myHiIsr(void)
{
if(INTCONbits.TMR0IE && INTCONbits.TMR0IF) //timer0 interrupt enable ve flag bitleri kontrol ediliyor
{
i++; //i 1 artirilir
TMR0H=46005;//TMRH0 bitinin saymaya ba?layaca?? de?er yaz?l?r
INTCONbits.TMR0IF=0;// Kesme bayra?? s?f?rlan?yor.
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
void kurulum(){
TRISB = 0x00; //B portu ç?k?? olarak belirlendi
TRISD = 0x00; //D portu ç?k?? olarak belirlendi
INTCONbits.GIE=1; //enable all global interrupts
INTCONbits.GIEH=1;//Enables all high priority interrupts
RCONbits.IPEN=1; //Enable priority levels on interrupts
INTCONbits.TMR0IE=1; //ENABLE T?MER ?NTERRUPT
INTCONbits.TMR0IF=0; ////Kesme bayra??n? her ihtimale kar?? s?f?rlad?k
TMR0H=46005;//Timer0 register?na ms'de bir kesme olu?turacak de?er yükleniyor.
ei(); //Enable Interrupts
//configure our timer
T0CONbits.TMR0ON=1; //Enables Timer0
T0CONbits.T08BIT=0; //Timer0 is configured as a 16-bit timer/counter
T0CONbits.T0CS=0; //Internal instruction cycle clock (CLKO)
T0CONbits.T0SE=0; //Increment on low-to-high transition on T0CKI pin
T0CONbits.PSA=0; //Timer0 prescaler is assigned. Timer0 clock input comes from prescaler output.
T0CONbits.T0PS0=1; //1:64 prescale value
T0CONbits.T0PS1=0; //1:64 prescale value
T0CONbits.T0PS2=1; //1:64 prescale value
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
void main()
{
kurulum();
while(1)
{
LATB = 0x05; //RB0 ve RB2 ç?k?? olarak ayarland?.Led ba?lay?p picin çal???p çal??mad??? kontrol edilir.
if(i==1) // E?er i=18 ise yani 18 kesme olu?mu?sa(18 x 3.33s = 60 s)
{
LATD=~LATD;//portD tersleniyor
i=0;//i de?i?keni s?f?rlan?yor.
}
}
}
Gördüklerimi şöyle söyleyeyim, PIC'e çok hakim değilim ama fikir oluşturabilir;
- Interrupt flagini temizlemek gerekmez mi? Okununca mı temizleniyor?
- TMR0H sanırım High Byte'ı. TMR0L'de olmalı diye düşündüm. Bu durumda TMR0H aslında 46005 sayısının high byte'ı ve TMROL 46005'in low byte'ı olmalı.
- Birde timer prescaleri önemli. O kaç? Sıfır mı?
Timer sıfırı 16 bit modunda kullanırken tmr0h ve tmr0l registerlerına yazmalısınız. Yalnızca tmr0h registerına yazacağınız değerle olmaz. 46005 değeri için tmr0h = 0xb3,tmr0l = 0xb5
1/ (Fosc/4)
1/(20MHz/4) = 0.2 mikrosaniye de bir timer bir artar.
46005 * 64 * 0.2 = 0.588 saniyede bir kesme verir.
Pic (10f ~ 18F) in bir komut işleme süresi
osilatör frekansı / 4
her komut 4 adımda işleniyor,
mimari bu şekilde tasarlanmış.
Alıntı yapılan: mylord92 - 05 Nisan 2019, 17:53:54Gördüklerimi şöyle söyleyeyim, PIC'e çok hakim değilim ama fikir oluşturabilir;
- Interrupt flagini temizlemek gerekmez mi? Okununca mı temizleniyor?
- TMR0H sanırım High Byte'ı. TMR0L'de olmalı diye düşündüm. Bu durumda TMR0H aslında 46005 sayısının high byte'ı ve TMROL 46005'in low byte'ı olmalı.
- Birde timer prescaleri önemli. O kaç? Sıfır mı?
-46005 değeri için high ve low için yazmak mantıklı, deneyeceğim.
-prescaler=64
Alıntı yapılan: ahuramazda - 05 Nisan 2019, 20:17:02Timer sıfırı 16 bit modunda kullanırken tmr0h ve tmr0l registerlerına yazmalısınız. Yalnızca tmr0h registerına yazacağınız değerle olmaz. 46005 değeri için tmr0h = 0xb3,tmr0l = 0xb5
46005 değerini high ve low registerlarına denk gelecek şekilde ayarlayarak deneyeceğim, teşekkürler
Alıntı yapılan: RaMu - 05 Nisan 2019, 20:29:251/ (Fosc/4)
1/(20MHz/4) = 0.2 mikrosaniye de bir timer bir artar.
46005 * 64 * 0.2 = 0.588 saniyede bir kesme verir.
Pic (10f ~ 18F) in bir komut işleme süresi
osilatör frekansı / 4
her komut 4 adımda işleniyor,
mimari bu şekilde tasarlanmış.
Hocam hesaplama şu şekilde değilmi
(65535-46005)*64*0.2=0.249s
Evet doğru söylüyorsun.
Ama sadece TMR0H a değer yüklemek yeterli değil datasheete göre ve
TMR0H 8bit yani 46005 zaten yüklenemez.
Değeri H L registerlarına ne denk geliyorsa öyle yazacaksın.
Önce TMR0H sonrada L yazılacak.
Datasheete göre TMR0L yüklendiği anda
TMR0H değeri bufferdan
gerçek registerlarına aktarılıyor.
Denemek için:
Verdiğin programda TMR0H registerına hiç değer yazmasanda
hiç değişiklik olmayacak aynı hatalı 1 saniye çalışmasına devam edecek.
Daha doğrusu 0.83 saniye.
Alıntı yapılan: RaMu - 07 Nisan 2019, 01:23:31Evet doğru söylüyorsun.
Ama sadece TMR0H a değer yüklemek yeterli değil datasheete göre ve
TMR0H 8bit yani 46005 zaten yüklenemez.
Değeri H L registerlarına ne denk geliyorsa öyle yazacaksın.
Önce TMR0H sonrada L yazılacak.
Datasheete göre TMR0L yüklendiği anda
TMR0H değeri bufferdan
gerçek registerlarına aktarılıyor.
Denemek için:
Verdiğin programda TMR0H registerına hiç değer yazmasanda
hiç değişiklik olmayacak aynı hatalı 1 saniye çalışmasına devam edecek.
Daha doğrusu 0.83 saniye.
Teşekkür ederim. Deneme fırsatı bulamadım. Denedikten sonra sonucu bildireceğim.
https://www.mikroe.com/timer-calculator (https://www.mikroe.com/timer-calculator)
46005 değeri için high ve low bytlara karşılık gelen değerleri yazdım, TMR0H=0xB3;
TMR0L=0xB5; sorun düzeldi.
yardımcı olan herkese teşekkür ederim.