-
11. Data: 2011-02-09 22:44:27
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: "Robbo" <y...@m...com>
> Otóż procesor AVR wchodząc w obsługę przerwania sam wyłącza przerwania.
> Więc stan jest taki, że do czasu zakończenia obsługi aktualnego
> przerwania, obsługa kolejnych przerwań jest wyłączona.
>
> Więc cli() po wejściu w obsługę przerwania nie ma sensu (bo przerwania już
> są wyłączone), natomiast sei() dajesz wtedy jak chcesz włączyć ręcznie
> obsługę przerwań, co oczywiście jest możliwe, tylko na stos trzeba uważać
> (jeśli tych przerwań jest dużo w jednostce czasu).
>
> sei() na końcu też nie ma sensu, ponieważ procedury obsługi przerwania nie
> opuszcza się poprzez ret, tylko poprzez reti, będące niczym innym jak
> połączeniem: ret + sei.
Dziękuję.
A chciałem jeszcze prosić o odpowiedź na pytanie dotyczące użycia
sei i cli w pętli głównej.
R.
-
12. Data: 2011-02-09 23:04:44
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: "Robbo" <y...@m...com>
> Ja bym liczył czas pomiedzy dwoma narastającymi zboczami. Ale ja
> herbatę cukrem...
Ja miodem...
Sprawdziłem. W tej chwili:
- mierzenie czasu między narastającym a opadającym zboczem dodatniej połówki
daje czas 998/7.
- mierzenie czasu między narastającymi zboczami kolejnych dodatnich połówek
daje czas 2000/1.
R
-
13. Data: 2011-02-09 23:38:42
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: RoMan Mandziejewicz <r...@p...pl>
Hello Robbo,
Thursday, February 10, 2011, 12:04:44 AM, you wrote:
>> Ja bym liczył czas pomiedzy dwoma narastającymi zboczami. Ale ja
>> herbatę cukrem...
> Ja miodem...
Za mocny smak...
> Sprawdziłem. W tej chwili:
> - mierzenie czasu między narastającym a opadającym zboczem dodatniej połówki
> daje czas 998/7.
> - mierzenie czasu między narastającymi zboczami kolejnych dodatnich połówek
> daje czas 2000/1.
Jak Ci się wydaje - który wynik jest bardziej zbliżony do
rzeczywistości?
--
Best regards,
RoMan mailto:r...@p...pl
Nowa strona: http://www.elektronika.squadack.com (w budowie!)
-
14. Data: 2011-02-09 23:54:37
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: "Robbo" <y...@m...com>
> Jak Ci się wydaje - który wynik jest bardziej zbliżony do
> rzeczywistości?
Wydaje mi się, że oczywiście ten drugi wynik :)
Ale, jeszcze trzeba będzie popracować nad elektroniką
i może uda się wykrzesać coś więcej z metody nr 1
Może też ujemną połówkę uda się użyć i wtedy miałbym
szybszy odczyt częstotliwości z niewielkim błędem.
R.
-
15. Data: 2011-02-10 00:47:34
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: "Robbo" <y...@m...com>
> Witam
> Na wstępie to się zapytam, na czym Koledze tak naprawdę zależy ? Na
> pomiarze czasu (okresu) czy częstotliwości ?
Owszem, nieprecyzyjnie napisałem. Mierzyć będę czas i na tej podstawie
będzie działać układ. Użytkownikowi będę jednak prezentował częstotliwość
wyznaczoną na podstawie zmierzonego czasu.
> 2. Pomiar czasu między impulsami (okresu). Tu aż się prosi wykorzystać
> Input Capture Register.
I to chyba będzie eleganckie rozwiązanie. Właśnie się tym zająłem i mam
już efekty. Jutro pozwolę sobie wkleić kod do oceny.
R.
-
16. Data: 2011-02-10 06:26:04
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: "Marcin Wasilewski" <j...@a...pl>
Użytkownik "Robbo" <y...@m...com> napisał w wiadomości
news:4d531cb8$0$2457$65785112@news.neostrada.pl...
> Dziękuję.
> A chciałem jeszcze prosić o odpowiedź na pytanie dotyczące użycia
> sei i cli w pętli głównej.
W wielkim skrócie - cli/sei używasz wtedy gdy dokonujesz zapisu/odczytu
zmiennych, które: wykorzystujesz też w przerwaniach i cała operacja zajmuje
więcej niż 1 operację procesora (zmienne dłuższe niż 1 bajt i operacje
bitowe). No i oczywiście wtedy gdy z pewnych przyczyn (głównie czasowych)
dana operacja nie powinna zostać przerwana obsługą przerwania.
-
17. Data: 2011-02-10 15:09:25
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: "Robbo" <y...@m...com>
Oto kod:
volatile unsigned short icr, prevIcr;
SIGNAL (SIG_INPUT_CAPTURE3)
{
icr = ICR3;
acutalDuration = icr - prevIcr;
prevIcr = icr;
}
int main(void)
{
char buf[16];
unsigned short actualDurationLatch;
TCCR3A = 0;
TCCR3B |= _BV(ICES3) | _BV(ICNC3) |
_BV(CS32) | _BV(30); // prescaler 64
ETIMSK |= _BV(TICIE3);
sei();
while (1) {
cli();
actualDurationLatch = actualDuration;
sei();
sprintf(s, "%u ", actualDurationLatch);
LCDwriteString(s);
}
}
Na kwarcu 16MHz i prescalerze 64, ICR3 zwiększa się z częstotliwością
1/250000. Dla 50Hz na wyświetlaczu mam liczbę 5000. Mogę zejść do ok. 2Hz --
poniżej już się nie da, bo licznik 16-bitowy ICR3 się przepełnia. Jednak 2Hz
jest dla mnie akceptowalnym wynikiem i nie potrzebuję już zwiększać
prescalera, kosztem obniżenia dokładności pomiaru.
Chciałem zapytać
1. Czy kod jest poprawny, a jeśli nie, to co poprawić?
2. Jak poradzić sobie teraz z "odcinaniem" dla częstotliwości mniejszej niż
2Hz?
Poniżej 2Hz licznik się przekręci i wskazany czas nie będzie poprawny;
może być też sytuacja, gdy sygnał zaniknie (częstotliwość 0Hz). Muszę mieć o
tym informację.
W moim programie z timerem nie było problemu (pokazywały się "---" na
wyświetlaczu dla zbyt niskich częstotliwości) -- tu nie wiem, jak to dobrze
rozwiązać.
R.
-
18. Data: 2011-02-10 15:16:29
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: Zbych <a...@o...pl>
W dniu 2011-02-10 16:09, Robbo pisze:
> cli();
> actualDurationLatch = actualDuration;
> sei();
> Chciałem zapytać
> 1. Czy kod jest poprawny, a jeśli nie, to co poprawić?
Nie używaj cli i sei do robienia sekcji atomowych, te makra nie są
zabezpieczone przed optymalizacją i kompilator może zmienić kolejność
instrukcji (choć oczywiście nie musi). Zamiast tego posłuż się
ATOMIC_BLOCK
http://www.nongnu.org/avr-libc/user-manual/group__ut
il__atomic.html
> 2. Jak poradzić sobie teraz z "odcinaniem" dla częstotliwości mniejszej
> niż 2Hz?
> Poniżej 2Hz licznik się przekręci i wskazany czas nie będzie poprawny;
> może być też sytuacja, gdy sygnał zaniknie (częstotliwość 0Hz). Muszę
> mieć o tym informację.
Albo zmniejsz taktowanie timera, albo wykorzystaj przerwanie od
przepełnienia do "dorobienia" trzeciego bajtu do licznika.
-
19. Data: 2011-02-10 15:27:16
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: "Robbo" <y...@m...com>
> ... wykorzystaj przerwanie od przepełnienia do "dorobienia" trzeciego
> bajtu do licznika.
Czy chodzi o coś takiego (pisane z pamięci)?
volatile unsigned long icr, prevIcr;
volatile char overflow;
SIGNAL (SIG_INPUT_CAPTURE3)
{
icr = ICR3;
acutalDuration = icr - prevIcr + overflow * 0xffffUL;
overflow = 0;
prevIcr = icr;
}
SIGNAL (SIG_INPUT_OVERFLOW3)
{
overflow++;
}
int main(void)
{
char buf[16];
unsigned long actualDurationLatch;
TCCR3A = 0;
TCCR3B |= _BV(ICES3) | _BV(ICNC3) |
_BV(CS32) | _BV(30); // prescaler 64
ETIMSK |= _BV(TICIE3) | _BV(TOIE3);
sei();
while (1) {
cli();
actualDurationLatch = actualDuration;
sei();
sprintf(s, "%ld ", actualDurationLatch);
LCDwriteString(s);
}
}
Jeśli chodzi o coś takiego, to mi nie działa. "overflow" impulsuje czasem na
wartość "1", bo ICR3 nieustannie się przepełnia.
Czy ktoś może wskazać, jak poprawnie zastosować rozwiązanie z
przepełnieniem?
To mogłoby być dobre rozwiązanie "odcięcia" niskich częstotliwości, tylko
nie wiem, jak poprawnie to zrealizować.
R.
-
20. Data: 2011-02-10 15:46:13
Temat: Re: AVR ATmega, pomiar częstotliwości przebiegu, prośba o sprawdzenie kodu
Od: Zbych <a...@o...pl>
W dniu 2011-02-10 16:27, Robbo pisze:
>> ... wykorzystaj przerwanie od przepełnienia do "dorobienia" trzeciego
>> bajtu do licznika.
>
> Czy chodzi o coś takiego (pisane z pamięci)?
Po pierwsze jak obydwa przerwania (przechwytywanie i przepełnienie)
zostaną zgłoszone jednocześnie, to będziesz miał nieprawidłowy wynik.
Trzeba w przerwaniu od przechwytywania sprawdzać obecność nieobsłużonego
przepełnienia. Zmienna prev powinno pamiętać nie tylko stan licznika
sprzętowego, ale i software'owego. Zamiast mnożyć 65535 powinieneś
mnożyć przez 65536, a zdecydowanie lepiej przesunąć liczbę o 16-bitów
(albo jeszcze lepiej użyć unii liczby 32-bitowej z tablicą 4 bajtów, bo
gcc ma słabą optymalizację przy obsłudze długich liczb na avr). Do tego
trzeba pamiętać o ręcznym rzutowaniu na 32-bity przed przesunięciem, bo
kompilator tego za ciebie nie zrobi (co najwyżej zrobi promocję do
16-bitów, bo tyle ma int).