• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Timery Atmega8 nie działają poprawnie

Object Storage Arubacloud
0 głosów
444 wizyt
pytanie zadane 4 października 2016 w Mikrokontrolery przez Mavimix Dyskutant (8,390 p.)

Napisałem taki kod:

#define F_CPU 1000000UL

#include <cstdlib>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "lcd.c"

int main(void)
{
	LCD_Ini();

	sei();

	TIMSK |= (1<<TOIE0);
	TCCR0 |= (1<<CS01);

	_delay_ms(5000);

	TCCR0 &= ~(1<<CS01);

	char Temp[8];
						sprintf(Temp,"%i", TCNT0);

	LCD_ZapiszText(Temp);
}

ISR(TIMER0_OVF_vect)
{
	TCNT0 = 0;
}

Według moich obliczeń (reszta z dzielenia 5.000.000 przez 256) wynika, że TCNT0 powinno być równe 64, a na wyświetlaczu pokazuje że jest równe 231. Zauważyłem, że timer nie działa poprawnie. Czemu tak jest?

1 odpowiedź

+1 głos
odpowiedź 4 października 2016 przez jeremus Maniak (59,720 p.)

Bardzo karkołomny kod. Nie wiem za bardzo co chcesz udowodnić.Ustawiłeś preskaler na 8. Przerwania powinny być 125 000 razy na sekundę . Procedura obsługi przerwania , mimo że prosta zajmuje trochę czasu i ten delay(5000) będzie trwał nieco dłużej niź 5 sekund. W liczniku może więc pojawić się dziwna przypadkowa ( acz powtarzalna ) . Użyj prawidłowego sposobu obsługi Timerów i wszystko się zgodzi. http://www.robotyka.net.pl/mikrokontrolery-avr-czesc-6-timer0/

komentarz 5 października 2016 przez Mavimix Dyskutant (8,390 p.)

Faktycznie nie zauważyłem, że ustawiłem preskaler na 8 a nie na 1. Poprawiłem to, ale cały czas ten sam błąd. Co zrobić żeby dokładnie odmierzyć 10us? Czy ten program będzie działał?


#define F_CPU 1000000UL
 
#include <cstdlib>
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "lcd.c"
 
int main(void)
{
    LCD_Ini();
 
    sei();
 
    TIMSK |= (1<<TOIE0);
    TCNT0 = 246;
    TCCR0 |= (1<<CS00);
 
    while(1)
    {
    }

}
 
ISR(TIMER0_OVF_vect)
{
    TCCR0 &= ~(1<<CS00);
    TCNT0 = 0;

    char Temp[8];
                        sprintf(Temp,"%i", TCNT0);
 
    LCD_ZapiszText(Temp);
    LCD_XY(0,1);
    LCD_ZapiszText("Minelo 10 us");

     _Delay_ms(100000);
}

 

komentarz 5 października 2016 przez jeremus Maniak (59,720 p.)

ale co właściwie ten program ma robić ?

funkcja obsługi przerwania powinna być jak najkrótsza

np.

zwiększ jakiś licznik;

ustaw jakiś wskaźnik

i

TCNT0=246; // aby powtórzyć kolejny cykl

nie należy używać w tej funkcji żadnych instrukcji delay, obługa wyświetlacza tez zajmuje trochę czasu

10 us to raptem 10  taktów zegara przy tym taktowaniu  procesora - niewiele więc można zrobić  w procedurze przerwania

poza tym :

 dlaczego wyłączasz obsługę przerwań ?  TCCR0 &= ~(1<<CS00);

 

 ma się tylko raz wykonać przerwanie  po 10 us ?

ale to trochę bez sensu -

i na koniec

sei() wykonujemy po ustawieniu rejestrów a nie przed - to powinna być ostatnia instrukcja przed pętlą główną programu

 

komentarz 5 października 2016 przez Mavimix Dyskutant (8,390 p.)
Docelowo chcę zaprogramować czujnik odległości - ustawiam na jeden pin stan wysoki przez 10us, potem do mikrokontrolera wysyłany jest sygnał wysoki, który trzeba zmierzyć też w mikrosekundach i w zależności od tego czasu przelicza się na odległość. Za każdym razem jak napiszę program sprawny w 99% to mam wrażenie, że timery nie działają poprawnie.

Podobne pytania

–1 głos
2 odpowiedzi 742 wizyt
pytanie zadane 9 lipca 2016 w Mikrokontrolery przez Mavimix Dyskutant (8,390 p.)
0 głosów
1 odpowiedź 163 wizyt
pytanie zadane 5 marca 2017 w Mikrokontrolery przez Mavimix Dyskutant (8,390 p.)
0 głosów
1 odpowiedź 446 wizyt
pytanie zadane 9 lipca 2016 w Mikrokontrolery przez Mavimix Dyskutant (8,390 p.)

92,572 zapytań

141,422 odpowiedzi

319,644 komentarzy

61,959 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...