Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[ATMEGA8] kwarc 11MHz, problem z USART

herszt 03 Lut 2011 20:59 1390 5
  • #1 03 Lut 2011 20:59
    herszt
    Poziom 18  

    Witam!

    Chciałem nieco poeksperymentować z moją atmegą i dorzuciłem kwarc. Ustawiłem fuse bity (hFuse: C9, lFuse: FF, Lock bit: 3F) i niestety troszeczkę się coś posypało. Obsługa USARTa, która wcześniej działała teraz jakoś gorzej sobie radzi bez względu na ustawioną prędkość. Testowałem nawet kilka 'gotowych' kodów i zawsze lecą mi jakieś krzaczki. Obecny kod wygląda następująco:

    Code:

    #define F_CPU 11000000UL

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

    #define sbi(add,bit) add |= _BV(bit);
    #define cbi(add,bit) add &= ~_BV(bit);

    #define BAUD 9600
    #define MYUBRR F_CPU/16/BAUD-1


    void USART_Init( unsigned int ubrr )
    {
       UBRRH = (unsigned char)(ubrr>>8);
       UBRRL = (unsigned char)ubrr;
       UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
       UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
    }


    void US_TRA( unsigned char data )
    {
       while(!(UCSRA & (1<<UDRE)));
       UDR=data;
    }

    void writeTextUSART( char * s )
    {
       while(*s)
       {
          US_TRA(*s);
          s++;
       }
    }


    int main( void )
    {
       USART_Init(MYUBRR);
       sei();

     while(1)
     {   

       writeTextUSART("Test\n\r");
       
       _delay_ms(100);
       _delay_ms(100);
       _delay_ms(100);
       _delay_ms(100);
       _delay_ms(100);
       _delay_ms(100);
       _delay_ms(100);
       _delay_ms(100);
       _delay_ms(100);
       _delay_ms(100);
     
     }

    }


    Oczywiście po stronie komputera ustawiam odpowiednią prędkość. I tak swoją drogą - czy wraz ze wzrostem częstotliwości taktowania maleje możliwa wielkość opóźnienia przez _delay_ms()? Bo jakoś specjalnie nie widzę różnicy jak zwiększam jego wartość poprzez dodanie kilku dodatkowych opóźnień.

    0 5
  • #2 03 Lut 2011 21:13
    kots
    Poziom 11  

    Możliwe przyczyny:

    1. Użyłeś procesora nowego typu, inaczej obsługują UCSRC
    2. źle dobrałeś czestotliwosci, tabela jest w instrukcjach obsługi

    Częstotliwosć mozesz oszacować ustaw prędkosci tak by w komputerze była kilka razy większa od tej w AVR wyślij jeden bajt FF lub 00 i zobacz co odbierasz, zmieniaj częstotliwość narysuj sobie diagramy przebiegu i zobaczysz czy coś pasuje.

    0
  • #3 03 Lut 2011 21:28
    janbernat
    Poziom 38  

    Ale jesteś pewien że to 11000000 a nie normalny 11059200?
    Mam takie na których jest napisane 11.0Y9BF a są na 11059200.
    A częstotliwość wpisz raczej w opcje projektu a nie w main().
    Można się trochę naciąć.

    0
  • #4 04 Lut 2011 21:07
    herszt
    Poziom 18  

    Przetestowałem trochę, i wszystko działa dobrze dopóki fusebity są ustawione na wewnętrzny oscylator. Jak podłączam zewnętrzny, ustawiam fusebity i przestawiam prędkość wg. tabeli w dokumentacji to komunikacja przestaje działać - zaczynają lecieć krzaki. Co może być przyczyną?

    ----------------------------------------------------------------------

    Problem rozwiązany - odłączyłem od Atmegi CLK z programatora i teraz chodzi bez problemu. Jak widać miało to dość istotny wpływ.

    Jeszcze jedno pytanie, nieco poza tematem - czy zwiększanie taktowania ma jakiś konkretny wpływ na funkcje _delay_ms(), _delay_us() z biblioteki delay.h?

    z góry dzięki
    pozdrawiam
    herszt

    0
  • #5 05 Lut 2011 08:16
    dondu
    Moderator Mikrokontrolery Projektowanie

    herszt napisał:
    czy zwiększanie taktowania ma jakiś konkretny wpływ na funkcje _delay_ms(), _delay_us() z biblioteki delay.h?

    Nie ma jeżeli prawidłowo ustawisz F_CPU.
    Zobacz definicje tych funkcji w plikach delay.h i delay_basic.h
    To rozwieje wszelkie wątpliwości na przyszłość, ale też uświadomi, że nie blokują przerwań, więc ...

    A z ciekawości czemu 10 razy _delay_ms(100) zamiast 1 raz _delay_ms(1000) ?

    0
  • #6 05 Lut 2011 13:51
    herszt
    Poziom 18  

    dondu napisał:
    Nie ma jeżeli prawidłowo ustawisz F_CPU.
    Zobacz definicje tych funkcji w plikach delay.h i delay_basic.h
    To rozwieje wszelkie wątpliwości na przyszłość, ale też uświadomi, że nie blokują przerwań, więc ...

    A z ciekawości czemu 10 razy _delay_ms(100) zamiast 1 raz _delay_ms(1000) ?


    Wpisałem 10x definicję aby zobaczyć czy jest jakaś różnica między pojedynczym wywołaniem z argumentem 1000, bo generalnie jakoś mi to nie pasuje na 1000ms, które powinny być 1s. Dołączyłem diodę na linię TX i w mojej subiektywnej ocenie miga zdecydowanie szybciej niż 1s (poza tym w terminalu tekst też się zdecydowanie szybciej pojawia), a zgodnie z programem tekst powinien być wysyłany co sekundę. Dlatego zastanawiałem się na ile dokładne są te funkcje. Swoją drogą chciałem napisać program do obsługi DS18B20 i zauważyłem w różnych przykładach, że ludzie tworzą swoje procedury do generacji opóźnień, się zastanawiałem dlaczego? Bo w sumie jak użyłem tych 'standardowych' to wszystko działa dobrze, ale tylko w momencie wysyłane pierwszego PRESENCE PULSE, a potem już nic nie działa jak powinno (odczytywane są same 1).

    z góry dzięki
    pozdrawiam
    herszt

    0