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] kwarc 11MHz, problem z USART

herszt 03 Lut 2011 20:59 1555 5
REKLAMA
  • #1 9099078
    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:

    
    #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ń.
  • REKLAMA
  • #2 9099194
    kots
    Poziom 12  
    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.
  • REKLAMA
  • #3 9099296
    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ąć.
  • REKLAMA
  • #4 9104075
    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
  • REKLAMA
  • #5 9105462
    dondu
    Moderator na urlopie...
    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) ?
  • #6 9106602
    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
REKLAMA