• Witaj na Forum Arduino Polska! Zapraszamy do rejestracji!
  • Znajdziesz tutaj wiele informacji na temat hardware / software.
Witaj! Logowanie Rejestracja


Ocena wątku:
  • 1 głosów - średnia: 1
  • 1
  • 2
  • 3
  • 4
  • 5
Odczyt wartości Timera1 - problem.
#1
Plan jest taki że chcę odczytywać wartość timera1 po każdym wywołaniu przerwania i go zerować. 
Docelowo ma z tego powstać obrotomierz do silnika ale to teraz nie istotne.

Kod:
volatile int timer_val=0;
volatile int timer_val_old=0;

void setup() {
  Serial.begin(2000000);
  pinMode(2, INPUT);
  pinMode(2, INPUT_PULLUP);
   attachInterrupt(digitalPinToInterrupt(2), alarm, FALLING);

  TCCR1A = 0;               // set entire TCCR1A register to 0
  TCCR1B = 0;               // same for TCCR1B
  TCNT1 = 0; // Reset Timer1 Count
  TCCR1B |= (1 << CS10);    // prescaler 1024
  TCCR1B |= (1 << CS12);    // prescaler 1024
}

void loop() {
  if(timer_val!=timer_val_old){
     Serial.println(timer_val);
     timer_val_old=timer_val;
     }
}

void alarm() {
    timer_val=TCNT1;
    TCNT1=0;
}


Przerwanie jest wywoływane podaniem na wejście D2 syganłu z dokładnego generatora na AD9850 tak że przerwania zapewne są wywoływane bardzo równo. 
Oto wynik działania programu dla 1Hz ! Dramat !
Wydaje mi się że różnice między kolejnymi odczytami powinny być prawie identyczne, + - klika klików.

   

Co zrobiłem źle ?

ps. serial dałem na full żeby wykluczyć że przerwanie wlezie na funkcje print
 
Odpowiedź
#2
A co się stanie jeśli zamiast attachInterrupt wpiszesz:

Kod:
    EICRA = (1 << ISC01) | (0 << ISC00);
    EIMSK = (1 << INT0);
       sei();

A zamiast:

Kod:
void alarm() {

    timer_val=TCNT1;
    TCNT1=0;
    
}

Wpiszesz:

Kod:
ISR(INT0_vect)
{
    timer_val=TCNT1;
    TCNT1=0;
}

????????????
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#3
(08-03-2020, 01:57)m72 napisał(a): Plan jest taki że chcę odczytywać wartość timera1 po każdym wywołaniu przerwania i go zerować. 
Docelowo ma z tego powstać obrotomierz do silnika ale to teraz nie istotne.
Istotne bo rozwiązanie jest złe. Zanim wykona się przerwanie timer może zliczyć już ileś tam impulsów. Jest to tym bardziej prawdopodobne, że arduinowe biblioteki uwielbiają blokować globalnie przerwania na długi czas. Pomiędzy odczytem timera a jego zerowaniem też mogą się pojawić impulsy. Wynik pomiaru będzie zaniżony a ewentualne blokady przerwań będą powodować niestabilne odczyty. To, że chcesz mierzyć niskie częstotliwości może zamaskuje problem, może nie (zależy co poza pomiarem częstotliwości będziesz robił).

Mierzona częstotliwość nie jest duża. Pewnie chcesz zliczać liczbę impulsów w zadanym czasie? Jeśli tak to błąd, nie tak to się robi, mierzy się okres. Do tego w przypadku popularnych AVR przeznaczony jest timer 1 (ICP), w większych np Mega256 takich timerów jest więcej.
Kod z delay to nie kod, to DEMO!
Możliwości sprzętowe uC trzeba wykorzystywać a nie /machać/. GPIO!
Jestem a usilnie chcę być amatorem to dwie różne rzeczy.

http://er-mik.prv.pl/projekty edw.php 
http://er-mik.prv.pl/projekty_avt.php
 
Odpowiedź
#4
(08-03-2020, 09:30)Robson Kerman napisał(a): A co się stanie jeśli zamiast attachInterrupt wpiszesz:

Kod:
    EICRA = (1 << ISC01) | (0 << ISC00);
    EIMSK = (1 << INT0);
       sei();

A zamiast:

Kod:
void alarm() {

    timer_val=TCNT1;
    TCNT1=0;
   
}

Wpiszesz:

Kod:
ISR(INT0_vect)
{
    timer_val=TCNT1;
    TCNT1=0;
}

????????????


W zasadzie nic się nie zmienia.

   

Ale warto zauważyć ze w wynikach naprzemiennie pojawiają się dwie wartości (z małymi odchyłkami) 
 
Odpowiedź
#5
To znaczy, że wyjście jest przesunięte w fazie.
Masz na płytce taki mały potencjometr do jej regulacji, ale to najlepiej robić z oscyloskopem.
Jeśli masz problem z kodem lub sprzętem, zadaj pytanie na forum. Nie odpowiadam na PW, jeśli nie dotyczą one spraw forum lub innych tematów prywatnych.

[Obrazek: SsIndaG.jpg]
 
Odpowiedź
#6
(08-03-2020, 16:02)Robson Kerman napisał(a): To znaczy, że wyjście jest przesunięte w fazie.
Masz na płytce taki mały potencjometr do jej regulacji, ale to najlepiej robić z oscyloskopem.

No tak, zastanawiałem się nad tym wcześniej ale to by nie miało sensu.
Przecież niezależnie od tego jaki jest stopień wypełenienia prostokąta na wejściu to powinno działać identycznie. Podczas jednego okresu jest przecież tylko jedno zbocze opadające i jedno rosnące. Przerwanie ma się generować nawet jeśli podamy szpilki na wejście. Prawie nigdy przerwania nie są generowane idealnym prostokątem tylko przypadkowymi impulsami.
ps. no chyba że o czym innym mówimy, ja mam na mysli potencjometr na płytce AD9850 do regulacji stopnia wypełnienia przebiegu
 
Odpowiedź
#7
Mnie ciekawi czemu wyniki ma na poziomie 8600/7100, skoro sygnał 1Hz to coś tu nie hallo... Bo powinno być 15625 wiec albo jego AD9850 oszukuje albo nie taktuje układu na 1Hz...


Co do tematu to jak kolega wyżej timer w ICP był by najlepszym rozwiązaniem, bo zaraz kolega mimo że rozwiąże będzie miał problem z większa częstotliwością...
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#8
Skoro powinno być 15000 to z tego wynika że przerwanie jest generowane na obydwu zboczach. Zakładając że sygnał jest lekko niesymetrycznie wypełniony - a jest (obrazek), to wyniki pomiaru są poprawne.

Jedyne co mi przychodzi do głowy to źle wyzwalane przerwanie, na obydwu zboczach, ale dla czego ?

   
 
Odpowiedź
#9
Choć mogłem być w błędzie bo nie założyłem że AVR możesz mieć 8MHz przyjąłem standardową częstotliwość 16Mhz

16000000Hz/1024 prescaler= 15625 licznik TNC1 przy 1Hz

A o jakim układzie mowa?? jakie ardunio??

Jedynie sie zapytam czemu

void setup() {
Serial.begin(2000000);
pinMode(2, INPUT);
pinMode(2, INPUT_PULLUP);


dwa razy??
Arduino zostało wymyślone po to, by robić dobrze jedną prostą rzecz – migać diodą. 
 
Odpowiedź
#10
(08-03-2020, 19:00)Jarewa0606 napisał(a): Choć mogłem być w błędzie bo nie założyłem  że AVR możesz mieć 8MHz przyjąłem standardową częstotliwość 16Mhz

16000000Hz/1024 prescaler= 15625 licznik TNC1 przy 1Hz

A o jakim układzie mowa?? jakie ardunio??

Standardowe NANO
 
Odpowiedź
  


Skocz do:


Przeglądający: 1 gości