簡體   English   中英

閣樓 402 定時器 0 提供意外中斷周期

[英]ATtiny 402 timer 0 is providing unexpected interrupt period

我正在使用 ATtiny 402 來實現定時器中斷。 我選擇的內部時鍾是 20Mhz。 預分頻器未啟用。 對於定時器中斷,我在正常模式下使用定時器 0。 PA6用作output,通過示波器查看中斷時間周期。

對於實驗,我使用了 30000 的 TOP 值。

在當前配置中,定時器中斷時間應為 = TOP * (Pre / Clk) = 30000 * ( 1 / 20000000) s = 1.5 ms

但在示波器中,中斷周期時間為:8.8 ms

我算錯了什么或者我的代碼有什么錯誤。

我的源代碼是:

#include <avr/io.h>
#include <avr/interrupt.h>

FUSES = {
    .WDTCFG = 0x00, // WDTCFG {PERIOD=OFF, WINDOW=OFF}
    .BODCFG = 0x00, // BODCFG {SLEEP=DIS, ACTIVE=DIS, SAMPFREQ=1KHz, LVL=BODLEVEL0}
    .OSCCFG = 0x02, // OSCCFG {FREQSEL=20MHZ, OSCLOCK=CLEAR}
    .TCD0CFG = 0x00, // TCD0CFG {CMPA=CLEAR, CMPB=CLEAR, CMPC=CLEAR, CMPD=CLEAR, CMPAEN=CLEAR, CMPBEN=CLEAR, CMPCEN=CLEAR, CMPDEN=CLEAR}
    .SYSCFG0 = 0xC4, // SYSCFG0 {EESAVE=CLEAR, RSTPINCFG=UPDI, CRCSRC=NOCRC}
    .SYSCFG1 = 0x07, // SYSCFG1 {SUT=64MS}
    .APPEND = 0x00, // APPEND {APPEND=User range:  0x0 - 0xFF}
    .BOOTEND = 0x00, // BOOTEND {BOOTEND=User range:  0x0 - 0xFF}
};

LOCKBITS = 0xC5; // {LB=NOLOCK}


void io_set(void){
    PORTA.DIR = 0b01000000 ;   // pin PA1 input others output
    PORTA.PIN1CTRL = 0b0001000  ;  // pullup PA1 
}

void clk_conf(void){
    CLKCTRL.MCLKCTRLA = 0b00000000 ;  // internal clock 20 Mhz ////
    CLKCTRL.MCLKCTRLB = 0b00000000 ;  // Prescaler is not enabled /////
}

void timer0_init(){
    TCA0.SINGLE.CTRLA = 0b00000001 ;// // Peripheral enable, clock = CLOCK_PER
    TCA0.SINGLE.CTRLB = 0b00000000 ;// // Timer in normal mode
    TCA0.SINGLE.PER    = 30000;    ////// Setting the Top value to 30000
    TCA0.SINGLE.INTCTRL = 0b00000001; //
}

void en_global_int(){
    SREG |= 0b10000000 ; //enable global interrupt
}

int main(void)
{
    clk_conf() ; 
    io_set() ; 
    en_global_int() ; 
    timer0_init() ;
    sei()  ; 
    while (1){

    }
}


ISR(TCA0_OVF_vect){
    TCA0.SINGLE.INTFLAGS = TCA_SINGLE_OVF_bm; //clearing the flag
    TCA0.SINGLE.CNT = 0 ; //counter set to zero
    
    PORTA.OUT ^= 0b01000000 ; //toggling the output pin 
}

在一個項目(使用 ATTiny406)中,我遇到了同樣的問題。 我用幾行解決了它:

// CLOCK Setup
CCP = CCP_IOREG_gc;
CLKCTRL.MCLKCTRLA = CLKCTRL_CLKSEL_OSC20M_gc;
while(!(CLKCTRL.MCLKSTATUS & CLKCTRL_OSC20MS_bm));

CCP = CCP_IOREG_gc;
CLKCTRL.MCLKCTRLB = 0x00;
CLKCTRL.OSC20MCTRLA = CLKCTRL_RUNSTDBY_bm;

也許這有助於...

默認情況下,CLOCK_MAIN 設置為 20MHz,CLOCK_PER 設置為 20/6=3.33333MHz,預分頻器為 6,這正是您使用的。

您設置主時鍾預分頻器的嘗試不起作用的原因是系統關鍵 I/O 寄存器設置受到配置更改保護 (CCP) 的保護,不會被意外修改。 閱讀Attiny202/402 數據表的第 10 節和關於 CCP 的第 8.5.7 節,然后閱讀第 3.5 節關於如何向 CCP 寫入 AVR® MCU 的 C 代碼入門

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM