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

Jak ustawić zegar 32MHz w ATXMEGA128A1AU? CPU nadal działa na 2MHz

elpenor18 23 Maj 2016 11:54 969 1
  • #1 15694909
    elpenor18
    Poziom 10  
    Proszę o pomoc.
    W wielu miejscach internetu i książkach sporo napisano o zmianie częstotliwości taktowania CPU uk ATXMEGA1AU. Przedstawiane treści są logiczne i wydawałoby się, że zmiana częstotliwości dla CPU czy innych układów to prosta sprawa.
    Mnie jednak jakoś nie udaje się zmienić częstotliwości na 32MHz z generatora wewnętrznego. Próbowałem użyć PLL i też bez rezultatu. Szukając przyczyny tego stanu uruchomiłem USART i przy pomocy RS232 sprawdzałem stan rejestrów. Okazało się, że np. generator wewnętrzny 32MHz mogę włączyć ale nie udaję się przełączyć tego sygnału na CPU (ani bezpośrednio ani przez PLL).
    Żeby nie przeciągać podam prosty kod który włącza gen. 32MHz ale CPU mimo polecenia przejścia na tę częstotliwość pracuje na 2 MHz (choć patrząc na przebieg prostokątny jaki generuję przy tym zegarze mam wrażenie, że jest zdecydowanie mniej). Kod jest taki jaki znalazłem gdzieś w internecie (używałem kilku z takim samym skutkiem).

    OSC_CTRL = 0x02; // 32MHz internal RC oscillator

    uint8_t czas=255;
    while ((!(OSC.STATUS & OSC_RC32MRDY_bm)) && (--czas))
    _delay_ms(1);

    CPU_CCP = 0xD8;
    CLK_CTRL = 0x01; // 32MHz internal RC oscillator
    po wpisaniu programu na RS232 odczytuję na RS232:
    OSC.STATUS = 0x03 co wskazuje, że generatory 2MHz i 32MHz pracują, ale CLK.CTRL = 0x00.
    CO wskazuje, że CPU pracuje na 2MHz.
    Pan Tomasz Francuz w swojej książce "AVR Praktyczne projekty" sugeruje aby w takich przypadkach szukać w erratach, ale nie trafiłem na taką, która omawia ten problem.
    Dodam, że przebieg prostokątny, który miał wskazywać zmianę zegara wygląda następująco:
    PORTA_OUT = 0XFF;
    czekaj (100);
    PORTA_OUT = 0X00;
    czekaj (100);

    PORTD_OUT = 0XFF;
    PORTE_OUT = 0XFF;

    czekaj (100);
    PORTD_OUT = 0X00;
    PORTE_OUT = 0X00;

    czekaj (100);

    funkcja czekaj poniżej
    void czekaj (unsigned char zt)
    {

    for(; zt > 0; zt--);

    }
    Sygnał prostokątny ma okres około 2,44ms, co wskazuje na taktowanie CPU wyjątkowo niską częstotliwością czego nie mogę wyjaśnić w żaden sposób.
    Dotychczas programowałem ATMEGA i ATTINY i takie problemy nie występowały. Mogą pojawiać się drobne rozbieżności ale nie aż takie.
    Bardzo możliwe, że popełniam elementarny błąd, ale swoich błędów człowiek nie zauważa.
    Za pomoc z góry serdecznie dziękuję
  • #2 15695115
    ASMnauka_
    Poziom 15  
    Witaj
    W tym poradniku kolega Leon przedstawił rozwiązanie Twojego problemu bardzo przystępnie.
    Jedyne, co może sprawić Ci kłopot to nazwy rejestrów (poszczególnych bitów) jakie tam występują, ale z tym już sobie poradzisz.
    Dodaję niezbędna pomoc.
    Pozdrawiam
REKLAMA