logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Atmega8] [C] dziwne opóźnienie timera1

Bartusjusz 09 Sty 2011 16:16 932 2
REKLAMA
  • #1 8982064
    Bartusjusz
    Poziom 25  
    Timer działa i generuje przerwanie co około 4 sekundy świetnie, ale jest jeden problem zanim wejdzie w pierwsze przerwanie przez około minutę przerwań nie generuje.

    Podmieniłem atmegę na inną, działa identycznie...
    Dopisałem parę linijek na początku pracy ze zmianą portuB i opuźnieniem delay_ms i dopisane linijki się zrealizowały, ostatni stan się "zamroził" i po około minucie, zaczęły działać przerwania co 4 sek



    Poniżej kod:
    Cytat:

    #define F_CPU 1000000L

    #include<avr/io.h>
    #include <avr/interrupt.h>
    #include <avr/signal.h>
    #include <inttypes.h>
    #include <util/delay.h>




    // Program główny
    int main(void)
    {

    DDRB = 0xFF;
    PORTB = 0x34;


    TCNT1L = 0x00; // załadowanie do licznika wartości początkowych
    TCNT1H = 0xF0;

    TCCR1B = 0x05;

    TIMSK|=(1<<TOIE1);// odblokowanie przerwania od licznika

    sei();// globalne odblokowanie przerwań




    while(1);
    }


    SIGNAL (SIG_OVERFLOW1)
    {


    if(PORTB == 34)
    {PORTB = 11+11*16;}
    else
    {PORTB = 34;}

    TCNT1L = 0x00; // załadowanie do licznika wartości początkowych
    TCNT1H = 0xF0;
    }
  • REKLAMA
  • Pomocny post
    #2 8982111
    BoskiDialer
    Poziom 34  
    Dokumentacja mówi WYRAŹNIE: najpierw należy ładować wartość do TCNT1H (który zostaje zapisany do rejestru TEMP), a dopiero potem do TCNT1L, co pociąga za sobą wpisanie do TCNT1 aktualnej części jako dół i wartości TEMP jako góra (przy odczycie najpierw należy odczytać dół, potem górę). Ciągu skutków powodujących takie zachowanie a inne nie chce mi się opisywać.

    -- edit:
    Albo rozpiszę. Przy inicjalizacji do TCNT1 zostaje wpisana wartość 0 (zapis do TCNT1L podczas gdy TEMP najprawdopodobniej ma wartość 0). Zapis do TCNT1H powoduje tylko ustawienie TEMP. W przerwaniu zapis do TCNT1L pociąga za sobą wpisanie 0xF000, jako że TEMP został ustawiony podczas inicjalizacji/przerwanie wcześniej.


    Cytat:
    Timer/Counter 1 – TCNT1H and TCNT1L

    To ensure that both the high and Low bytes are read and written simultaneously
    when the CPU accesses these registers, the access is performed using an 8-bit
    temporary High byte Register (TEMP). This temporary register is shared by all the other
    16-bit registers. See “Accessing 16-bit Registers” on page 79.

    Cytat:
    Accessing 16-bit Registers

    [...] To do a 16-bit write, the High byte must be written before the Low byte. For a 16-bit
    read, the Low byte must be read before the High byte.
  • #3 8982281
    Bartusjusz
    Poziom 25  
    Wielkie dzięki, pomogło :)
REKLAMA