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

Taktowanie procesora Atmega8A?

mati1988k 23 Lut 2011 00:21 2334 15
REKLAMA
  • #1 9190276
    mati1988k
    Poziom 13  
    Witam.
    Używam procesora Atmega8A z podłączonym kwarcem 10MHz.

    Jednak gdy w programie użyje funkcji _delay_ms(1000) to procesor czeka 10 sekund a nie 1sekundę. Podobny problem mam z Timeram który mam tak zadeklarowany:
    	TCCR1B = 1<<WGM12 | 1<<CS11 | 1<<CS10;
    	OCR1A = 7811;
    	TIMSK = 1<<OCIE1A;


    Wg mnie powinien wchodzić w przerwanie z częstotliwością 10Hz a on wchodzi w nie około 5 razy częściej. Nie rozumiem gdzie robię błąd. Proszę o pomoc :).

    Programuje w C za pomocą AVR studio. I oczywiście w zakładce Projekt->Configuration Options ustawiam wszystko tak jak należy.
  • REKLAMA
  • #2 9190306
    xanio
    Poziom 27  
    a F_CPU ustawione?
  • REKLAMA
  • #3 9190309
    dondu
    Moderator na urlopie...
    mati1988k napisał:
    Jednak gdy w programie użyje funkcji _delay_ms(1000) to procesor czeka 10 sekund a nie 1sekundę.

    Aby ta funkcja prawidłowo działała musisz mieć prawidłowo zdefiniowany F_CPU.
    Nie wiem jakiego środowiska używasz do pracy, a od tego zależy gdzie się to ustawia (czasami w opcjach, a czasami w kodzie).
    Jeżeli w kodzie to wpisz: #define F_CPU 10000000UL
  • REKLAMA
  • #4 9190319
    mati1988k
    Poziom 13  
    FCPU jest ustawiane w ustawieniach projektu, i oczywiście je ustawiłem na 10000000 :). Więc to jest raczej ok.

    Taktowanie procesora Atmega8A?
  • #5 9190331
    dondu
    Moderator na urlopie...
    Nie sprawdzałem z datasheet poprawności ustawień, ale używaj nawiasów:
    TCCR1B = (1<<WGM12) | (1<<CS11) | (1<<CS10); 


    Dodano po 1 [minuty]:

    ... i wklej jeśli możesz swój kod.

    Dodano po 1 [minuty]:

    mati1988k napisał:
    FCPU jest ustawiane w ustawieniach projektu, i oczywiście je ustawiłem na 10000000 :). Więc to jest raczej ok.

    Tak, to wystarczy.
  • #6 9190339
    mati1988k
    Poziom 13  
    Proszę, oto kod:

    #include <avr/io.h>
    #include <util/delay.h>  
    #include "HD44780.h" 
    #include <stdio.h>
    #include <avr/interrupt.h>
    
    
    volatile int ms=0, sec=0, min=0, h=0, time=0;            
    
    #define SetBit(x,y)	x |= (1<<y)
    #define ClrBit(x,y) x &= ~(1<<y)
    #define NegBit(x,y) x ^= (1<<y)
    
    ISR(TIMER1_COMPA_vect)
    {
    	ms+=100;
    	if(ms==1000)
    	{
    		sec++;
    		ms=0;
    		if(sec==60)
    		{
    			min++;
    			sec=0;
    		}
    		if(min==60)
    		{
    			h++;
    			min=0;
    		}
    		if(h==24)
    		{
    		 	h=0;
    		}
    		time=1;
    
    
    	}
    }
    
    
    int main(void)
    {
      
    	DDRB=	0b11111111;
    	PORTB=	0b00000000;
    
    	DDRC=	0b11111111;
    	PORTC=	0b00000000;
    
        TCCR1B = 1<<WGM12 | 1<<CS11 | 1<<CS10;
        OCR1A = 7811;
        TIMSK = 1<<OCIE1A;
    	sei();
    
    	LCD_Initalize();
    	LCD_Clear();
    	LCD_Home();
    	LCD_WriteText("HELLO");
    
    	char buf[20];
    
    	while(1)
    	{  
                         if(time==1)
                            {
    			sprintf(buf,"  %.2d:%.2d:%.2d:%.2d", h, min, sec, ms);
    			LCD_Home();
    			LCD_WriteText(buf);			
    			time=0;
                            }
    
    	}
    }
    
  • #8 9190363
    mati1988k
    Poziom 13  
    Hmmm już chyba wiem w czym problem. Okazało się, że kwarc jaki mi sprzedano jako 10Mhz jest chyba 1Mhz, Napisane jest na nim YIC 10.00000
  • #10 9190375
    mati1988k
    Poziom 13  
    No właśnie kupiłem je w TME na woreczku napisane jest 10Mhz a jak ustawiłem na 1Mhz to Timer i tak nie działa za dobrze. Więc chyba dalej jestem w polu :/
  • REKLAMA
  • #12 9190422
    mati1988k
    Poziom 13  
    teraz kod wygląda tak:

    DDRB=	0b11111111;
    	PORTB=	0b00000000;
    
    	DDRC=	0b11111111;
    	PORTC=	0b00000000;
    
        TCCR1B = (1<<WGM12) | (1<<CS11) | (1<<CS10);
        OCR1A = 7811;
        TIMSK = 1<<OCIE1A;
    	sei();
    
    	LCD_Initalize();
    	LCD_Clear();
    	LCD_Home();
    	LCD_WriteText("HELLO");


    Policzyłem ze wzoru który podany jest w datasheet na stronie 91 za N podstawiłem 64, za fOCnA 10, za fclk/io 10000000, wyznaczylem z tego OCR1A.

    Teraz mecze te fusebity :) Pierwszy raz to robię więc może to trochę potrwać :) bo jak narazie nie wiem czemu nie ma częstotliwosc 10Mhz w tabeli 8-3 na stronie 26 :)

    Hmm jak na razie działa. Ustawiłem CKSEL3..1 na jedynki a wynik jaki mi wyszedł ze wzoru czyli 7811 pomnożyłem razy 2 i na razie liczy dobrze :). Tylko nie wiem czemu razy dwa musiałem OCR1A pomnożyć.
  • Pomocny post
    #13 9190436
    dondu
    Moderator na urlopie...
    To najczęstszy problem - złe ustawienie fusów :)
    Ta magiczna 2 wynika z tego że wzór jest na częstotliwość, a nie okres przez co przechodzisz przez 2 zbocza w jednym pełnym cyklu o danej częstotliwości.
    Ta 2 jest we wzorze na stronie 91.
  • #14 9190442
    mati1988k
    Poziom 13  
    Na wykresach ładnie widać, ze powinno się wynik razy dwa pomnożyć :) Dzięki wielkie za pomoc.
  • #15 9190444
    dondu
    Moderator na urlopie...
    Nie ma sprawy :)
    Życzę szybkich postępów w pracach i udanych projektów!

    Dodano po 1 [minuty]:

    I bonusik ode mnie 20 pkt, boś biedny strasznie (1,09pkt), ale C używasz a ja takich ludzi promuję :)
    Może ktoś dorzuci się jeszcze?
  • #16 9190612
    xanio
    Poziom 27  
    Mało ich używam więc się trochę tego nazbierało.
REKLAMA