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

Atmega16A - prawdopodobnie błędna obsługa przerwań

michal_grunwald 10 Lut 2011 13:58 1581 25
REKLAMA
  • #1 9131011
    michal_grunwald
    Poziom 10  
    Witam, pracuję na atmedze16A i wewnętrznym clocku 4Mhz. Próbuję wygenerować przerwanie z częstotliwością 80kHz, które spowoduje negacje jednego z bitów portu B(PORTB 0). Rozumiem, że dzięki takiej operacji wygeneruję sygnał o częstotliwości 40kHz, który pozwoli mi generować ultradźwięki w nadajniku. Napisałem taka obsługę przerwania, ale coś mi nie działa:
       TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode 
       OCR1A   = 50; 
       TCCR1B |= ((1 << CS10));
       TIMSK |= (1 << OCIE1A);


    ISR(TIMER1_COMPA_vect)
    {
    
    	PORTB ^= (1<<0);
    
    	ilosc++;
    }

    Dodam, że układ wygląda tak:
    Atmega16A - prawdopodobnie błędna obsługa przerwań

    Dziękuję za pomoc w rozwiązaniu problemu[/code]
  • REKLAMA
  • #2 9131139
    Fredy
    Poziom 27  
    Czy masz sei()?
    Czy masz PORTB 0 jako wyjście zadeklarowane?
  • #3 9131221
    michal_grunwald
    Poziom 10  
    tak mam,
    	DDRB |= (1<<0);
    	PORTB &= ~(1<<0);


    
    int Odbierz()
    {
    	ilosc = 0;	
    	nadawaj = 1;
    	sei();
    	
    //wyslanie sygnalu	
    	while(ilosc < 70);	
    
    
    	ilosc = 0;
    	nadawaj = 0;
    //wlaczenie odbierania	
    	DDRB &= ~(1<<2);
    	//odebranie sygnalu
    	while(ilosc < 60)
    	{
    		if(bit_is_set(ACSR,ACO))
    			return 1;
    	}
    	cli();
    //wylaczenie odbierania
    	DDRB |= (1<<2);
    	PORTB &= ~(1<<2);
    	return 0;
    
    }
  • #4 9131265
    asembler
    Poziom 32  
    Dlaczego wszyscy upierają sie na przerwanie od COMPARE i do tego jeszcze A
    Nie lepiej wykorzystac przerwanie od przepełnienia?
    To nawet na 8 bitowy pojdzie a w przerwaniu można dokładnie wyregulowac czestotliwosc wpisując nową wartość do licznika.
  • #5 9131269
    michal_grunwald
    Poziom 10  
    to podaj rozwiązanie, ponieważ ja nie umiem tego napisać. byłbym wdzięczny
  • #6 9131281
    piotrva
    VIP Zasłużony dla elektroda
    wykorzystanie compare to bardzo dobry nawyk
    może odblokuj globalnie system przerwań, a nie tylko w jednej konkretnej funkcji?
  • #7 9131310
    asembler
    Poziom 32  
    piotrva napisał:
    wykorzystanie compare to bardzo dobry nawyk
    może odblokuj globalnie system przerwań, a nie tylko w jednej konkretnej funkcji?

    To wytłumacz mi jak to działa bo sie zamuliłem chyba.
    Przerwanie przyjdzie raz na 65536 czyli de facto dziala jak dzielnik przez tą liczbe.
    Gdzie tu w powyższym przykładzie mozliwosc ustawienia żadanej czestotliwości., Gdzyz to samo osiagniemy przy przerwaniu od przepelnienia a COMPARE mozna wykorzystać do innych bardziej wymagających celów.
  • REKLAMA
  • #8 9131323
    michal_grunwald
    Poziom 10  
    jest problem przy Takiej częstotliwości generować przerwanie o tak dużej częstotliwości. Niewiele rozkazów wykonam pomiędzy każdym przerwaniem, a mój projekt to samochodzik oparty na dwóch silnikach krokowych sterowanych z procesora...
  • #9 9131350
    asembler
    Poziom 32  
    To zwiększ do 16Mhz a bedziesz mial do dyspozycjie 3200 taktów na przerwanie o ile sie nie myle a to masa rozkazów.

    Dodano po 5 [minuty]:

    Wszystko jasne sprawdz czy nie masz przebiegu na innej nóżce.
    I skasuj obsługe przerwania oraz zezwalanie na przerwanie bo z jedejstrony ty chcesz sprzetowo generować a z drugiej strony programowo wiec zdecyduj sie.
    Sygnał jak juz poprawnie napiszesz powinien pojawic sie na B1 a nie na B0
  • #10 9131400
    michal_grunwald
    Poziom 10  
    nie rozumiem co mam zrobić. możesz dogłębniej wytłumaczyć?
  • #11 9131411
    asembler
    Poziom 32  
    Ja sie nie znam ale bym wywalil linijke z TIMSK oraz obsługę przerwania CAŁĄ a sygnału szukał na nodze B1 .
  • #12 9131415
    michal_grunwald
    Poziom 10  
    na nodze B1 zobaczę przebieg TIMERA, ale jak to wykorzystam do nadajnika skoro muszę krótkie paczki wysyłać?
  • #13 9131436
    asembler
    Poziom 32  
    No cóż dalej to sobie radź całego programu nie da sie napisać nei wiedząc czego oczekujesz. Ty chyba wiesz prawda?
    Ponieważ umiesz już włączyc nośną 80kHz to prwadopodobnie też dasz radę wyłączyć. Odpowiednie włącz/wyłącz bedziesz mogł nadawać co chcesz nawet paczki polecone.
  • REKLAMA
  • #14 9131445
    michal_grunwald
    Poziom 10  
    wiem, ale nadal nie wiem czy dobrze generowane jest to przerwanie...
  • #15 9131452
    asembler
    Poziom 32  
    A do czego ci to przerwanie skoro sprzetowo otrzymujesz sygnał?
  • #16 9131464
    michal_grunwald
    Poziom 10  
    hmm musze wygenerować paczkę ultradźwieków czyli sygnału o częstotliwości 40kHz, rozumiem, że dzięki takiemu przerwaniu będę mógł na jednym z bitów portu wygenerować sygnał 101010101... właśnie o takiej częstotliwości. Paczka nie może być długa, bo w przeciwnym wypadku odbiornik zgłupieje i ciągle będzie otrzymywał jakieś ultradźwieki...
  • #17 9131483
    asembler
    Poziom 32  
    Oczywiscie te 10101010 to jest sygnał i nie ma sygnał jak rozumiem o f 40kHz
    Jaka długosc (szerokośc) tego sygnału w takim razie.
  • REKLAMA
  • #18 9131494
    michal_grunwald
    Poziom 10  
    wyliczyłem, że 880us czyli 35 powtórzen przebiegu 10
  • #19 9131509
    asembler
    Poziom 32  
    No to teraz rozumiem o co ci chodzi. Zagmatwałes z tym portem B0 pewnie jakbys podesłał schemat to by sie wyjaśniło ale tu standard pytac o program bez schematu co niestety jedno z drugim jest ścisle związane.
    Oczywiscie mozesz liczyc ilosc impulsów i na tej podstawie okreslicz czas trwania impulsu i przerwy i jedyna droga to przerwanie.
  • #20 9131513
    michal_grunwald
    Poziom 10  
    jakbyś spojrzał dokładnie to schemat jest w pierwszym poście : )

    Dodano po 1 [minuty]:

    teraz wpadłem na pomysł czy nie dałoby sie zrobić tak że puszczam TIMER1 który będzie liczył sobie te 80kHz i do niego podłączyć nadajnik i w razie potrzeby go załączać albo nie i w ten sposób generować paczkę ultradźwięków?
  • #21 9131524
    asembler
    Poziom 32  
    Faktycznie jest ale nie odzierciedla tego czego ja sie domyslam co chcesz zrobic.
    Uzywasz B0 a na schemacie nic.

    Dodano po 1 [minuty]:

    Najlepiej to przenies na 8 bitowy, A z portu B0 możesz kluczować tranzystorkiem paczki używając przerwania.

    Dodano po 1 [minuty]:

    ja bym odliczał czasy impulsów w paczka za pomocą innego timera i w odpowiednich momentach wyłączał generacje 40kHz, wtedy nie tracimy portu na kluczowanie.
  • #22 9131572
    Fredy
    Poziom 27  
    Timer 1 potrafi działać w trybie CTC tak, że przy zauważeniu równej wartości licznika z rejestrem OCRA może sam zmienić ci stan jednej końcówki procka zwanej OCR na przeciwny. Włącz sobie taki tryb - to wtedy będzie ci to działać automatycznie - czyli bez procedury obsługi przerwania , w pełni sprzętowo.

    Aby to zrobić zaprogramuj bit COM1A0 czyli TCCR1A|=(1<<6) a następnie ustaw końcówkę OC1A na wyjście czyli DDR|=(1<<PD5).
    Potem sprzawdź czy na końcówce OC1A czyli PD5 będziesz mieć przebieg.

    No i wtedy też zlikwidować możesz procedurę obsługi przerwania i całę to przerwanie. To bo będzie ci niepotrzebne.
    Wszystko będzie się dziać sprzętowo.

    A odnośnie to Twojego rozwiązania to :
    Zauważ że masz b.małą częstotliwość kwarcu , a chcesz uzyskać dużą częstotliwość przebiegu w przerwaniu. Spróbuj wywalić tę inkrementację Ilosc++ z procedury obsługi przerwania - może ona za długo trwa jeśli jest np long.
    Spróbuj też jak zachowa sie układ gdy włączysz preskaler. Jeśli będzie przebieg przy preskalerze np przez 16 to wiadome będzie że problem jest ze zbyt małą częstotliwością kwarcu.
  • #23 9131602
    piotrva
    VIP Zasłużony dla elektroda
    asembler napisał:
    piotrva napisał:
    wykorzystanie compare to bardzo dobry nawyk
    może odblokuj globalnie system przerwań, a nie tylko w jednej konkretnej funkcji?

    To wytłumacz mi jak to działa bo sie zamuliłem chyba.
    Przerwanie przyjdzie raz na 65536 czyli de facto dziala jak dzielnik przez tą liczbe.
    Gdzie tu w powyższym przykładzie mozliwosc ustawienia żadanej czestotliwości., Gdzyz to samo osiagniemy przy przerwaniu od przepelnienia a COMPARE mozna wykorzystać do innych bardziej wymagających celów.

    cóż, dzięki stosowaniu compare można w banalny sposób określić częstotliwość wystąpienia przerwania, bez konieczności ciągłego aktualizowania zawartości licznika przy każdym przerwaniu przepełnienia (overflow)
  • #24 9131847
    asembler
    Poziom 32  
    Nie zauważyłem ze on ustawia sprzetowa generacje, gdyz obsługa przerwania sugerowała na realizacje programową. teraz to wszystko jasne.

    Dodano po 2 [minuty]:

    Do konca nie wiadomo jak ma projekt wyglądac wiec trudno sugerowac ostateczne rozwiazanie. A dla samego sprawdzenia to mozna nawet w programie main odpowiednimi opoznieniami wygenerowac dowolny przebieg i nie wiem czy w tym wypadku nie byłaby najlepsza droga choć podniosą sie głosy ze niejedynie słuszna.
  • #25 9131944
    Konto nie istnieje
    Poziom 1  
  • #26 9131999
    asembler
    Poziom 32  
    Nie wykorzystam wpisując do liczników dlatego np tez puszczam timer1 wolno a aktualizuje wartosci ocra/b.
    Zresztą te wypowiedzi nieaktualne i mozna miedzy bajki włozyć.
REKLAMA