Skocz do zawartości

Arduino i timery - problem ze zrozumieniem preskalerów


farmaceuta

Pomocna odpowiedź

Cienki jestem w rejestry bo dopiero się tego uczę, ale trochę pobawiłem się pierwszym kodem. Testuję na klonie arduino nano- atmega 328, "nowy" bootloader(nie ruszany). Problem zwalniania diody występuje już przy preskalerze ustawionym na 32 (TCCR2B |= (1 << CS21) | (1 << CS20); ). Zmierzyłem czasy przełączania diody (poprzez licznik na millis) na różnych ustawieniach preskalera i zauważyłem pewną zależność:

clk/1=249 [ms]		//TCCR2B |= (1 << CS20);
clk/128=249 [ms]
  
clk/8= 499 [ms]
clk/256=499 [ms]
  
clk/32=1991 [ms]
clk/1024=1991 [ms]

  
  

Na mój chłopski rozum, to coś się tu przepełnia(?), tylko co?

  • Lubię! 1
Link do komentarza
Share on other sites

1 minutę temu, farmaceuta napisał:

Usbasp to rozumiem ze boot mi zostanie w atmedze tak??

Tak pod warunkiem że nie zmienisz bitu botrst oraz nie wgrasz przez isp innego programu który zasłoni sekcję bootloadera. Uważam że jeśli uart poprawnie wysyła dane to f_cpu też jest tak jak ma być

Link do komentarza
Share on other sites

2 minuty temu, Peposh napisał:

Cienki jestem w rejestry bo dopiero się tego uczę, ale trochę pobawiłem się pierwszym kodem

Jeśli możesz to sprawdź czy działa na tych dwóch ustawieniach w sensie czy dioda mruga

	TCCR2B |= (1 << CS21);  //preskaler na 8
	//  TCCR2B |=  (1<<CS20); // 1

 

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

@_LM_ Tak, mruga na obu ustawieniach

 

EDIT: jeszcze dla pewności wrzucam swój kod (kod z pierwszego posta wątku z dodatkowym licznikiem czasu):

volatile uint32_t x = 0;

void setup() {
  pinMode(13, OUTPUT);
  Serial.begin(115200);
  Serial.println("///////");

  //TCCR2B |= (1 << CS22) | (1 << CS21) | (1 << CS20); //preskaler na 1024
  //TCCR2B |=  (1<<CS22) | (1<<CS21);  //preskaler na 256
  // TCCR2B |=  (1<<CS22) | (1<<CS20);    //128
  // TCCR2B |= (1 << CS22); //preskaler na 64
  //TCCR2B |= (1 << CS21) | (1 << CS20); //32
  //TCCR2B |= (1 << CS21); //preskaler na 8
  TCCR2B |= (1 << CS20);

  TIMSK2 |= (1 << TOIE2);  //wlaczenie przerwania od przepelnienia


  sei();                 // przerwania globalne wlacz
}

void loop() {
  static bool blink_done = true;
  static unsigned long czas_prev;
  static unsigned long czas;


  if (x == 61)  {
    digitalWrite(13, HIGH);
    if (blink_done == true) {       //x==61 przez kilka pętli, zmienna blink_done służy jako filtr "antyspamowy"
      Serial.println(czas);
      czas_prev = millis();
      czas = millis() - czas_prev;
      blink_done = false;

    }
  }
  if (x == 122)  {
    digitalWrite(13, LOW);
    x = 0;
    // Serial.println();
    blink_done = true;
    czas = millis() - czas_prev;
    Serial.println(czas);
  }

}

ISR (TIMER2_OVF_vect)
{
  x++;
}

Kompilowałem w arduino 1.8.12, domyślna płytka arduino nano. 

Edytowano przez Peposh
dodanie kodu
  • Lubię! 1
Link do komentarza
Share on other sites

@farmaceuta Wklej tę funkcję migania diodą do przerwania oraz zmień x na uint8_t jeśli nie korzystasz z wartości > 255. Jak zadziała to w pętli głównej możesz mieć funkcje obsługującą x ale gdy będzie miał zakres >uint8_t to użyj odczytu atomowego. Tak jak pokazywałem wcześniej.

Link do komentarza
Share on other sites

I tak...wkleilem twoj kod kolego @_LM_  i dziala tak jak ma dzialac! Na kazdym preskalerze i bez niego..(w sensie 1), wgrane przez usb i wgrane przez Usbasp w celu zamazania bootloadera...dziala! 

ale jesli uzywam mojej wersji programu z loop() i setup() to dziala blednie jak na poczatku opisalem...wgrane przez usb i usbasp..to samo...przeciez to niemozliwe zeby to robilo taka roznice...🤔 ludzie uzywaja tych timerow  z polaczeniem loop/setup i ma dzialac...

Link do komentarza
Share on other sites

(edytowany)
1 godzinę temu, Peposh napisał:

@_LM_ Tak, mruga na obu ustawieniach

Ale mruga z prawidlowa czestotliwoscia???

Z preskalerem na 1 wpisz w if'ach odpowiednio 62500/125000 i powinno byc co sekunde zmiana stanu

Edytowano przez farmaceuta
Link do komentarza
Share on other sites

5 minut temu, _LM_ napisał:

https://forbot.pl/blog/kurs-arduino-ii-wielozadaniowosc-opoznienia-z-millis-id18418 tu napisane jest że do millis wykorzystany jest timer. Bardzo możliwe że jest to właśnie timer2 stąd problemy tak myślę 

Z tego co ja wyczytalem to uzyty jest timer0...timer2 jest niby calkowicie wolny...poczekajmy jeszcze niech kolega @Peposh sprawdzi czy ma prawidlowa czestotliwosc..

Link do komentarza
Share on other sites

@_LM_ Przetestowałem taki kod(zmieniony pin diody na PB5, odkomentowałem atomowe rzeczy):

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

volatile uint32_t x;

int main(void) {

  DDRB |= (1 << PB5);

  //TCCR2B |= ((1 << CS22) | (1 << CS21) | (1 << CS20)); //preskaler na 1024
  TCCR2B |=  (1<<CS22) | (1<<CS21);  //preskaler na 256
  // TCCR2B |=  (1<<CS22) | (1<<CS20);    //128
  // TCCR2B |= (1 << CS22); //preskaler na 64
  //TCCR2B |= (1 << CS21) | (1 << CS20); //32
  //TCCR2B |= (1 << CS21); //preskaler na 8
  //TCCR2B |= (1 << CS20);
  
  TIMSK2 |= (1 << TOIE2);    //wlaczenie przerwania od przepelnienia

  sei();

  for (;;) {

    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
    {
      if (x == 6100) {
        //digitalWrite(13, HIGH);
        PORTB |= (1 << PB5);
      }
      if (x == 12200) {
        //digitalWrite(13, LOW);
        PORTB &= ~(1 << PB5);
        x = 0;
      }
    }
  }
}

ISR (TIMER2_OVF_vect) {
  x++;
}

Kod działa, dioda miga coraz szybciej im mniejszy dzielnik preskalera. Czasów jeszcze nie mierzyłem bo mam trochę domowych obowiązków, ale mruganie jest zbyt wolne(kilka sekund dla clk/256). Podejrzewam, że jest to kwestia dopasowania wartości x w ifach.

@farmaceuta Skupiałem się głównie na tym, że dioda miga wolniej na 8 niż na 64 😉.  Częstotliwości wyglądały sensownie do momentu dzielenia preskalera przez 32

preskaler    ilosc przerwan(x) na/s    zmiana stanu(bledna) led/Hz		czas zmierzony:
1024             61                       0.5				1991 [ms]-> ok 0.5 [Hz]
256              244                      2				499 [ms] -> ok 2[Hz]
128									249 [ms] -> ok 4 [Hz]
64              976                       4(?)				zgubiłem wynik :( , ale było ok 127[ms]
32									znowu 1991 [ms]
8               7812                      2(???????)			znowu 499 [ms]
0               62500

 

  • Lubię! 1
  • Pomogłeś! 1
Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.